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