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