2 * Copyright (c) 2005 Zmanda Inc. All Rights Reserved.
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.
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
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
17 * Contact information: Zmanda Inc, 505 N Mathlida Ave, Suite 120
18 * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
20 * Author: Dustin J. Mitchell <dustin@zmanda.com>
23 * Utility routines for handling sockaddrs
26 #include "sockaddr-util.h"
30 struct sockaddr_storage *sa)
33 char ipstr[INET6_ADDRSTRLEN];
35 char ipstr[INET_ADDRSTRLEN];
39 port = SS_GET_PORT(sa);
41 if (sa->ss_family == (sa_family_t)AF_INET6) {
42 inet_ntop(AF_INET6, &((struct sockaddr_in6 *)sa)->sin6_addr,
43 ipstr, sizeof(ipstr));
44 dbprintf("(sockaddr_in6 *)%p = { %d, %d, %s }\n",
46 ((struct sockaddr_in6 *)sa)->sin6_family,
52 inet_ntop(AF_INET, &((struct sockaddr_in *)sa)->sin_addr, ipstr,
54 dbprintf("(sockaddr_in *)%p = { %d, %d, %s }\n",
56 ((struct sockaddr_in *)sa)->sin_family,
64 static char mystr_sockaddr[INET6_ADDRSTRLEN + 20];
66 static char mystr_sockaddr[INET_ADDRSTRLEN + 20];
71 struct sockaddr_storage *sa)
74 char ipstr[INET6_ADDRSTRLEN];
76 char ipstr[INET_ADDRSTRLEN];
80 port = SS_GET_PORT(sa);
82 if ( sa->ss_family == (sa_family_t)AF_INET6) {
83 inet_ntop(AF_INET6, &((struct sockaddr_in6 *)sa)->sin6_addr,
84 ipstr, sizeof(ipstr));
88 inet_ntop(AF_INET, &((struct sockaddr_in *)sa)->sin_addr, ipstr,
91 g_snprintf(mystr_sockaddr,sizeof(mystr_sockaddr),"%s.%d", ipstr, port);
92 return mystr_sockaddr;
97 struct sockaddr_storage *ss1,
98 struct sockaddr_storage *ss2,
101 /* if addresses are v4mapped, "unmap" them */
103 #ifdef IN6_IS_ADDR_V4MAPPED
104 struct sockaddr_in ss1_v4;
105 struct sockaddr_in ss2_v4;
107 if (ss1->ss_family == AF_INET6 &&
108 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss1)->sin6_addr)) {
109 memset(&ss1_v4, 0, sizeof(struct sockaddr_in));
110 memcpy(&ss1_v4.sin_addr.s_addr,
111 &(((struct sockaddr_in6 *)ss1)->sin6_addr.s6_addr[12]),
112 sizeof(struct in_addr));
113 ss1_v4.sin_family = AF_INET;
114 SS_SET_PORT((struct sockaddr_storage *)&ss1_v4, SS_GET_PORT(ss1));
115 ss1 = (struct sockaddr_storage *)&ss1_v4;
118 if (ss2->ss_family == AF_INET6 &&
119 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss2)->sin6_addr)) {
120 memset(&ss2_v4, 0, sizeof(struct sockaddr_in));
121 memcpy(&ss2_v4.sin_addr.s_addr,
122 &(((struct sockaddr_in6 *)ss2)->sin6_addr.s6_addr[12]),
123 sizeof(struct in_addr));
124 ss2_v4.sin_family = AF_INET;
125 SS_SET_PORT((struct sockaddr_storage *)&ss2_v4, SS_GET_PORT(ss2));
126 ss2 = (struct sockaddr_storage *)&ss2_v4;
131 if (ss1->ss_family == ss2->ss_family) {
134 if(ss1->ss_family == (sa_family_t)AF_INET6)
136 &((struct sockaddr_in6 *)ss1)->sin6_addr,
137 &((struct sockaddr_in6 *)ss2)->sin6_addr,
138 sizeof(((struct sockaddr_in6 *)ss1)->sin6_addr));
142 &((struct sockaddr_in *)ss1)->sin_addr,
143 &((struct sockaddr_in *)ss2)->sin_addr,
144 sizeof(((struct sockaddr_in *)ss1)->sin_addr));
146 return memcmp(ss1, ss2, SS_LEN(ss1));
149 /* compare families to give a total order */
150 if (ss1->ss_family < ss2->ss_family)