1 /* 2 3 Copyright 1991, 1998 The Open Group 4 5 Permission to use, copy, modify, distribute, and sell this software and its 6 documentation for any purpose is hereby granted without fee, provided that 7 the above copyright notice appear in all copies and that both that 8 copyright notice and this permission notice appear in supporting 9 documentation. 10 11 The above copyright notice and this permission notice shall be included 12 in all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 OTHER DEALINGS IN THE SOFTWARE. 21 22 Except as contained in this notice, the name of The Open Group shall 23 not be used in advertising or otherwise to promote the sale, use or 24 other dealings in this Software without prior written authorization 25 from The Open Group. 26 27 */ 28 29 /* 30 * xdm - X display manager 31 * 32 * netaddr.c - Interpretation of XdmcpNetaddr object. 33 */ 34 35 #include "dm.h" 36 #include "dm_error.h" 37 38 #include <X11/X.h> /* FamilyInternet, etc. */ 39 40 #ifdef XDMCP 41 42 # include "dm_socket.h" 43 44 # ifdef IPv6 45 # include <arpa/inet.h> 46 # endif 47 48 # ifdef UNIXCONN 49 # include <sys/un.h> /* struct sockaddr_un */ 50 # endif 51 52 /* given an XdmcpNetaddr, returns the socket protocol family used, 53 e.g., AF_INET */ 54 55 int NetaddrFamily(XdmcpNetaddr netaddrp) 56 { 57 return ((struct sockaddr *)netaddrp)->sa_family; 58 } 59 60 61 /* given an XdmcpNetaddr, returns a pointer to the TCP/UDP port used 62 and sets *lenp to the length of the address 63 or 0 if not using TCP or UDP. */ 64 65 char * NetaddrPort(XdmcpNetaddr netaddrp, int *lenp) 66 { 67 switch (NetaddrFamily(netaddrp)) 68 { 69 case AF_INET: 70 *lenp = 2; 71 return (char *)&(((struct sockaddr_in *)netaddrp)->sin_port); 72 # ifdef IPv6 73 case AF_INET6: 74 *lenp = 2; 75 return (char *)&(((struct sockaddr_in6 *)netaddrp)->sin6_port); 76 # endif 77 default: 78 *lenp = 0; 79 return NULL; 80 } 81 } 82 83 84 /* given an XdmcpNetaddr, returns a pointer to the network address 85 and sets *lenp to the length of the address */ 86 87 char * NetaddrAddress(XdmcpNetaddr netaddrp, int *lenp) 88 { 89 switch (NetaddrFamily(netaddrp)) { 90 # ifdef UNIXCONN 91 case AF_UNIX: 92 *lenp = strlen(((struct sockaddr_un *)netaddrp)->sun_path); 93 return (char *) (((struct sockaddr_un *)netaddrp)->sun_path); 94 # endif 95 # ifdef TCPCONN 96 case AF_INET: 97 *lenp = sizeof (struct in_addr); 98 return (char *) &(((struct sockaddr_in *)netaddrp)->sin_addr); 99 # ifdef IPv6 100 case AF_INET6: 101 { 102 struct in6_addr *a = &(((struct sockaddr_in6 *)netaddrp)->sin6_addr); 103 if (IN6_IS_ADDR_V4MAPPED(a)) { 104 *lenp = sizeof (struct in_addr); 105 return ((char *) &(a->s6_addr))+12; 106 } else { 107 *lenp = sizeof (struct in6_addr); 108 return (char *) &(a->s6_addr); 109 } 110 } 111 # endif 112 # endif 113 default: 114 *lenp = 0; 115 return NULL; 116 } 117 } 118 119 120 /* given an XdmcpNetaddr, sets *addr to the network address used and 121 sets *len to the number of bytes in addr. 122 Returns the X protocol family used, e.g., FamilyInternet */ 123 124 int ConvertAddr (XdmcpNetaddr saddr, int *len, char **addr) 125 { 126 int retval; 127 128 if ((len == NULL) || (saddr == NULL)) 129 return -1; 130 *addr = NetaddrAddress(saddr, len); 131 switch (NetaddrFamily(saddr)) 132 { 133 # ifdef AF_UNSPEC 134 case AF_UNSPEC: 135 retval = FamilyLocal; 136 break; 137 # endif 138 # ifdef AF_UNIX 139 case AF_UNIX: 140 retval = FamilyLocal; 141 break; 142 # endif 143 # ifdef TCPCONN 144 case AF_INET: 145 retval = FamilyInternet; 146 break; 147 # ifdef IPv6 148 case AF_INET6: 149 if (*len == sizeof(struct in_addr)) 150 retval = FamilyInternet; 151 else 152 retval = FamilyInternet6; 153 break; 154 # endif 155 # endif 156 default: 157 retval = -1; 158 break; 159 } 160 Debug ("ConvertAddr returning %d for family %d\n", retval, 161 NetaddrFamily(saddr)); 162 return retval; 163 } 164 165 int 166 addressEqual (XdmcpNetaddr a1, int len1, XdmcpNetaddr a2, int len2) 167 { 168 int partlen1, partlen2; 169 char *part1, *part2; 170 171 if (len1 != len2) 172 { 173 return FALSE; 174 } 175 if (NetaddrFamily(a1) != NetaddrFamily(a2)) 176 { 177 return FALSE; 178 } 179 part1 = NetaddrPort(a1, &partlen1); 180 part2 = NetaddrPort(a2, &partlen2); 181 if (partlen1 != partlen2 || memcmp(part1, part2, partlen1) != 0) 182 { 183 return FALSE; 184 } 185 part1 = NetaddrAddress(a1, &partlen1); 186 part2 = NetaddrAddress(a2, &partlen2); 187 if (partlen1 != partlen2 || memcmp(part1, part2, partlen1) != 0) 188 { 189 return FALSE; 190 } 191 return TRUE; 192 } 193 194 # ifdef DEBUG 195 /*ARGSUSED*/ 196 void 197 PrintSockAddr (struct sockaddr *a, int len) 198 { 199 unsigned char *t, *p; 200 201 Debug ("family %d, ", a->sa_family); 202 switch (a->sa_family) { 203 # ifdef AF_INET 204 case AF_INET: 205 206 p = (unsigned char *) &((struct sockaddr_in *) a)->sin_port; 207 t = (unsigned char *) &((struct sockaddr_in *) a)->sin_addr; 208 209 Debug ("port %d, host %d.%d.%d.%d\n", 210 (p[0] << 8) + p[1], t[0], t[1], t[2], t[3]); 211 break; 212 # endif 213 # ifdef IPv6 214 case AF_INET6: 215 { 216 char astr[INET6_ADDRSTRLEN] = ""; 217 218 inet_ntop(a->sa_family, &((struct sockaddr_in6 *) a)->sin6_addr, 219 astr, sizeof(astr)); 220 p = (unsigned char *) &((struct sockaddr_in6 *) a)->sin6_port; 221 222 Debug ("port %d, host %s\n", (p[0] << 8) + p[1], astr); 223 break; 224 } 225 # endif 226 } 227 } 228 # endif 229 230 #endif /* XDMCP */ 231