2 * Copyright (c) 2007,2008 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, 465 S. Mathilda Ave., Suite 300
18 * Sunnyvale, CA 94086, 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"
33 char ipstr[INET6_ADDRSTRLEN];
35 char ipstr[INET_ADDRSTRLEN];
39 port = SU_GET_PORT(sa);
41 if (SU_GET_FAMILY(sa) == AF_INET6) {
42 inet_ntop(AF_INET6, &sa->sin6.sin6_addr, ipstr, sizeof(ipstr));
43 dbprintf("(sockaddr_in6 *)%p = { %d, %d, %s }\n",
51 inet_ntop(AF_INET, &sa->sin.sin_addr.s_addr, ipstr, sizeof(ipstr));
52 dbprintf("(sockaddr_in *)%p = { %d, %d, %s }\n",
62 static char mystr_sockaddr[INET6_ADDRSTRLEN + 20];
64 static char mystr_sockaddr[INET_ADDRSTRLEN + 20];
72 char ipstr[INET6_ADDRSTRLEN];
74 char ipstr[INET_ADDRSTRLEN];
78 port = SU_GET_PORT(sa);
80 if ( SU_GET_FAMILY(sa) == AF_INET6) {
81 inet_ntop(AF_INET6, &sa->sin6.sin6_addr, ipstr, sizeof(ipstr));
85 inet_ntop(AF_INET, &sa->sin.sin_addr.s_addr, ipstr, sizeof(ipstr));
87 g_snprintf(mystr_sockaddr,sizeof(mystr_sockaddr),"%s.%d", ipstr, port);
88 mystr_sockaddr[sizeof(mystr_sockaddr)-1] = '\0';
90 return mystr_sockaddr;
93 /* Unmap a V4MAPPED IPv6 address into its equivalent IPv4 address. The location
94 * TMP is used to store the rewritten address, if necessary. Returns a pointer
95 * to the unmapped address.
97 #if defined(WORKING_IPV6) && defined(IN6_IS_ADDR_V4MAPPED)
98 static sockaddr_union *
103 if (SU_GET_FAMILY(sa) == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa->sin6.sin6_addr)) {
104 SU_INIT(tmp, AF_INET);
105 SU_SET_PORT(tmp, SU_GET_PORT(sa));
106 /* extract the v4 address from byte 12 of the v6 address */
107 memcpy(&tmp->sin.sin_addr.s_addr,
108 &sa->sin6.sin6_addr.s6_addr[12],
109 sizeof(struct in_addr));
116 /* nothing to do if no IPv6 */
117 #define unmap_v4mapped(sa, tmp) ((void)tmp, sa)
126 sockaddr_union tmp1, tmp2;
128 /* if addresses are v4mapped, "unmap" them */
129 ss1 = unmap_v4mapped(ss1, &tmp1);
130 ss2 = unmap_v4mapped(ss2, &tmp2);
132 if (SU_GET_FAMILY(ss1) == SU_GET_FAMILY(ss2)) {
135 if(SU_GET_FAMILY(ss1) == AF_INET6)
137 &ss1->sin6.sin6_addr,
138 &ss2->sin6.sin6_addr,
139 sizeof(ss1->sin6.sin6_addr));
145 sizeof(ss1->sin.sin_addr));
147 return memcmp(ss1, ss2, SS_LEN(ss1));
150 /* compare families to give a total order */
151 if (SU_GET_FAMILY(ss1) < SU_GET_FAMILY(ss2))