提交 1ab80f32 编写于 作者: L Laine Stump

New virSocketAddr utility functions

virSocketPrefixToNetmask: Given a 'prefix', which is the number of 1
bits in a netmask, fill in a virSocketAddr object with a netmask as an
IP address (IPv6 or IPv4).

virSocketAddrMask: Mask off the host bits in one virSocketAddr
according to the netmask in another virSocketAddr.

virSocketAddrMaskByPrefix, Mask off the host bits in a virSocketAddr
according to a prefix (number of 1 bits in netmask).

VIR_SOCKET_FAMILY: return the family of a virSocketAddr
上级 9a4af303
...@@ -559,6 +559,9 @@ virShrinkN; ...@@ -559,6 +559,9 @@ virShrinkN;
# network.h # network.h
virSocketAddrIsNetmask; virSocketAddrIsNetmask;
virSocketAddrMask;
virSocketAddrMaskByPrefix;
virSocketAddrPrefixToNetmask;
virSocketCheckNetmask; virSocketCheckNetmask;
virSocketFormatAddr; virSocketFormatAddr;
virSocketFormatAddrFull; virSocketFormatAddrFull;
......
...@@ -287,6 +287,59 @@ int virSocketAddrIsNetmask(virSocketAddrPtr netmask) { ...@@ -287,6 +287,59 @@ int virSocketAddrIsNetmask(virSocketAddrPtr netmask) {
return 0; return 0;
} }
/**
* virSocketAddrMask:
* @addr: address that needs to be masked
* @netmask: the netmask address
*
* Mask off the host bits of @addr according to @netmask, turning it
* into a network address.
*
* Returns 0 in case of success, or -1 on error.
*/
int
virSocketAddrMask(virSocketAddrPtr addr, const virSocketAddrPtr netmask)
{
if (addr->data.stor.ss_family != netmask->data.stor.ss_family)
return -1;
if (addr->data.stor.ss_family == AF_INET) {
addr->data.inet4.sin_addr.s_addr
&= netmask->data.inet4.sin_addr.s_addr;
return 0;
}
if (addr->data.stor.ss_family == AF_INET6) {
int ii;
for (ii = 0; ii < 16; ii++)
addr->data.inet6.sin6_addr.s6_addr[ii]
&= netmask->data.inet6.sin6_addr.s6_addr[ii];
return 0;
}
return -1;
}
/**
* virSocketAddrMaskByPrefix:
* @addr: address that needs to be masked
* @prefix: prefix (# of 1 bits) of netmask to apply
*
* Mask off the host bits of @addr according to @prefix, turning it
* into a network address.
*
* Returns 0 in case of success, or -1 on error.
*/
int
virSocketAddrMaskByPrefix(virSocketAddrPtr addr, unsigned int prefix)
{
virSocketAddr netmask;
if (virSocketAddrPrefixToNetmask(prefix, &netmask,
addr->data.stor.ss_family) < 0)
return -1;
return virSocketAddrMask(addr, &netmask);
}
/** /**
* virSocketCheckNetmask: * virSocketCheckNetmask:
* @addr1: a first network address * @addr1: a first network address
...@@ -486,3 +539,63 @@ int virSocketGetNumNetmaskBits(const virSocketAddrPtr netmask) ...@@ -486,3 +539,63 @@ int virSocketGetNumNetmaskBits(const virSocketAddrPtr netmask)
} }
return -1; return -1;
} }
/**
* virSocketPrefixToNetmask:
* @prefix: number of 1 bits to put in the netmask
* @netmask: address to fill in with the desired netmask
* @family: family of the address (AF_INET or AF_INET6 only)
*
* given @prefix and @family, fill in @netmask with a netmask
* (eg 255.255.255.0).
*
* Returns 0 on success or -1 on error.
*/
int
virSocketAddrPrefixToNetmask(unsigned int prefix,
virSocketAddrPtr netmask,
int family)
{
int result = -1;
netmask->data.stor.ss_family = AF_UNSPEC; /* assume failure */
if (family == AF_INET) {
int ip;
if (prefix > 32)
goto error;
ip = prefix ? ~((1 << (32 - prefix)) - 1) : 0;
netmask->data.inet4.sin_addr.s_addr = htonl(ip);
netmask->data.stor.ss_family = AF_INET;
result = 0;
} else if (family == AF_INET6) {
int ii = 0;
if (prefix > 128)
goto error;
while (prefix >= 8) {
/* do as much as possible an entire byte at a time */
netmask->data.inet6.sin6_addr.s6_addr[ii++] = 0xff;
prefix -= 8;
}
if (prefix > 0) {
/* final partial byte */
netmask->data.inet6.sin6_addr.s6_addr[ii++]
= ~((1 << (8 - prefix)) -1);
}
while (ii < 16) {
/* zerofill remainder in case it wasn't initialized */
netmask->data.inet6.sin6_addr.s6_addr[ii++] = 0;
}
netmask->data.stor.ss_family = AF_INET6;
result = 0;
}
error:
return result;
}
...@@ -41,6 +41,9 @@ typedef struct { ...@@ -41,6 +41,9 @@ typedef struct {
# define VIR_SOCKET_IS_FAMILY(s, f) \ # define VIR_SOCKET_IS_FAMILY(s, f) \
((s)->data.sa.sa_family == f) ((s)->data.sa.sa_family == f)
# define VIR_SOCKET_FAMILY(s) \
((s)->data.sa.sa_family)
typedef virSocketAddr *virSocketAddrPtr; typedef virSocketAddr *virSocketAddrPtr;
int virSocketParseAddr (const char *val, int virSocketParseAddr (const char *val,
...@@ -70,7 +73,14 @@ int virSocketAddrIsNetmask(virSocketAddrPtr netmask); ...@@ -70,7 +73,14 @@ int virSocketAddrIsNetmask(virSocketAddrPtr netmask);
int virSocketCheckNetmask (virSocketAddrPtr addr1, int virSocketCheckNetmask (virSocketAddrPtr addr1,
virSocketAddrPtr addr2, virSocketAddrPtr addr2,
virSocketAddrPtr netmask); virSocketAddrPtr netmask);
int virSocketAddrMask (virSocketAddrPtr addr,
const virSocketAddrPtr netmask);
int virSocketAddrMaskByPrefix(virSocketAddrPtr addr,
unsigned int prefix);
int virSocketGetNumNetmaskBits(const virSocketAddrPtr netmask); int virSocketGetNumNetmaskBits(const virSocketAddrPtr netmask);
int virSocketAddrPrefixToNetmask(unsigned int prefix,
virSocketAddrPtr netmask,
int family);
#endif /* __VIR_NETWORK_H__ */ #endif /* __VIR_NETWORK_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册