1 /* $NetBSD: nametoaddr.c,v 1.3 1995/04/29 05:42:23 cgd Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1991, 1992, 1993, 1994 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 #ifndef lint 28 static char rcsid[] = 29 "@(#) Header: nametoaddr.c,v 1.21 94/06/20 19:07:54 leres Exp (LBL)"; 30 #endif 31 32 #include <sys/param.h> 33 #include <sys/socket.h> 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 <netdb.h> 42 #include <pcap.h> 43 #include <pcap-namedb.h> 44 #include <stdio.h> 45 #ifdef __NetBSD__ 46 #include <stdlib.h> 47 #include <string.h> 48 #endif 49 50 #include "gencode.h" 51 52 #ifndef __GNUC__ 53 #define inline 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 u_long ** 68 pcap_nametoaddr(const char *name) 69 { 70 #ifndef h_addr 71 static u_long *hlist[2]; 72 #endif 73 u_long **p; 74 struct hostent *hp; 75 76 if ((hp = gethostbyname(name)) != NULL) { 77 #ifndef h_addr 78 hlist[0] = (u_long *)hp->h_addr; 79 NTOHL(hp->h_addr); 80 return hlist; 81 #else 82 for (p = (u_long **)hp->h_addr_list; *p; ++p) 83 NTOHL(**p); 84 return (u_long **)hp->h_addr_list; 85 #endif 86 } 87 else 88 return 0; 89 } 90 91 /* 92 * Convert net name to internet address. 93 * Return 0 upon failure. 94 */ 95 u_long 96 pcap_nametonetaddr(const char *name) 97 { 98 struct netent *np; 99 100 if ((np = getnetbyname(name)) != NULL) 101 return np->n_net; 102 else 103 return 0; 104 } 105 106 /* 107 * Convert a port name to its port and protocol numbers. 108 * We assume only TCP or UDP. 109 * Return 0 upon failure. 110 */ 111 int 112 pcap_nametoport(const char *name, int *port, int *proto) 113 { 114 struct servent *sp; 115 char *other; 116 117 sp = getservbyname(name, (char *)0); 118 if (sp != NULL) { 119 NTOHS(sp->s_port); 120 *port = sp->s_port; 121 *proto = pcap_nametoproto(sp->s_proto); 122 /* 123 * We need to check /etc/services for ambiguous entries. 124 * If we find the ambiguous entry, and it has the 125 * same port number, change the proto to PROTO_UNDEF 126 * so both TCP and UDP will be checked. 127 */ 128 if (*proto == IPPROTO_TCP) 129 other = "udp"; 130 else 131 other = "tcp"; 132 133 sp = getservbyname(name, other); 134 if (sp != 0) { 135 NTOHS(sp->s_port); 136 if (*port != sp->s_port) 137 /* Can't handle ambiguous names that refer 138 to different port numbers. */ 139 #ifdef notdef 140 warning("ambiguous port %s in /etc/services", 141 name); 142 #else 143 ; 144 #endif 145 *proto = PROTO_UNDEF; 146 } 147 return 1; 148 } 149 #if defined(ultrix) || defined(__osf__) 150 /* Special hack in case NFS isn't in /etc/services */ 151 if (strcmp(name, "nfs") == 0) { 152 *port = 2049; 153 *proto = PROTO_UNDEF; 154 return 1; 155 } 156 #endif 157 return 0; 158 } 159 160 int 161 pcap_nametoproto(const char *str) 162 { 163 struct protoent *p; 164 165 p = getprotobyname(str); 166 if (p != 0) 167 return p->p_proto; 168 else 169 return PROTO_UNDEF; 170 } 171 172 #include "ethertype.h" 173 174 struct eproto { 175 char *s; 176 u_short p; 177 }; 178 179 /* Static data base of ether protocol types. */ 180 struct eproto eproto_db[] = { 181 { "pup", ETHERTYPE_PUP }, 182 { "xns", ETHERTYPE_NS }, 183 { "ip", ETHERTYPE_IP }, 184 { "arp", ETHERTYPE_ARP }, 185 { "rarp", ETHERTYPE_REVARP }, 186 { "sprite", ETHERTYPE_SPRITE }, 187 { "mopdl", ETHERTYPE_MOPDL }, 188 { "moprc", ETHERTYPE_MOPRC }, 189 { "decnet", ETHERTYPE_DN }, 190 { "lat", ETHERTYPE_LAT }, 191 { "lanbridge", ETHERTYPE_LANBRIDGE }, 192 { "vexp", ETHERTYPE_VEXP }, 193 { "vprod", ETHERTYPE_VPROD }, 194 { "atalk", ETHERTYPE_ATALK }, 195 { "atalkarp", ETHERTYPE_AARP }, 196 { "loopback", ETHERTYPE_LOOPBACK }, 197 { "decdts", ETHERTYPE_DECDTS }, 198 { "decdns", ETHERTYPE_DECDNS }, 199 { (char *)0, 0 } 200 }; 201 202 int 203 pcap_nametoeproto(const char *s) 204 { 205 struct eproto *p = eproto_db; 206 207 while (p->s != 0) { 208 if (strcmp(p->s, s) == 0) 209 return p->p; 210 p += 1; 211 } 212 return PROTO_UNDEF; 213 } 214 215 /* Hex digit to integer. */ 216 static inline int 217 xdtoi(c) 218 register int c; 219 { 220 if (isdigit(c)) 221 return c - '0'; 222 else if (islower(c)) 223 return c - 'a' + 10; 224 else 225 return c - 'A' + 10; 226 } 227 228 u_long 229 __pcap_atoin(const char *s) 230 { 231 u_long addr = 0; 232 u_int n; 233 234 while (1) { 235 n = 0; 236 while (*s && *s != '.') 237 n = n * 10 + *s++ - '0'; 238 addr <<= 8; 239 addr |= n & 0xff; 240 if (*s == '\0') 241 return addr; 242 ++s; 243 } 244 /* NOTREACHED */ 245 } 246 247 u_long 248 __pcap_atodn(const char *s) 249 { 250 #define AREASHIFT 10 251 #define AREAMASK 0176000 252 #define NODEMASK 01777 253 254 u_long addr = 0; 255 u_int node, area; 256 257 if (sscanf((char *)s, "%d.%d", &area, &node) != 2) 258 bpf_error("malformed decnet address '%s'", s); 259 260 addr = (area << AREASHIFT) & AREAMASK; 261 addr |= (node & NODEMASK); 262 263 return(addr); 264 } 265 266 /* 267 * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new 268 * ethernet address. Assumes 's' is well formed. 269 */ 270 u_char * 271 pcap_ether_aton(const char *s) 272 { 273 register u_char *ep, *e; 274 register u_int d; 275 276 e = ep = (u_char *)malloc(6); 277 278 while (*s) { 279 if (*s == ':') 280 s += 1; 281 d = xdtoi(*s++); 282 if (isxdigit(*s)) { 283 d <<= 4; 284 d |= xdtoi(*s++); 285 } 286 *ep++ = d; 287 } 288 289 return (e); 290 } 291 292 #ifndef ETHER_SERVICE 293 /* Roll our own */ 294 u_char * 295 pcap_ether_hostton(const char *name) 296 { 297 register struct pcap_etherent *ep; 298 register u_char *ap; 299 static FILE *fp = NULL; 300 static init = 0; 301 302 if (!init) { 303 fp = fopen(PCAP_ETHERS_FILE, "r"); 304 ++init; 305 if (fp == NULL) 306 return (NULL); 307 } else if (fp == NULL) 308 return (NULL); 309 else 310 rewind(fp); 311 312 while ((ep = pcap_next_etherent(fp)) != NULL) { 313 if (strcmp(ep->name, name) == 0) { 314 ap = (u_char *)malloc(6); 315 if (ap != NULL) { 316 memcpy(ap, ep->addr, 6); 317 return (ap); 318 } 319 break; 320 } 321 } 322 return (NULL); 323 } 324 #else 325 /* Use the os supplied routines */ 326 u_char * 327 pcap_ether_hostton(const char *name) 328 { 329 register u_char *ap; 330 u_char a[6]; 331 #ifndef sgi 332 extern int ether_hostton(char *, struct ether_addr *); 333 #endif 334 335 ap = NULL; 336 if (ether_hostton((char*)name, (struct ether_addr *)a) == 0) { 337 ap = (u_char *)malloc(6); 338 if (ap != NULL) 339 memcpy(ap, a, 6); 340 } 341 return (ap); 342 } 343 #endif 344 345 u_short 346 __pcap_nametodnaddr(const char *name) 347 { 348 #ifdef DECNETLIB 349 struct nodeent *getnodebyname(); 350 struct nodeent *nep; 351 unsigned short res; 352 353 nep = getnodebyname(name); 354 if (nep == ((struct nodeent *)0)) 355 bpf_error("unknown decnet host name '%s'\n", name); 356 357 memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short)); 358 return(res); 359 #else 360 bpf_error("decnet name support not included, '%s' cannot be translated\n", 361 name); 362 #endif 363 } 364