9 /* #include <sock_addr.h>
11 /* int sock_addr_cmp_addr(sa, sb)
12 /* const struct sockaddr *sa;
13 /* const struct sockaddr *sb;
15 /* int sock_addr_cmp_port(sa, sb)
16 /* const struct sockaddr *sa;
17 /* const struct sockaddr *sb;
19 /* int SOCK_ADDR_EQ_ADDR(sa, sb)
20 /* const struct sockaddr *sa;
21 /* const struct sockaddr *sb;
23 /* int SOCK_ADDR_EQ_PORT(sa, sb)
24 /* const struct sockaddr *sa;
25 /* const struct sockaddr *sb;
27 /* int sock_addr_in_loopback(sa)
28 /* const struct sockaddr *sa;
30 /* struct sockaddr *SOCK_ADDR_PTR(ptr)
31 /* unsigned char SOCK_ADDR_FAMILY(ptr)
32 /* unsigned char SOCK_ADDR_LEN(ptr)
33 /* unsigned short SOCK_ADDR_PORT(ptr)
34 /* unsigned short *SOCK_ADDR_PORTP(ptr)
36 /* struct sockaddr_in *SOCK_ADDR_IN_PTR(ptr)
37 /* unsigned char SOCK_ADDR_IN_FAMILY(ptr)
38 /* unsigned short SOCK_ADDR_IN_PORT(ptr)
39 /* struct in_addr SOCK_ADDR_IN_ADDR(ptr)
40 /* struct in_addr IN_ADDR(ptr)
42 /* struct sockaddr_in6 *SOCK_ADDR_IN6_PTR(ptr)
43 /* unsigned char SOCK_ADDR_IN6_FAMILY(ptr)
44 /* unsigned short SOCK_ADDR_IN6_PORT(ptr)
45 /* struct in6_addr SOCK_ADDR_IN6_ADDR(ptr)
46 /* struct in6_addr IN6_ADDR(ptr)
48 /* These utilities take protocol-independent address structures
49 /* and perform protocol-dependent operations on structure members.
50 /* Some of the macros described here are called unsafe,
51 /* because they evaluate one or more arguments multiple times.
53 /* sock_addr_cmp_addr() or sock_addr_cmp_port() compare the
54 /* address family and network address or port fields for
55 /* equality, and return indication of the difference between
56 /* their arguments: < 0 if the first argument is "smaller",
57 /* 0 for equality, and > 0 if the first argument is "larger".
59 /* The unsafe macros SOCK_ADDR_EQ_ADDR() or SOCK_ADDR_EQ_PORT()
60 /* compare compare the address family and network address or
61 /* port fields for equality, and return non-zero when their
64 /* sock_addr_in_loopback() determines if the argument specifies
65 /* a loopback address.
67 /* The SOCK_ADDR_PTR() macro casts a generic pointer to (struct
68 /* sockaddr *). The name is upper case for consistency not
69 /* safety. SOCK_ADDR_FAMILY() and SOCK_ADDR_LEN() return the
70 /* address family and length of the real structure that hides
71 /* inside a generic sockaddr structure. On systems where struct
72 /* sockaddr has no sa_len member, SOCK_ADDR_LEN() cannot be
73 /* used as lvalue. SOCK_ADDR_PORT() returns the IPv4 or IPv6
74 /* port number, in network byte order; it must not be used as
75 /* lvalue. SOCK_ADDR_PORTP() returns a pointer to the same.
77 /* The macros SOCK_ADDR_IN{,6}_{PTR,FAMILY,PORT,ADDR}() cast
78 /* a generic pointer to a specific socket address structure
79 /* pointer, or access a specific socket address structure
80 /* member. These can be used as lvalues.
82 /* The unsafe INADDR() and IN6_ADDR() macros dereference a
83 /* generic pointer to a specific address structure.
85 /* Panic: unsupported address family.
89 /* The Secure Mailer license must be distributed with this software.
92 /* IBM T.J. Watson Research
94 /* Yorktown Heights, NY 10598, USA
100 #include <sys/socket.h>
101 #include <netinet/in.h>
104 /* Utility library. */
107 #include <sock_addr.h>
109 /* sock_addr_cmp_addr - compare addresses for equality */
111 int sock_addr_cmp_addr(const struct sockaddr
* sa
,
112 const struct sockaddr
* sb
)
114 if (sa
->sa_family
!= sb
->sa_family
)
115 return (sa
->sa_family
- sb
->sa_family
);
118 * With IPv6 address structures, assume a non-hostile implementation that
119 * stores the address as a contiguous sequence of bits. Any holes in the
120 * sequence would invalidate the use of memcmp().
122 if (sa
->sa_family
== AF_INET
) {
123 return (SOCK_ADDR_IN_ADDR(sa
).s_addr
- SOCK_ADDR_IN_ADDR(sb
).s_addr
);
125 } else if (sa
->sa_family
== AF_INET6
) {
126 return (memcmp((char *) &(SOCK_ADDR_IN6_ADDR(sa
)),
127 (char *) &(SOCK_ADDR_IN6_ADDR(sb
)),
128 sizeof(SOCK_ADDR_IN6_ADDR(sa
))));
131 msg_panic("sock_addr_cmp_addr: unsupported address family %d",
136 /* sock_addr_cmp_port - compare ports for equality */
138 int sock_addr_cmp_port(const struct sockaddr
* sa
,
139 const struct sockaddr
* sb
)
141 if (sa
->sa_family
!= sb
->sa_family
)
142 return (sa
->sa_family
- sb
->sa_family
);
144 if (sa
->sa_family
== AF_INET
) {
145 return (SOCK_ADDR_IN_PORT(sa
) - SOCK_ADDR_IN_PORT(sb
));
147 } else if (sa
->sa_family
== AF_INET6
) {
148 return (SOCK_ADDR_IN6_PORT(sa
) - SOCK_ADDR_IN6_PORT(sb
));
151 msg_panic("sock_addr_cmp_port: unsupported address family %d",
156 /* sock_addr_in_loopback - determine if address is loopback */
158 int sock_addr_in_loopback(const struct sockaddr
* sa
)
160 unsigned long inaddr
;
162 if (sa
->sa_family
== AF_INET
) {
163 inaddr
= ntohl(SOCK_ADDR_IN_ADDR(sa
).s_addr
);
164 return (IN_CLASSA(inaddr
)
165 && ((inaddr
& IN_CLASSA_NET
) >> IN_CLASSA_NSHIFT
)
168 } else if (sa
->sa_family
== AF_INET6
) {
169 return (IN6_IS_ADDR_LOOPBACK(&SOCK_ADDR_IN6_ADDR(sa
)));
172 msg_panic("sock_addr_in_loopback: unsupported address family %d",