1d021c344051af91f42c5ba9fdedc176740cbd238Andy King/*
2d021c344051af91f42c5ba9fdedc176740cbd238Andy King * VMware vSockets Driver
3d021c344051af91f42c5ba9fdedc176740cbd238Andy King *
4d021c344051af91f42c5ba9fdedc176740cbd238Andy King * Copyright (C) 2007-2012 VMware, Inc. All rights reserved.
5d021c344051af91f42c5ba9fdedc176740cbd238Andy King *
6d021c344051af91f42c5ba9fdedc176740cbd238Andy King * This program is free software; you can redistribute it and/or modify it
7d021c344051af91f42c5ba9fdedc176740cbd238Andy King * under the terms of the GNU General Public License as published by the Free
8d021c344051af91f42c5ba9fdedc176740cbd238Andy King * Software Foundation version 2 and no later version.
9d021c344051af91f42c5ba9fdedc176740cbd238Andy King *
10d021c344051af91f42c5ba9fdedc176740cbd238Andy King * This program is distributed in the hope that it will be useful, but WITHOUT
11d021c344051af91f42c5ba9fdedc176740cbd238Andy King * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12d021c344051af91f42c5ba9fdedc176740cbd238Andy King * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13d021c344051af91f42c5ba9fdedc176740cbd238Andy King * more details.
14d021c344051af91f42c5ba9fdedc176740cbd238Andy King */
15d021c344051af91f42c5ba9fdedc176740cbd238Andy King
16d021c344051af91f42c5ba9fdedc176740cbd238Andy King#include <linux/types.h>
17d021c344051af91f42c5ba9fdedc176740cbd238Andy King#include <linux/socket.h>
18d021c344051af91f42c5ba9fdedc176740cbd238Andy King#include <linux/stddef.h>
19d021c344051af91f42c5ba9fdedc176740cbd238Andy King#include <net/sock.h>
2082a54d0ebbee03a8dcf4e1e4016a53fed4d6c933Asias He#include <net/vsock_addr.h>
21d021c344051af91f42c5ba9fdedc176740cbd238Andy King
22d021c344051af91f42c5ba9fdedc176740cbd238Andy Kingvoid vsock_addr_init(struct sockaddr_vm *addr, u32 cid, u32 port)
23d021c344051af91f42c5ba9fdedc176740cbd238Andy King{
24d021c344051af91f42c5ba9fdedc176740cbd238Andy King	memset(addr, 0, sizeof(*addr));
25d021c344051af91f42c5ba9fdedc176740cbd238Andy King	addr->svm_family = AF_VSOCK;
26d021c344051af91f42c5ba9fdedc176740cbd238Andy King	addr->svm_cid = cid;
27d021c344051af91f42c5ba9fdedc176740cbd238Andy King	addr->svm_port = port;
28d021c344051af91f42c5ba9fdedc176740cbd238Andy King}
29d021c344051af91f42c5ba9fdedc176740cbd238Andy KingEXPORT_SYMBOL_GPL(vsock_addr_init);
30d021c344051af91f42c5ba9fdedc176740cbd238Andy King
31d021c344051af91f42c5ba9fdedc176740cbd238Andy Kingint vsock_addr_validate(const struct sockaddr_vm *addr)
32d021c344051af91f42c5ba9fdedc176740cbd238Andy King{
33d021c344051af91f42c5ba9fdedc176740cbd238Andy King	if (!addr)
34d021c344051af91f42c5ba9fdedc176740cbd238Andy King		return -EFAULT;
35d021c344051af91f42c5ba9fdedc176740cbd238Andy King
36d021c344051af91f42c5ba9fdedc176740cbd238Andy King	if (addr->svm_family != AF_VSOCK)
37d021c344051af91f42c5ba9fdedc176740cbd238Andy King		return -EAFNOSUPPORT;
38d021c344051af91f42c5ba9fdedc176740cbd238Andy King
39d021c344051af91f42c5ba9fdedc176740cbd238Andy King	if (addr->svm_zero[0] != 0)
40d021c344051af91f42c5ba9fdedc176740cbd238Andy King		return -EINVAL;
41d021c344051af91f42c5ba9fdedc176740cbd238Andy King
42d021c344051af91f42c5ba9fdedc176740cbd238Andy King	return 0;
43d021c344051af91f42c5ba9fdedc176740cbd238Andy King}
44d021c344051af91f42c5ba9fdedc176740cbd238Andy KingEXPORT_SYMBOL_GPL(vsock_addr_validate);
45d021c344051af91f42c5ba9fdedc176740cbd238Andy King
46d021c344051af91f42c5ba9fdedc176740cbd238Andy Kingbool vsock_addr_bound(const struct sockaddr_vm *addr)
47d021c344051af91f42c5ba9fdedc176740cbd238Andy King{
48d021c344051af91f42c5ba9fdedc176740cbd238Andy King	return addr->svm_port != VMADDR_PORT_ANY;
49d021c344051af91f42c5ba9fdedc176740cbd238Andy King}
50d021c344051af91f42c5ba9fdedc176740cbd238Andy KingEXPORT_SYMBOL_GPL(vsock_addr_bound);
51d021c344051af91f42c5ba9fdedc176740cbd238Andy King
52d021c344051af91f42c5ba9fdedc176740cbd238Andy Kingvoid vsock_addr_unbind(struct sockaddr_vm *addr)
53d021c344051af91f42c5ba9fdedc176740cbd238Andy King{
54d021c344051af91f42c5ba9fdedc176740cbd238Andy King	vsock_addr_init(addr, VMADDR_CID_ANY, VMADDR_PORT_ANY);
55d021c344051af91f42c5ba9fdedc176740cbd238Andy King}
56d021c344051af91f42c5ba9fdedc176740cbd238Andy KingEXPORT_SYMBOL_GPL(vsock_addr_unbind);
57d021c344051af91f42c5ba9fdedc176740cbd238Andy King
58d021c344051af91f42c5ba9fdedc176740cbd238Andy Kingbool vsock_addr_equals_addr(const struct sockaddr_vm *addr,
59d021c344051af91f42c5ba9fdedc176740cbd238Andy King			    const struct sockaddr_vm *other)
60d021c344051af91f42c5ba9fdedc176740cbd238Andy King{
61d021c344051af91f42c5ba9fdedc176740cbd238Andy King	return addr->svm_cid == other->svm_cid &&
62d021c344051af91f42c5ba9fdedc176740cbd238Andy King		addr->svm_port == other->svm_port;
63d021c344051af91f42c5ba9fdedc176740cbd238Andy King}
64d021c344051af91f42c5ba9fdedc176740cbd238Andy KingEXPORT_SYMBOL_GPL(vsock_addr_equals_addr);
65d021c344051af91f42c5ba9fdedc176740cbd238Andy King
66d021c344051af91f42c5ba9fdedc176740cbd238Andy Kingint vsock_addr_cast(const struct sockaddr *addr,
67d021c344051af91f42c5ba9fdedc176740cbd238Andy King		    size_t len, struct sockaddr_vm **out_addr)
68d021c344051af91f42c5ba9fdedc176740cbd238Andy King{
69d021c344051af91f42c5ba9fdedc176740cbd238Andy King	if (len < sizeof(**out_addr))
70d021c344051af91f42c5ba9fdedc176740cbd238Andy King		return -EFAULT;
71d021c344051af91f42c5ba9fdedc176740cbd238Andy King
72d021c344051af91f42c5ba9fdedc176740cbd238Andy King	*out_addr = (struct sockaddr_vm *)addr;
73d021c344051af91f42c5ba9fdedc176740cbd238Andy King	return vsock_addr_validate(*out_addr);
74d021c344051af91f42c5ba9fdedc176740cbd238Andy King}
75d021c344051af91f42c5ba9fdedc176740cbd238Andy KingEXPORT_SYMBOL_GPL(vsock_addr_cast);
76