1 /* $OpenBSD: nametoaddr.c,v 1.22 2019/07/19 04:51:31 dlg Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 * 23 * Name to id translation routines used by the scanner. 24 * These functions are not time critical. 25 */ 26 27 #include <sys/param.h> 28 #include <sys/types.h> /* concession to AIX */ 29 #include <sys/socket.h> 30 #include <sys/time.h> 31 32 struct mbuf; 33 struct rtentry; 34 35 #include <net/if.h> 36 #include <netinet/in.h> 37 #include <netinet/if_ether.h> 38 #include <arpa/inet.h> 39 40 #include <ctype.h> 41 #include <errno.h> 42 #include <stdlib.h> 43 #include <netdb.h> 44 #include <stdio.h> 45 #include <string.h> 46 47 #include "pcap-int.h" 48 49 #include "gencode.h" 50 #include <pcap-namedb.h> 51 52 #ifdef HAVE_OS_PROTO_H 53 #include "os-proto.h" 54 #endif 55 56 #ifndef NTOHL 57 #define NTOHL(x) (x) = ntohl(x) 58 #define NTOHS(x) (x) = ntohs(x) 59 #endif 60 61 static __inline int xdtoi(int); 62 63 /* 64 * Convert host name to internet address. 65 * Return 0 upon failure. 66 */ 67 bpf_u_int32 ** 68 pcap_nametoaddr(const char *name) 69 { 70 #ifndef h_addr 71 static bpf_u_int32 *hlist[2]; 72 #endif 73 bpf_u_int32 **p; 74 struct hostent *hp; 75 76 if ((hp = gethostbyname(name)) != NULL) { 77 #ifndef h_addr 78 hlist[0] = (bpf_u_int32 *)hp->h_addr; 79 NTOHL(hp->h_addr); 80 return hlist; 81 #else 82 for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p) 83 NTOHL(**p); 84 return (bpf_u_int32 **)hp->h_addr_list; 85 #endif 86 } 87 else 88 return 0; 89 } 90 91 #ifdef INET6 92 struct addrinfo * 93 pcap_nametoaddrinfo(const char *name) 94 { 95 struct addrinfo hints, *res; 96 int error; 97 98 memset(&hints, 0, sizeof(hints)); 99 hints.ai_family = PF_UNSPEC; 100 hints.ai_socktype = SOCK_STREAM; /*not really*/ 101 error = getaddrinfo(name, NULL, &hints, &res); 102 if (error) 103 return NULL; 104 else 105 return res; 106 } 107 #endif /*INET6*/ 108 109 /* 110 * Convert net name to internet address. 111 * Return 0 upon failure. 112 */ 113 bpf_u_int32 114 pcap_nametonetaddr(const char *name) 115 { 116 struct netent *np; 117 118 if ((np = getnetbyname(name)) != NULL) 119 return np->n_net; 120 else 121 return 0; 122 } 123 124 /* 125 * Convert a port name to its port and protocol numbers. 126 * We assume only TCP or UDP. 127 * Return 0 upon failure. 128 */ 129 int 130 pcap_nametoport(const char *name, int *port, int *proto) 131 { 132 struct servent *sp; 133 char *other; 134 135 sp = getservbyname(name, (char *)0); 136 if (sp != NULL) { 137 NTOHS(sp->s_port); 138 *port = sp->s_port; 139 *proto = pcap_nametoproto(sp->s_proto); 140 /* 141 * We need to check /etc/services for ambiguous entries. 142 * If we find the ambiguous entry, and it has the 143 * same port number, change the proto to PROTO_UNDEF 144 * so both TCP and UDP will be checked. 145 */ 146 if (*proto == IPPROTO_TCP) 147 other = "udp"; 148 else 149 other = "tcp"; 150 151 sp = getservbyname(name, other); 152 if (sp != 0) { 153 NTOHS(sp->s_port); 154 #ifdef notdef 155 if (*port != sp->s_port) 156 /* Can't handle ambiguous names that refer 157 to different port numbers. */ 158 warning("ambiguous port %s in /etc/services", 159 name); 160 #endif 161 *proto = PROTO_UNDEF; 162 } 163 return 1; 164 } 165 #if defined(ultrix) || defined(__osf__) 166 /* Special hack in case NFS isn't in /etc/services */ 167 if (strcmp(name, "nfs") == 0) { 168 *port = 2049; 169 *proto = PROTO_UNDEF; 170 return 1; 171 } 172 #endif 173 return 0; 174 } 175 176 int 177 pcap_nametoproto(const char *str) 178 { 179 struct protoent *p; 180 181 p = getprotobyname(str); 182 if (p != 0) 183 return p->p_proto; 184 else 185 return PROTO_UNDEF; 186 } 187 188 #include "ethertype.h" 189 190 struct eproto { 191 char *s; 192 u_short p; 193 }; 194 195 /* Static data base of ether protocol types. */ 196 static const struct eproto _eproto_db[] = { 197 { "pup", ETHERTYPE_PUP }, 198 { "xns", ETHERTYPE_NS }, 199 { "ip", ETHERTYPE_IP }, 200 #ifdef INET6 201 { "ip6", ETHERTYPE_IPV6 }, 202 #endif 203 { "arp", ETHERTYPE_ARP }, 204 { "rarp", ETHERTYPE_REVARP }, 205 { "lldp", ETHERTYPE_LLDP }, 206 { "slow", ETHERTYPE_SLOW }, 207 { "sprite", ETHERTYPE_SPRITE }, 208 { "mopdl", ETHERTYPE_MOPDL }, 209 { "moprc", ETHERTYPE_MOPRC }, 210 { "decnet", ETHERTYPE_DN }, 211 { "lat", ETHERTYPE_LAT }, 212 { "sca", ETHERTYPE_SCA }, 213 { "lanbridge", ETHERTYPE_LANBRIDGE }, 214 { "vexp", ETHERTYPE_VEXP }, 215 { "vprod", ETHERTYPE_VPROD }, 216 { "atalk", ETHERTYPE_ATALK }, 217 { "atalkarp", ETHERTYPE_AARP }, 218 { "loopback", ETHERTYPE_LOOPBACK }, 219 { "decdts", ETHERTYPE_DECDTS }, 220 { "decdns", ETHERTYPE_DECDNS }, 221 { (char *)0, 0 } 222 }; 223 /* Accessor for tcpdump */ 224 const struct eproto * const eproto_db = _eproto_db; 225 226 int 227 pcap_nametoeproto(const char *s) 228 { 229 const struct eproto *p = _eproto_db; 230 231 while (p->s != 0) { 232 if (strcmp(p->s, s) == 0) 233 return p->p; 234 p += 1; 235 } 236 return PROTO_UNDEF; 237 } 238 239 #include "llc.h" 240 241 /* Static data base of LLC values. */ 242 static const struct eproto llc_db[] = { 243 { "stp", LLCSAP_8021D }, 244 { (char *)0, 0 } 245 }; 246 247 int 248 pcap_nametollc(const char *s) 249 { 250 const struct eproto *p = llc_db; 251 252 while (p->s != 0) { 253 if (strcmp(p->s, s) == 0) 254 return p->p; 255 p += 1; 256 } 257 return PROTO_UNDEF; 258 } 259 260 /* Hex digit to integer. */ 261 static __inline int 262 xdtoi(c) 263 int c; 264 { 265 if (isdigit(c)) 266 return c - '0'; 267 else if (islower(c)) 268 return c - 'a' + 10; 269 else 270 return c - 'A' + 10; 271 } 272 273 int 274 __pcap_atoin(const char *s, bpf_u_int32 *addr) 275 { 276 u_int n; 277 int len; 278 279 *addr = 0; 280 len = 0; 281 while (1) { 282 n = 0; 283 while (*s && *s != '.') 284 n = n * 10 + *s++ - '0'; 285 *addr <<= 8; 286 *addr |= n & 0xff; 287 len += 8; 288 if (*s == '\0') 289 return len; 290 ++s; 291 } 292 /* NOTREACHED */ 293 } 294 295 int 296 __pcap_atodn(const char *s, bpf_u_int32 *addr) 297 { 298 #define AREASHIFT 10 299 #define AREAMASK 0176000 300 #define NODEMASK 01777 301 302 u_int node, area; 303 304 if (sscanf((char *)s, "%d.%d", &area, &node) != 2) 305 bpf_error("malformed decnet address '%s'", s); 306 307 *addr = (area << AREASHIFT) & AREAMASK; 308 *addr |= (node & NODEMASK); 309 310 return(32); 311 } 312 313 /* 314 * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new 315 * ethernet address. Assumes 's' is well formed. 316 */ 317 u_char * 318 pcap_ether_aton(const char *s) 319 { 320 u_char *ep, *e; 321 u_int d; 322 323 e = ep = malloc(6); 324 if (e == NULL) 325 bpf_error("malloc"); 326 327 while (*s) { 328 if (*s == ':') 329 s += 1; 330 d = xdtoi(*s++); 331 if (isxdigit((unsigned char)*s)) { 332 d <<= 4; 333 d |= xdtoi(*s++); 334 } 335 *ep++ = d; 336 } 337 338 return (e); 339 } 340 341 #ifndef HAVE_ETHER_HOSTTON 342 /* Roll our own */ 343 u_char * 344 pcap_ether_hostton(const char *name) 345 { 346 struct pcap_etherent *ep; 347 u_char *ap; 348 static FILE *fp = NULL; 349 static init = 0; 350 351 if (!init) { 352 fp = fopen(PCAP_ETHERS_FILE, "r"); 353 ++init; 354 if (fp == NULL) 355 return (NULL); 356 } else if (fp == NULL) 357 return (NULL); 358 else 359 rewind(fp); 360 361 while ((ep = pcap_next_etherent(fp)) != NULL) { 362 if (strcmp(ep->name, name) == 0) { 363 ap = malloc(6); 364 if (ap != NULL) { 365 memcpy(ap, ep->addr, 6); 366 return (ap); 367 } 368 break; 369 } 370 } 371 return (NULL); 372 } 373 #else 374 375 /* Use the os supplied routines */ 376 u_char * 377 pcap_ether_hostton(const char *name) 378 { 379 u_char *ap; 380 u_char a[6]; 381 382 ap = NULL; 383 if (ether_hostton(name, (struct ether_addr *)a) == 0) { 384 ap = malloc(6); 385 if (ap != NULL) 386 memcpy((char *)ap, (char *)a, 6); 387 } 388 return (ap); 389 } 390 #endif 391 392 u_short 393 __pcap_nametodnaddr(const char *name) 394 { 395 #ifdef DECNETLIB 396 struct nodeent *getnodebyname(); 397 struct nodeent *nep; 398 unsigned short res; 399 400 nep = getnodebyname(name); 401 if (nep == ((struct nodeent *)0)) 402 bpf_error("unknown decnet host name '%s'\n", name); 403 404 memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short)); 405 return(res); 406 #else 407 bpf_error("decnet name support not included, '%s' cannot be translated\n", 408 name); 409 /* NOTREACHED */ 410 #endif 411 } 412