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