Postfix3.3.1
sock_addr.c
[詳解]
1 /*++
2 /* NAME
3 /* sock_addr 3
4 /* SUMMARY
5 /* sockaddr utilities
6 /* SYNOPSIS
7 /* #include <sock_addr.h>
8 /*
9 /* int sock_addr_cmp_addr(sa, sb)
10 /* const struct sockaddr *sa;
11 /* const struct sockaddr *sb;
12 /*
13 /* int sock_addr_cmp_port(sa, sb)
14 /* const struct sockaddr *sa;
15 /* const struct sockaddr *sb;
16 /*
17 /* int SOCK_ADDR_EQ_ADDR(sa, sb)
18 /* const struct sockaddr *sa;
19 /* const struct sockaddr *sb;
20 /*
21 /* int SOCK_ADDR_EQ_PORT(sa, sb)
22 /* const struct sockaddr *sa;
23 /* const struct sockaddr *sb;
24 /*
25 /* int sock_addr_in_loopback(sa)
26 /* const struct sockaddr *sa;
27 /* AUXILIARY MACROS
28 /* struct sockaddr *SOCK_ADDR_PTR(ptr)
29 /* unsigned char SOCK_ADDR_FAMILY(ptr)
30 /* unsigned char SOCK_ADDR_LEN(ptr)
31 /* unsigned short SOCK_ADDR_PORT(ptr)
32 /* unsigned short *SOCK_ADDR_PORTP(ptr)
33 /*
34 /* struct sockaddr_in *SOCK_ADDR_IN_PTR(ptr)
35 /* unsigned char SOCK_ADDR_IN_FAMILY(ptr)
36 /* unsigned short SOCK_ADDR_IN_PORT(ptr)
37 /* struct in_addr SOCK_ADDR_IN_ADDR(ptr)
38 /* struct in_addr IN_ADDR(ptr)
39 /*
40 /* struct sockaddr_in6 *SOCK_ADDR_IN6_PTR(ptr)
41 /* unsigned char SOCK_ADDR_IN6_FAMILY(ptr)
42 /* unsigned short SOCK_ADDR_IN6_PORT(ptr)
43 /* struct in6_addr SOCK_ADDR_IN6_ADDR(ptr)
44 /* struct in6_addr IN6_ADDR(ptr)
45 /* DESCRIPTION
46 /* These utilities take protocol-independent address structures
47 /* and perform protocol-dependent operations on structure members.
48 /* Some of the macros described here are called unsafe,
49 /* because they evaluate one or more arguments multiple times.
50 /*
51 /* sock_addr_cmp_addr() or sock_addr_cmp_port() compare the
52 /* address family and network address or port fields for
53 /* equality, and return indication of the difference between
54 /* their arguments: < 0 if the first argument is "smaller",
55 /* 0 for equality, and > 0 if the first argument is "larger".
56 /*
57 /* The unsafe macros SOCK_ADDR_EQ_ADDR() or SOCK_ADDR_EQ_PORT()
58 /* compare compare the address family and network address or
59 /* port fields for equality, and return non-zero when their
60 /* arguments differ.
61 /*
62 /* sock_addr_in_loopback() determines if the argument specifies
63 /* a loopback address.
64 /*
65 /* The SOCK_ADDR_PTR() macro casts a generic pointer to (struct
66 /* sockaddr *). The name is upper case for consistency not
67 /* safety. SOCK_ADDR_FAMILY() and SOCK_ADDR_LEN() return the
68 /* address family and length of the real structure that hides
69 /* inside a generic sockaddr structure. On systems where struct
70 /* sockaddr has no sa_len member, SOCK_ADDR_LEN() cannot be
71 /* used as lvalue. SOCK_ADDR_PORT() returns the IPv4 or IPv6
72 /* port number, in network byte order; it must not be used as
73 /* lvalue. SOCK_ADDR_PORTP() returns a pointer to the same.
74 /*
75 /* The macros SOCK_ADDR_IN{,6}_{PTR,FAMILY,PORT,ADDR}() cast
76 /* a generic pointer to a specific socket address structure
77 /* pointer, or access a specific socket address structure
78 /* member. These can be used as lvalues.
79 /*
80 /* The unsafe INADDR() and IN6_ADDR() macros dereference a
81 /* generic pointer to a specific address structure.
82 /* DIAGNOSTICS
83 /* Panic: unsupported address family.
84 /* LICENSE
85 /* .ad
86 /* .fi
87 /* The Secure Mailer license must be distributed with this software.
88 /* AUTHOR(S)
89 /* Wietse Venema
90 /* IBM T.J. Watson Research
91 /* P.O. Box 704
92 /* Yorktown Heights, NY 10598, USA
93 /*--*/
94 
95 /* System library. */
96 
97 #include <sys_defs.h>
98 #include <sys/socket.h>
99 #include <netinet/in.h>
100 #include <string.h>
101 
102 /* Utility library. */
103 
104 #include <msg.h>
105 #include <sock_addr.h>
106 
107 /* sock_addr_cmp_addr - compare addresses for equality */
108 
109 int sock_addr_cmp_addr(const struct sockaddr *sa,
110  const struct sockaddr *sb)
111 {
112  if (sa->sa_family != sb->sa_family)
113  return (sa->sa_family - sb->sa_family);
114 
115  /*
116  * With IPv6 address structures, assume a non-hostile implementation that
117  * stores the address as a contiguous sequence of bits. Any holes in the
118  * sequence would invalidate the use of memcmp().
119  */
120  if (sa->sa_family == AF_INET) {
121  return (SOCK_ADDR_IN_ADDR(sa).s_addr - SOCK_ADDR_IN_ADDR(sb).s_addr);
122 #ifdef HAS_IPV6
123  } else if (sa->sa_family == AF_INET6) {
124  return (memcmp((void *) &(SOCK_ADDR_IN6_ADDR(sa)),
125  (void *) &(SOCK_ADDR_IN6_ADDR(sb)),
126  sizeof(SOCK_ADDR_IN6_ADDR(sa))));
127 #endif
128  } else {
129  msg_panic("sock_addr_cmp_addr: unsupported address family %d",
130  sa->sa_family);
131  }
132 }
133 
134 /* sock_addr_cmp_port - compare ports for equality */
135 
136 int sock_addr_cmp_port(const struct sockaddr *sa,
137  const struct sockaddr *sb)
138 {
139  if (sa->sa_family != sb->sa_family)
140  return (sa->sa_family - sb->sa_family);
141 
142  if (sa->sa_family == AF_INET) {
143  return (SOCK_ADDR_IN_PORT(sa) - SOCK_ADDR_IN_PORT(sb));
144 #ifdef HAS_IPV6
145  } else if (sa->sa_family == AF_INET6) {
146  return (SOCK_ADDR_IN6_PORT(sa) - SOCK_ADDR_IN6_PORT(sb));
147 #endif
148  } else {
149  msg_panic("sock_addr_cmp_port: unsupported address family %d",
150  sa->sa_family);
151  }
152 }
153 
154 /* sock_addr_in_loopback - determine if address is loopback */
155 
156 int sock_addr_in_loopback(const struct sockaddr *sa)
157 {
158  unsigned long inaddr;
159 
160  if (sa->sa_family == AF_INET) {
161  inaddr = ntohl(SOCK_ADDR_IN_ADDR(sa).s_addr);
162  return (IN_CLASSA(inaddr)
163  && ((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT)
164  == IN_LOOPBACKNET);
165 #ifdef HAS_IPV6
166  } else if (sa->sa_family == AF_INET6) {
167  return (IN6_IS_ADDR_LOOPBACK(&SOCK_ADDR_IN6_ADDR(sa)));
168 #endif
169  } else {
170  msg_panic("sock_addr_in_loopback: unsupported address family %d",
171  sa->sa_family);
172  }
173 }
int sock_addr_cmp_addr(const struct sockaddr *sa, const struct sockaddr *sb)
Definition: sock_addr.c:109
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
int sock_addr_in_loopback(const struct sockaddr *sa)
Definition: sock_addr.c:156
int sock_addr_cmp_port(const struct sockaddr *sa, const struct sockaddr *sb)
Definition: sock_addr.c:136
#define SOCK_ADDR_IN_ADDR(sa)
Definition: sock_addr.h:33
#define SOCK_ADDR_IN_PORT(sa)
Definition: sock_addr.h:32