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