2b162018d025081bc663e2bb8327399d7d427f50
[debian/amanda] / common-src / sockaddr-util.h
1 /*
2  * Copyright (c) 2007, 2008, 2010 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, 465 S. Mathilda Ave., Suite 300
18  * Sunnyvale, CA 94086, 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_UTIL_H
27 #define SOCKADDR_UTIL_H
28
29 #include "amanda.h"
30
31 /* Dump a sockaddr_union using dbprintf
32  *
33  * @param sa: the sockaddr to dump
34  */
35 void    dump_sockaddr(sockaddr_union *  sa);
36
37 /* Convert a sockaddr_union to a string.
38  *
39  * NOTE: this function is not threadsafe!
40  *
41  * @param sa: the sockaddr_union to dump
42  * @returns: pointer to statically allocated string
43  */
44 char *  str_sockaddr(sockaddr_union *sa);
45 char *  str_sockaddr_no_port(sockaddr_union *sa);
46
47 /* Compare two sockaddr_union objects, optionally comparing
48  * only the address (and thus ignoring port, flow info, etc.).
49  *
50  * @param su1: one sockaddr_union to compare
51  * @param su2: the other sockaddr_union to compare
52  * @param addr_only: if true, ignore port, flow info, etc.
53  * @returns: -1, 0, or 1 for <, ==, >, respectively
54  */
55 int     cmp_sockaddr(sockaddr_union *su1,
56                      sockaddr_union *su2,
57                      int addr_only);
58
59 /* Parse a string into a sockaddr.  This will try all available address
60  * families.
61  *
62  * @param src: the string representation of the address
63  * @param dst: the sockaddr_union in which to store the result
64  * @returns: 1 on success, -1 on error, or 0 if unparseable
65  */
66 int     str_to_sockaddr(
67         const char *src,
68         sockaddr_union *dst);
69
70 /* Copy a sockaddr object.
71  *
72  * @param dest: destination
73  * @param src: source
74  */
75 #define copy_sockaddr(dest, src) memcpy((dest), (src), SS_LEN((src)))
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 /* Get the family for a sockaddr_union.
87  *
88  * @param su: the sockaddr_union to examine
89  */
90 #define SU_GET_FAMILY(su) ((su)->sa.sa_family)
91 /* Calculate the length of the data in a sockaddr_union.
92  *
93  * @param su: the sockaddr_union to examine
94  * @returns: length of the data in the object
95  */
96 /* SS_LEN(su) */
97 #ifdef WORKING_IPV6
98 # define SS_LEN(su) (SU_GET_FAMILY(su)==AF_INET6? sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in))
99 #else
100 # define SS_LEN(su) (sizeof(struct sockaddr_in))
101 #endif
102
103 /* Initialize a sockaddr_union to all zeroes (as directed by RFC),
104  * and set its address family as specified
105  *
106  * @param su: sockaddr_union object to initialize
107  * @param family: an AF_* constant
108  */
109 /* SU_INIT(su, family) */
110 #define SU_INIT(su, family) do { \
111     memset((su), 0, sizeof(*(su))); \
112     (su)->sa.sa_family = (family); \
113 } while (0);
114
115 /* set a sockaddr_union to the family-appropriate equivalent of
116  * INADDR_ANY -- a wildcard address and port.  Call SU_INIT(su)
117  * first to initialize the object and set the family.
118  *
119  * @param su: the sockaddr_union to set
120  */
121 /* SU_SET_INADDR_ANY(su) */
122 #ifdef WORKING_IPV6
123 #define SU_SET_INADDR_ANY(su) do { \
124     switch (SU_GET_FAMILY(su)) { \
125         case AF_INET6: \
126             (su)->sin6.sin6_flowinfo = 0; \
127             (su)->sin6.sin6_addr = in6addr_any; \
128             break; \
129         case AF_INET: \
130             (su)->sin.sin_addr.s_addr = INADDR_ANY; \
131             break; \
132     } \
133 } while (0);
134 #else
135 #define SU_SET_INADDR_ANY(su) do { \
136     (su)->sin.sin_addr.s_addr = INADDR_ANY; \
137 } while (0);
138 #endif
139
140 /* Set the port in a sockaddr_union that already has an family
141  *
142  * @param su: the sockaddr_union to manipulate
143  * @param port: the port to insert (in host byte order)
144  */
145 /* SU_SET_PORT(su, port) */
146 #ifdef WORKING_IPV6
147 #define SU_SET_PORT(su, port) \
148 switch (SU_GET_FAMILY(su)) { \
149     case AF_INET: \
150         (su)->sin.sin_port = (in_port_t)htons((port)); \
151         break; \
152     case AF_INET6: \
153         (su)->sin6.sin6_port = (in_port_t)htons((port)); \
154         break; \
155     default: assert(0); \
156 }
157 #else
158 #define SU_SET_PORT(su, port) \
159         (su)->sin.sin_port = (in_port_t)htons((port));
160 #endif
161
162 /* Get the port in a sockaddr_union object
163  *
164  * @param su: the sockaddr_union to manipulate
165  * @return: the port, in host byte horder
166  */
167 /* SU_GET_PORT(su) */
168 #ifdef WORKING_IPV6
169 #define SU_GET_PORT(su) (ntohs(SU_GET_FAMILY(su) == AF_INET6? (su)->sin6.sin6_port:(su)->sin.sin_port))
170 #else
171 #define SU_GET_PORT(su) (ntohs((su)->sin.sin_port))
172 #endif
173
174 #endif  /* SOCKADDR_UTIL_H */