849dd2ac758a53becbfa851a22c48ed41ba50156
[debian/amanda] / common-src / sockaddr-util.h
1 /*
2  * Copyright (c) 2005 Zmanda Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16  *
17  * Contact information: Zmanda Inc, 505 N Mathlida Ave, Suite 120
18  * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
19  *
20  * Author: Dustin J. Mitchell <dustin@zmanda.com>
21  */
22 /*
23  * Utility routines for handling sockaddrs
24  */
25
26 #ifndef SOCKADDR_H
27 #define SOCKADDR_H
28
29 #include "amanda.h"
30
31 /* Dump a sockaddr_storage using dbprintf
32  *
33  * @param sa: the sockaddr to dump
34  */
35 void    dump_sockaddr(struct sockaddr_storage * sa);
36
37 /* Convert a sockaddr_storage to a string.
38  *
39  * NOTE: this function is not threadsafe!
40  *
41  * @param sa: the sockaddr_storage to dump
42  * @returns: pointer to statically allocated string
43  */
44 char *  str_sockaddr(struct sockaddr_storage *sa);
45
46 /* Compare two sockaddr_storage objects, optionally comparing
47  * only the address (and thus ignoring port, flow info, etc.).
48  *
49  * @param ss1: one sockaddr_storage to compare
50  * @param ss2: the other sockaddr_storage to compare
51  * @param addr_only: if true, ignore port, flow info, etc.
52  * @returns: -1, 0, or 1 for <, ==, >, respectively
53  */
54 int     cmp_sockaddr(struct sockaddr_storage *ss1,
55                      struct sockaddr_storage *ss2,
56                      int addr_only);
57
58 /* Copy a sockaddr object.
59  *
60  * @param dest: destination
61  * @param src: source
62  */
63 #define copy_sockaddr(dest, src) memcpy((dest), (src), SS_LEN((src)))
64
65 /* Calculate the length of the data in a struct sockaddr_storage.
66  *
67  * @param ss: the sockaddr_storage to examine
68  * @returns: length of the data in the object
69  */
70 /* SS_LEN(ss) */
71 #ifdef WORKING_IPV6
72 # define SS_LEN(ss) (((struct sockaddr *)(ss))->sa_family==AF_INET6?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in))
73 #else
74 # define SS_LEN(ss) (sizeof(struct sockaddr_in))
75 #endif
76
77 /* The "best" address family we support.
78  */
79 /* AF_NATIVE */
80 #ifdef WORKING_IPV6
81 #define AF_NATIVE AF_INET6
82 #else
83 #define AF_NATIVE AF_INET
84 #endif
85
86 /* Initialize a sockaddr_storage to all zeroes (as directed by RFC),
87  * and set its ss_family as specified
88  *
89  * @param ss: sockaddr_storage object to initialize
90  * @param family: an AF_* constant
91  */
92 /* SS_INIT(ss, family) */
93 #define SS_INIT(ss, family) do { \
94     memset((ss), 0, sizeof(*(ss))); \
95     (ss)->ss_family = (family); \
96 } while (0);
97
98 /* set a sockaddr_storage to the family-appropriate equivalent of
99  * INADDR_ANY -- a wildcard address and port.  Call SS_INIT(ss)
100  * first to initialize the object and set the family.
101  *
102  * @param ss: the sockaddr_storage to set
103  */
104 /* SS_SET_INADDR_ANY(ss) */
105 #ifdef WORKING_IPV6
106 #define SS_SET_INADDR_ANY(ss) do { \
107     switch ((ss)->ss_family) { \
108         case AF_INET6: \
109             ((struct sockaddr_in6 *)(ss))->sin6_flowinfo = 0; \
110             ((struct sockaddr_in6 *)(ss))->sin6_addr = in6addr_any; \
111             break; \
112         case AF_INET: \
113             ((struct sockaddr_in *)(ss))->sin_addr.s_addr = INADDR_ANY; \
114             break; \
115     } \
116 } while (0);
117 #else
118 #define SS_SET_INADDR_ANY(ss) do { \
119     ((struct sockaddr_in *)(ss))->sin_addr.s_addr = INADDR_ANY; \
120 } while (0);
121 #endif
122
123 /* Set the port in a sockaddr_storage that already has an family
124  *
125  * @param ss: the sockaddr_storage to manipulate
126  * @param port: the port to insert
127  */
128 /* SS_SET_PORT(ss, port) */
129 #ifdef WORKING_IPV6
130 #define SS_SET_PORT(ss, port) \
131 switch ((ss)->ss_family) { \
132     case AF_INET: \
133         ((struct sockaddr_in *)(ss))->sin_port = (in_port_t)htons((port)); \
134         break; \
135     case AF_INET6: \
136         ((struct sockaddr_in6 *)(ss))->sin6_port = (in_port_t)htons((port)); \
137         break; \
138     default: assert(0); \
139 }
140 #else
141 #define SS_SET_PORT(ss, port) \
142         ((struct sockaddr_in *)(ss))->sin_port = (in_port_t)htons((port));
143 #endif
144
145 /* Get the port in a sockaddr_storage object
146  *
147  * @param ss: the sockaddr_storage to manipulate
148  */
149 /* SS_GET_PORT(ss) */
150 #ifdef WORKING_IPV6
151 #define SS_GET_PORT(ss) (ntohs( \
152        (ss)->ss_family == AF_INET6? \
153         ((struct sockaddr_in6 *)(ss))->sin6_port \
154        :((struct sockaddr_in *)(ss))->sin_port))
155 #else
156 #define SS_GET_PORT(ss) (ntohs( \
157         ((struct sockaddr_in *)(ss))->sin_port))
158 #endif
159
160 #endif  /* SOCKADDR_H */
161