1/*
| 1/*
|
2 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
| 2 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
|
3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * Internet, ethernet, port, and protocol string to address 22 * and address to string conversion routines 23 */ 24#ifndef lint 25static const char rcsid[] =
| 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * Internet, ethernet, port, and protocol string to address 22 * and address to string conversion routines 23 */ 24#ifndef lint 25static const char rcsid[] =
|
26 "@(#) $Header: addrtoname.c,v 1.54 96/12/05 22:10:19 leres Exp $ (LBL)";
| 26 "@(#) $Header: addrtoname.c,v 1.61 97/06/15 13:20:18 leres Exp $ (LBL)";
|
27#endif 28 29#include <sys/types.h> 30#include <sys/socket.h> 31#include <sys/time.h> 32 33#if __STDC__ 34struct mbuf; 35struct rtentry; 36#endif 37#include <net/if.h> 38 39#include <netinet/in.h> 40#include <net/ethernet.h> 41 42#include <arpa/inet.h> 43 44#include <ctype.h> 45#include <netdb.h> 46#include <pcap.h> 47#include <pcap-namedb.h>
| 27#endif 28 29#include <sys/types.h> 30#include <sys/socket.h> 31#include <sys/time.h> 32 33#if __STDC__ 34struct mbuf; 35struct rtentry; 36#endif 37#include <net/if.h> 38 39#include <netinet/in.h> 40#include <net/ethernet.h> 41 42#include <arpa/inet.h> 43 44#include <ctype.h> 45#include <netdb.h> 46#include <pcap.h> 47#include <pcap-namedb.h>
|
| 48#ifdef HAVE_MALLOC_H 49#include <malloc.h> 50#endif 51#ifdef HAVE_MEMORY_H 52#include <memory.h> 53#endif
|
48#include <signal.h> 49#include <stdio.h> 50#include <string.h> 51#include <stdlib.h> 52#include <unistd.h> 53 54#include "interface.h" 55#include "addrtoname.h" 56#include "llc.h"
| 54#include <signal.h> 55#include <stdio.h> 56#include <string.h> 57#include <stdlib.h> 58#include <unistd.h> 59 60#include "interface.h" 61#include "addrtoname.h" 62#include "llc.h"
|
| 63#include "savestr.h" 64#include "setsignal.h"
|
57 58/* Forwards */ 59static RETSIGTYPE nohostname(int); 60 61/* 62 * hash tables for whatever-to-name translations 63 */ 64 65#define HASHNAMESIZE 4096 66 67struct hnamemem { 68 u_int32_t addr; 69 char *name; 70 struct hnamemem *nxt; 71}; 72 73struct hnamemem hnametable[HASHNAMESIZE]; 74struct hnamemem tporttable[HASHNAMESIZE]; 75struct hnamemem uporttable[HASHNAMESIZE]; 76struct hnamemem eprototable[HASHNAMESIZE]; 77struct hnamemem dnaddrtable[HASHNAMESIZE]; 78struct hnamemem llcsaptable[HASHNAMESIZE]; 79 80struct enamemem { 81 u_short e_addr0; 82 u_short e_addr1; 83 u_short e_addr2; 84 char *e_name; 85 u_char *e_nsap; /* used only for nsaptable[] */ 86 struct enamemem *e_nxt; 87}; 88 89struct enamemem enametable[HASHNAMESIZE]; 90struct enamemem nsaptable[HASHNAMESIZE]; 91 92struct protoidmem { 93 u_int32_t p_oui; 94 u_short p_proto; 95 char *p_name; 96 struct protoidmem *p_nxt; 97}; 98 99struct protoidmem protoidtable[HASHNAMESIZE]; 100 101/* 102 * A faster replacement for inet_ntoa(). 103 */ 104char * 105intoa(u_int32_t addr) 106{ 107 register char *cp; 108 register u_int byte; 109 register int n; 110 static char buf[sizeof(".xxx.xxx.xxx.xxx")]; 111 112 NTOHL(addr); 113 cp = &buf[sizeof buf]; 114 *--cp = '\0'; 115 116 n = 4; 117 do { 118 byte = addr & 0xff; 119 *--cp = byte % 10 + '0'; 120 byte /= 10; 121 if (byte > 0) { 122 *--cp = byte % 10 + '0'; 123 byte /= 10; 124 if (byte > 0) 125 *--cp = byte + '0'; 126 } 127 *--cp = '.'; 128 addr >>= 8; 129 } while (--n > 0); 130 131 return cp + 1; 132} 133 134static u_int32_t f_netmask; 135static u_int32_t f_localnet; 136static u_int32_t netmask; 137 138/* 139 * "getname" is written in this atrocious way to make sure we don't 140 * wait forever while trying to get hostnames from yp. 141 */ 142#include <setjmp.h> 143 144jmp_buf getname_env; 145 146static RETSIGTYPE 147nohostname(int signo) 148{ 149 longjmp(getname_env, 1); 150} 151 152/* 153 * Return a name for the IP address pointed to by ap. This address 154 * is assumed to be in network byte order. 155 */ 156char * 157getname(const u_char *ap) 158{ 159 register struct hostent *hp; 160 u_int32_t addr; 161 static struct hnamemem *p; /* static for longjmp() */ 162 163#ifndef LBL_ALIGN 164 addr = *(const u_int32_t *)ap; 165#else 166 /* 167 * Extract 32 bits in network order, dealing with alignment. 168 */ 169 switch ((long)ap & 3) { 170 171 case 0: 172 addr = *(u_int32_t *)ap; 173 break; 174 175 case 2: 176#ifdef WORDS_BIGENDIAN 177 addr = ((u_int32_t)*(u_short *)ap << 16) | 178 (u_int32_t)*(u_short *)(ap + 2); 179#else 180 addr = ((u_int32_t)*(u_short *)(ap + 2) << 16) | 181 (u_int32_t)*(u_short *)ap; 182#endif 183 break; 184 185 default: 186#ifdef WORDS_BIGENDIAN 187 addr = ((u_int32_t)ap[0] << 24) | 188 ((u_int32_t)ap[1] << 16) | 189 ((u_int32_t)ap[2] << 8) | 190 (u_int32_t)ap[3]; 191#else 192 addr = ((u_int32_t)ap[3] << 24) | 193 ((u_int32_t)ap[2] << 16) | 194 ((u_int32_t)ap[1] << 8) | 195 (u_int32_t)ap[0]; 196#endif 197 break; 198 } 199#endif 200 p = &hnametable[addr & (HASHNAMESIZE-1)]; 201 for (; p->nxt; p = p->nxt) { 202 if (p->addr == addr) 203 return (p->name); 204 } 205 p->addr = addr; 206 p->nxt = newhnamemem(); 207 208 /* 209 * Only print names when: 210 * (1) -n was not given.
| 65 66/* Forwards */ 67static RETSIGTYPE nohostname(int); 68 69/* 70 * hash tables for whatever-to-name translations 71 */ 72 73#define HASHNAMESIZE 4096 74 75struct hnamemem { 76 u_int32_t addr; 77 char *name; 78 struct hnamemem *nxt; 79}; 80 81struct hnamemem hnametable[HASHNAMESIZE]; 82struct hnamemem tporttable[HASHNAMESIZE]; 83struct hnamemem uporttable[HASHNAMESIZE]; 84struct hnamemem eprototable[HASHNAMESIZE]; 85struct hnamemem dnaddrtable[HASHNAMESIZE]; 86struct hnamemem llcsaptable[HASHNAMESIZE]; 87 88struct enamemem { 89 u_short e_addr0; 90 u_short e_addr1; 91 u_short e_addr2; 92 char *e_name; 93 u_char *e_nsap; /* used only for nsaptable[] */ 94 struct enamemem *e_nxt; 95}; 96 97struct enamemem enametable[HASHNAMESIZE]; 98struct enamemem nsaptable[HASHNAMESIZE]; 99 100struct protoidmem { 101 u_int32_t p_oui; 102 u_short p_proto; 103 char *p_name; 104 struct protoidmem *p_nxt; 105}; 106 107struct protoidmem protoidtable[HASHNAMESIZE]; 108 109/* 110 * A faster replacement for inet_ntoa(). 111 */ 112char * 113intoa(u_int32_t addr) 114{ 115 register char *cp; 116 register u_int byte; 117 register int n; 118 static char buf[sizeof(".xxx.xxx.xxx.xxx")]; 119 120 NTOHL(addr); 121 cp = &buf[sizeof buf]; 122 *--cp = '\0'; 123 124 n = 4; 125 do { 126 byte = addr & 0xff; 127 *--cp = byte % 10 + '0'; 128 byte /= 10; 129 if (byte > 0) { 130 *--cp = byte % 10 + '0'; 131 byte /= 10; 132 if (byte > 0) 133 *--cp = byte + '0'; 134 } 135 *--cp = '.'; 136 addr >>= 8; 137 } while (--n > 0); 138 139 return cp + 1; 140} 141 142static u_int32_t f_netmask; 143static u_int32_t f_localnet; 144static u_int32_t netmask; 145 146/* 147 * "getname" is written in this atrocious way to make sure we don't 148 * wait forever while trying to get hostnames from yp. 149 */ 150#include <setjmp.h> 151 152jmp_buf getname_env; 153 154static RETSIGTYPE 155nohostname(int signo) 156{ 157 longjmp(getname_env, 1); 158} 159 160/* 161 * Return a name for the IP address pointed to by ap. This address 162 * is assumed to be in network byte order. 163 */ 164char * 165getname(const u_char *ap) 166{ 167 register struct hostent *hp; 168 u_int32_t addr; 169 static struct hnamemem *p; /* static for longjmp() */ 170 171#ifndef LBL_ALIGN 172 addr = *(const u_int32_t *)ap; 173#else 174 /* 175 * Extract 32 bits in network order, dealing with alignment. 176 */ 177 switch ((long)ap & 3) { 178 179 case 0: 180 addr = *(u_int32_t *)ap; 181 break; 182 183 case 2: 184#ifdef WORDS_BIGENDIAN 185 addr = ((u_int32_t)*(u_short *)ap << 16) | 186 (u_int32_t)*(u_short *)(ap + 2); 187#else 188 addr = ((u_int32_t)*(u_short *)(ap + 2) << 16) | 189 (u_int32_t)*(u_short *)ap; 190#endif 191 break; 192 193 default: 194#ifdef WORDS_BIGENDIAN 195 addr = ((u_int32_t)ap[0] << 24) | 196 ((u_int32_t)ap[1] << 16) | 197 ((u_int32_t)ap[2] << 8) | 198 (u_int32_t)ap[3]; 199#else 200 addr = ((u_int32_t)ap[3] << 24) | 201 ((u_int32_t)ap[2] << 16) | 202 ((u_int32_t)ap[1] << 8) | 203 (u_int32_t)ap[0]; 204#endif 205 break; 206 } 207#endif 208 p = &hnametable[addr & (HASHNAMESIZE-1)]; 209 for (; p->nxt; p = p->nxt) { 210 if (p->addr == addr) 211 return (p->name); 212 } 213 p->addr = addr; 214 p->nxt = newhnamemem(); 215 216 /* 217 * Only print names when: 218 * (1) -n was not given.
|
211 * (2) Address is foreign and -f was given. If -f was not 212 * present, f_netmask and f_local are 0 and the second 213 * test will succeed. 214 * (3) The host portion is not 0 (i.e., a network address). 215 * (4) The host portion is not broadcast.
| 219 * (2) Address is foreign and -f was given. (If -f was not 220 * give, f_netmask and f_local are 0 and the test 221 * evaluates to true) 222 * (3) -a was given or the host portion is not all ones 223 * nor all zeros (i.e. not a network or broadcast address)
|
216 */
| 224 */
|
217 if (!nflag && (addr & f_netmask) == f_localnet 218 && (addr &~ netmask) != 0 && (addr | netmask) != 0xffffffff) {
| 225 if (!nflag && 226 (addr & f_netmask) == f_localnet && 227 (aflag || 228 !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))) {
|
219 if (!setjmp(getname_env)) {
| 229 if (!setjmp(getname_env)) {
|
220 (void)signal(SIGALRM, nohostname);
| 230 (void)setsignal(SIGALRM, nohostname);
|
221 (void)alarm(20); 222 hp = gethostbyaddr((char *)&addr, 4, AF_INET); 223 (void)alarm(0); 224 if (hp) { 225 char *dotp; 226 227 p->name = savestr(hp->h_name); 228 if (Nflag) { 229 /* Remove domain qualifications */ 230 dotp = strchr(p->name, '.'); 231 if (dotp) 232 *dotp = '\0'; 233 } 234 return (p->name); 235 } 236 } 237 } 238 p->name = savestr(intoa(addr)); 239 return (p->name); 240} 241 242static char hex[] = "0123456789abcdef"; 243 244 245/* Find the hash node that corresponds the ether address 'ep' */ 246 247static inline struct enamemem * 248lookup_emem(const u_char *ep) 249{ 250 register u_int i, j, k; 251 struct enamemem *tp; 252 253 k = (ep[0] << 8) | ep[1]; 254 j = (ep[2] << 8) | ep[3]; 255 i = (ep[4] << 8) | ep[5]; 256 257 tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)]; 258 while (tp->e_nxt) 259 if (tp->e_addr0 == i && 260 tp->e_addr1 == j && 261 tp->e_addr2 == k) 262 return tp; 263 else 264 tp = tp->e_nxt; 265 tp->e_addr0 = i; 266 tp->e_addr1 = j; 267 tp->e_addr2 = k; 268 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 269 if (tp->e_nxt == NULL) 270 error("lookup_emem: calloc"); 271 272 return tp; 273} 274 275/* Find the hash node that corresponds the NSAP 'nsap' */ 276 277static inline struct enamemem * 278lookup_nsap(register const u_char *nsap) 279{ 280 register u_int i, j, k; 281 int nlen = *nsap; 282 struct enamemem *tp; 283 const u_char *ensap = nsap + nlen - 6; 284 285 if (nlen > 6) { 286 k = (ensap[0] << 8) | ensap[1]; 287 j = (ensap[2] << 8) | ensap[3]; 288 i = (ensap[4] << 8) | ensap[5]; 289 } 290 else 291 i = j = k = 0; 292 293 tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)]; 294 while (tp->e_nxt) 295 if (tp->e_addr0 == i && 296 tp->e_addr1 == j && 297 tp->e_addr2 == k && 298 tp->e_nsap[0] == nlen && 299 memcmp((char *)&(nsap[1]), 300 (char *)&(tp->e_nsap[1]), nlen) == 0) 301 return tp; 302 else 303 tp = tp->e_nxt; 304 tp->e_addr0 = i; 305 tp->e_addr1 = j; 306 tp->e_addr2 = k; 307 tp->e_nsap = (u_char *)malloc(nlen + 1); 308 if (tp->e_nsap == NULL) 309 error("lookup_nsap: malloc");
| 231 (void)alarm(20); 232 hp = gethostbyaddr((char *)&addr, 4, AF_INET); 233 (void)alarm(0); 234 if (hp) { 235 char *dotp; 236 237 p->name = savestr(hp->h_name); 238 if (Nflag) { 239 /* Remove domain qualifications */ 240 dotp = strchr(p->name, '.'); 241 if (dotp) 242 *dotp = '\0'; 243 } 244 return (p->name); 245 } 246 } 247 } 248 p->name = savestr(intoa(addr)); 249 return (p->name); 250} 251 252static char hex[] = "0123456789abcdef"; 253 254 255/* Find the hash node that corresponds the ether address 'ep' */ 256 257static inline struct enamemem * 258lookup_emem(const u_char *ep) 259{ 260 register u_int i, j, k; 261 struct enamemem *tp; 262 263 k = (ep[0] << 8) | ep[1]; 264 j = (ep[2] << 8) | ep[3]; 265 i = (ep[4] << 8) | ep[5]; 266 267 tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)]; 268 while (tp->e_nxt) 269 if (tp->e_addr0 == i && 270 tp->e_addr1 == j && 271 tp->e_addr2 == k) 272 return tp; 273 else 274 tp = tp->e_nxt; 275 tp->e_addr0 = i; 276 tp->e_addr1 = j; 277 tp->e_addr2 = k; 278 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 279 if (tp->e_nxt == NULL) 280 error("lookup_emem: calloc"); 281 282 return tp; 283} 284 285/* Find the hash node that corresponds the NSAP 'nsap' */ 286 287static inline struct enamemem * 288lookup_nsap(register const u_char *nsap) 289{ 290 register u_int i, j, k; 291 int nlen = *nsap; 292 struct enamemem *tp; 293 const u_char *ensap = nsap + nlen - 6; 294 295 if (nlen > 6) { 296 k = (ensap[0] << 8) | ensap[1]; 297 j = (ensap[2] << 8) | ensap[3]; 298 i = (ensap[4] << 8) | ensap[5]; 299 } 300 else 301 i = j = k = 0; 302 303 tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)]; 304 while (tp->e_nxt) 305 if (tp->e_addr0 == i && 306 tp->e_addr1 == j && 307 tp->e_addr2 == k && 308 tp->e_nsap[0] == nlen && 309 memcmp((char *)&(nsap[1]), 310 (char *)&(tp->e_nsap[1]), nlen) == 0) 311 return tp; 312 else 313 tp = tp->e_nxt; 314 tp->e_addr0 = i; 315 tp->e_addr1 = j; 316 tp->e_addr2 = k; 317 tp->e_nsap = (u_char *)malloc(nlen + 1); 318 if (tp->e_nsap == NULL) 319 error("lookup_nsap: malloc");
|
310 memcpy(tp->e_nsap, nsap, nlen + 1);
| 320 memcpy((char *)tp->e_nsap, (char *)nsap, nlen + 1);
|
311 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 312 if (tp->e_nxt == NULL) 313 error("lookup_nsap: calloc"); 314 315 return tp; 316} 317 318/* Find the hash node that corresponds the protoid 'pi'. */ 319 320static inline struct protoidmem * 321lookup_protoid(const u_char *pi) 322{ 323 register u_int i, j; 324 struct protoidmem *tp; 325 326 /* 5 octets won't be aligned */ 327 i = (((pi[0] << 8) + pi[1]) << 8) + pi[2]; 328 j = (pi[3] << 8) + pi[4]; 329 /* XXX should be endian-insensitive, but do big-endian testing XXX */ 330 331 tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)]; 332 while (tp->p_nxt) 333 if (tp->p_oui == i && tp->p_proto == j) 334 return tp; 335 else 336 tp = tp->p_nxt; 337 tp->p_oui = i; 338 tp->p_proto = j; 339 tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp)); 340 if (tp->p_nxt == NULL) 341 error("lookup_protoid: calloc"); 342 343 return tp; 344} 345 346char * 347etheraddr_string(register const u_char *ep) 348{ 349 register u_int i, j; 350 register char *cp; 351 register struct enamemem *tp; 352 char buf[sizeof("00:00:00:00:00:00")]; 353 354 tp = lookup_emem(ep); 355 if (tp->e_name) 356 return (tp->e_name); 357#ifdef HAVE_ETHER_NTOHOST 358 if (!nflag) { 359 char buf[128]; 360 if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) { 361 tp->e_name = savestr(buf); 362 return (tp->e_name); 363 } 364 } 365#endif 366 cp = buf; 367 if ((j = *ep >> 4) != 0) 368 *cp++ = hex[j]; 369 *cp++ = hex[*ep++ & 0xf]; 370 for (i = 5; (int)--i >= 0;) { 371 *cp++ = ':'; 372 if ((j = *ep >> 4) != 0) 373 *cp++ = hex[j]; 374 *cp++ = hex[*ep++ & 0xf]; 375 } 376 *cp = '\0'; 377 tp->e_name = savestr(buf); 378 return (tp->e_name); 379} 380 381char * 382etherproto_string(u_short port) 383{ 384 register char *cp; 385 register struct hnamemem *tp; 386 register u_int32_t i = port; 387 char buf[sizeof("0000")]; 388 389 for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 390 if (tp->addr == i) 391 return (tp->name); 392 393 tp->addr = i; 394 tp->nxt = newhnamemem(); 395 396 cp = buf; 397 NTOHS(port); 398 *cp++ = hex[port >> 12 & 0xf]; 399 *cp++ = hex[port >> 8 & 0xf]; 400 *cp++ = hex[port >> 4 & 0xf]; 401 *cp++ = hex[port & 0xf]; 402 *cp++ = '\0'; 403 tp->name = savestr(buf); 404 return (tp->name); 405} 406 407char * 408protoid_string(register const u_char *pi) 409{ 410 register u_int i, j; 411 register char *cp; 412 register struct protoidmem *tp; 413 char buf[sizeof("00:00:00:00:00")]; 414 415 tp = lookup_protoid(pi); 416 if (tp->p_name) 417 return tp->p_name; 418 419 cp = buf; 420 if ((j = *pi >> 4) != 0) 421 *cp++ = hex[j]; 422 *cp++ = hex[*pi++ & 0xf]; 423 for (i = 4; (int)--i >= 0;) { 424 *cp++ = ':'; 425 if ((j = *pi >> 4) != 0) 426 *cp++ = hex[j]; 427 *cp++ = hex[*pi++ & 0xf]; 428 } 429 *cp = '\0'; 430 tp->p_name = savestr(buf); 431 return (tp->p_name); 432} 433 434char * 435llcsap_string(u_char sap) 436{ 437 register char *cp; 438 register struct hnamemem *tp; 439 register u_int32_t i = sap; 440 char buf[sizeof("sap 00")]; 441 442 for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 443 if (tp->addr == i) 444 return (tp->name); 445 446 tp->addr = i; 447 tp->nxt = newhnamemem(); 448 449 cp = buf; 450 (void)strcpy(cp, "sap "); 451 cp += strlen(cp); 452 *cp++ = hex[sap >> 4 & 0xf]; 453 *cp++ = hex[sap & 0xf]; 454 *cp++ = '\0'; 455 tp->name = savestr(buf); 456 return (tp->name); 457} 458 459char * 460isonsap_string(const u_char *nsap) 461{ 462 register u_int i, nlen = nsap[0]; 463 register char *cp; 464 register struct enamemem *tp; 465 466 tp = lookup_nsap(nsap); 467 if (tp->e_name) 468 return tp->e_name; 469 470 tp->e_name = cp = (char *)malloc(nlen * 2 + 2 + (nlen>>1)); 471 if (cp == NULL) 472 error("isonsap_string: malloc"); 473 474 nsap++; 475 for (i = 0; i < nlen; i++) { 476 *cp++ = hex[*nsap >> 4]; 477 *cp++ = hex[*nsap++ & 0xf]; 478 if (((i & 1) == 0) && (i + 1 < nlen)) 479 *cp++ = '.'; 480 } 481 *cp = '\0'; 482 return (tp->e_name); 483} 484 485char * 486tcpport_string(u_short port) 487{ 488 register struct hnamemem *tp; 489 register u_int32_t i = port; 490 char buf[sizeof("00000")]; 491 492 for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 493 if (tp->addr == i) 494 return (tp->name); 495 496 tp->addr = i; 497 tp->nxt = newhnamemem(); 498 499 (void)sprintf(buf, "%u", i); 500 tp->name = savestr(buf); 501 return (tp->name); 502} 503 504char * 505udpport_string(register u_short port) 506{ 507 register struct hnamemem *tp; 508 register u_int32_t i = port; 509 char buf[sizeof("00000")]; 510 511 for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 512 if (tp->addr == i) 513 return (tp->name); 514 515 tp->addr = i; 516 tp->nxt = newhnamemem(); 517 518 (void)sprintf(buf, "%u", i); 519 tp->name = savestr(buf); 520 return (tp->name); 521} 522 523static void 524init_servarray(void) 525{ 526 struct servent *sv; 527 register struct hnamemem *table; 528 register int i; 529 char buf[sizeof("0000000000")]; 530 531 while ((sv = getservent()) != NULL) { 532 int port = ntohs(sv->s_port); 533 i = port & (HASHNAMESIZE-1); 534 if (strcmp(sv->s_proto, "tcp") == 0) 535 table = &tporttable[i]; 536 else if (strcmp(sv->s_proto, "udp") == 0) 537 table = &uporttable[i]; 538 else 539 continue; 540 541 while (table->name) 542 table = table->nxt; 543 if (nflag) { 544 (void)sprintf(buf, "%d", port); 545 table->name = savestr(buf); 546 } else 547 table->name = savestr(sv->s_name); 548 table->addr = port; 549 table->nxt = newhnamemem(); 550 } 551 endservent(); 552} 553 554/*XXX from libbpfc.a */ 555extern struct eproto { 556 char *s; 557 u_short p; 558} eproto_db[]; 559 560static void 561init_eprotoarray(void) 562{ 563 register int i; 564 register struct hnamemem *table; 565 566 for (i = 0; eproto_db[i].s; i++) { 567 int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1); 568 table = &eprototable[j]; 569 while (table->name) 570 table = table->nxt; 571 table->name = eproto_db[i].s; 572 table->addr = ntohs(eproto_db[i].p); 573 table->nxt = newhnamemem(); 574 } 575} 576 577/* 578 * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet 579 * types. 580 */ 581static void 582init_protoidarray(void) 583{ 584 register int i; 585 register struct protoidmem *tp; 586 u_char protoid[5]; 587 588 protoid[0] = 0; 589 protoid[1] = 0; 590 protoid[2] = 0; 591 for (i = 0; eproto_db[i].s; i++) { 592 u_short etype = htons(eproto_db[i].p); 593 594 memcpy((char *)&protoid[3], (char *)&etype, 2); 595 tp = lookup_protoid(protoid); 596 tp->p_name = savestr(eproto_db[i].s); 597 } 598} 599 600static struct etherlist { 601 u_char addr[6]; 602 char *name; 603} etherlist[] = { 604 {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" }, 605 {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL } 606}; 607 608/* 609 * Initialize the ethers hash table. We take two different approaches 610 * depending on whether or not the system provides the ethers name 611 * service. If it does, we just wire in a few names at startup, 612 * and etheraddr_string() fills in the table on demand. If it doesn't, 613 * then we suck in the entire /etc/ethers file at startup. The idea 614 * is that parsing the local file will be fast, but spinning through 615 * all the ethers entries via NIS & next_etherent might be very slow. 616 * 617 * XXX pcap_next_etherent doesn't belong in the pcap interface, but 618 * since the pcap module already does name-to-address translation, 619 * it's already does most of the work for the ethernet address-to-name 620 * translation, so we just pcap_next_etherent as a convenience. 621 */ 622static void 623init_etherarray(void) 624{ 625 register struct etherlist *el; 626 register struct enamemem *tp; 627#ifdef HAVE_ETHER_NTOHOST 628 char name[256]; 629#else 630 register struct pcap_etherent *ep; 631 register FILE *fp; 632 633 /* Suck in entire ethers file */ 634 fp = fopen(PCAP_ETHERS_FILE, "r"); 635 if (fp != NULL) { 636 while ((ep = pcap_next_etherent(fp)) != NULL) { 637 tp = lookup_emem(ep->addr); 638 tp->e_name = savestr(ep->name); 639 } 640 (void)fclose(fp); 641 } 642#endif 643 644 /* Hardwire some ethernet names */ 645 for (el = etherlist; el->name != NULL; ++el) { 646 tp = lookup_emem(el->addr); 647 /* Don't override existing name */ 648 if (tp->e_name != NULL) 649 continue; 650 651#ifdef HAVE_ETHER_NTOHOST 652 /* Use yp/nis version of name if available */ 653 if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) { 654 tp->e_name = savestr(name); 655 continue; 656 } 657#endif 658 tp->e_name = el->name; 659 } 660} 661 662static struct tok llcsap_db[] = { 663 { LLCSAP_NULL, "null" }, 664 { LLCSAP_8021B_I, "802.1b-gsap" }, 665 { LLCSAP_8021B_G, "802.1b-isap" }, 666 { LLCSAP_IP, "ip-sap" }, 667 { LLCSAP_PROWAYNM, "proway-nm" }, 668 { LLCSAP_8021D, "802.1d" }, 669 { LLCSAP_RS511, "eia-rs511" }, 670 { LLCSAP_ISO8208, "x.25/llc2" }, 671 { LLCSAP_PROWAY, "proway" }, 672 { LLCSAP_ISONS, "iso-clns" }, 673 { LLCSAP_GLOBAL, "global" }, 674 { 0, NULL } 675}; 676 677static void 678init_llcsaparray(void) 679{ 680 register int i; 681 register struct hnamemem *table; 682 683 for (i = 0; llcsap_db[i].s != NULL; i++) { 684 table = &llcsaptable[llcsap_db[i].v]; 685 while (table->name) 686 table = table->nxt; 687 table->name = llcsap_db[i].s; 688 table->addr = llcsap_db[i].v; 689 table->nxt = newhnamemem(); 690 } 691} 692 693/* 694 * Initialize the address to name translation machinery. We map all 695 * non-local IP addresses to numeric addresses if fflag is true (i.e., 696 * to prevent blocking on the nameserver). localnet is the IP address 697 * of the local network. mask is its subnet mask. 698 */ 699void
| 321 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 322 if (tp->e_nxt == NULL) 323 error("lookup_nsap: calloc"); 324 325 return tp; 326} 327 328/* Find the hash node that corresponds the protoid 'pi'. */ 329 330static inline struct protoidmem * 331lookup_protoid(const u_char *pi) 332{ 333 register u_int i, j; 334 struct protoidmem *tp; 335 336 /* 5 octets won't be aligned */ 337 i = (((pi[0] << 8) + pi[1]) << 8) + pi[2]; 338 j = (pi[3] << 8) + pi[4]; 339 /* XXX should be endian-insensitive, but do big-endian testing XXX */ 340 341 tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)]; 342 while (tp->p_nxt) 343 if (tp->p_oui == i && tp->p_proto == j) 344 return tp; 345 else 346 tp = tp->p_nxt; 347 tp->p_oui = i; 348 tp->p_proto = j; 349 tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp)); 350 if (tp->p_nxt == NULL) 351 error("lookup_protoid: calloc"); 352 353 return tp; 354} 355 356char * 357etheraddr_string(register const u_char *ep) 358{ 359 register u_int i, j; 360 register char *cp; 361 register struct enamemem *tp; 362 char buf[sizeof("00:00:00:00:00:00")]; 363 364 tp = lookup_emem(ep); 365 if (tp->e_name) 366 return (tp->e_name); 367#ifdef HAVE_ETHER_NTOHOST 368 if (!nflag) { 369 char buf[128]; 370 if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) { 371 tp->e_name = savestr(buf); 372 return (tp->e_name); 373 } 374 } 375#endif 376 cp = buf; 377 if ((j = *ep >> 4) != 0) 378 *cp++ = hex[j]; 379 *cp++ = hex[*ep++ & 0xf]; 380 for (i = 5; (int)--i >= 0;) { 381 *cp++ = ':'; 382 if ((j = *ep >> 4) != 0) 383 *cp++ = hex[j]; 384 *cp++ = hex[*ep++ & 0xf]; 385 } 386 *cp = '\0'; 387 tp->e_name = savestr(buf); 388 return (tp->e_name); 389} 390 391char * 392etherproto_string(u_short port) 393{ 394 register char *cp; 395 register struct hnamemem *tp; 396 register u_int32_t i = port; 397 char buf[sizeof("0000")]; 398 399 for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 400 if (tp->addr == i) 401 return (tp->name); 402 403 tp->addr = i; 404 tp->nxt = newhnamemem(); 405 406 cp = buf; 407 NTOHS(port); 408 *cp++ = hex[port >> 12 & 0xf]; 409 *cp++ = hex[port >> 8 & 0xf]; 410 *cp++ = hex[port >> 4 & 0xf]; 411 *cp++ = hex[port & 0xf]; 412 *cp++ = '\0'; 413 tp->name = savestr(buf); 414 return (tp->name); 415} 416 417char * 418protoid_string(register const u_char *pi) 419{ 420 register u_int i, j; 421 register char *cp; 422 register struct protoidmem *tp; 423 char buf[sizeof("00:00:00:00:00")]; 424 425 tp = lookup_protoid(pi); 426 if (tp->p_name) 427 return tp->p_name; 428 429 cp = buf; 430 if ((j = *pi >> 4) != 0) 431 *cp++ = hex[j]; 432 *cp++ = hex[*pi++ & 0xf]; 433 for (i = 4; (int)--i >= 0;) { 434 *cp++ = ':'; 435 if ((j = *pi >> 4) != 0) 436 *cp++ = hex[j]; 437 *cp++ = hex[*pi++ & 0xf]; 438 } 439 *cp = '\0'; 440 tp->p_name = savestr(buf); 441 return (tp->p_name); 442} 443 444char * 445llcsap_string(u_char sap) 446{ 447 register char *cp; 448 register struct hnamemem *tp; 449 register u_int32_t i = sap; 450 char buf[sizeof("sap 00")]; 451 452 for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 453 if (tp->addr == i) 454 return (tp->name); 455 456 tp->addr = i; 457 tp->nxt = newhnamemem(); 458 459 cp = buf; 460 (void)strcpy(cp, "sap "); 461 cp += strlen(cp); 462 *cp++ = hex[sap >> 4 & 0xf]; 463 *cp++ = hex[sap & 0xf]; 464 *cp++ = '\0'; 465 tp->name = savestr(buf); 466 return (tp->name); 467} 468 469char * 470isonsap_string(const u_char *nsap) 471{ 472 register u_int i, nlen = nsap[0]; 473 register char *cp; 474 register struct enamemem *tp; 475 476 tp = lookup_nsap(nsap); 477 if (tp->e_name) 478 return tp->e_name; 479 480 tp->e_name = cp = (char *)malloc(nlen * 2 + 2 + (nlen>>1)); 481 if (cp == NULL) 482 error("isonsap_string: malloc"); 483 484 nsap++; 485 for (i = 0; i < nlen; i++) { 486 *cp++ = hex[*nsap >> 4]; 487 *cp++ = hex[*nsap++ & 0xf]; 488 if (((i & 1) == 0) && (i + 1 < nlen)) 489 *cp++ = '.'; 490 } 491 *cp = '\0'; 492 return (tp->e_name); 493} 494 495char * 496tcpport_string(u_short port) 497{ 498 register struct hnamemem *tp; 499 register u_int32_t i = port; 500 char buf[sizeof("00000")]; 501 502 for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 503 if (tp->addr == i) 504 return (tp->name); 505 506 tp->addr = i; 507 tp->nxt = newhnamemem(); 508 509 (void)sprintf(buf, "%u", i); 510 tp->name = savestr(buf); 511 return (tp->name); 512} 513 514char * 515udpport_string(register u_short port) 516{ 517 register struct hnamemem *tp; 518 register u_int32_t i = port; 519 char buf[sizeof("00000")]; 520 521 for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 522 if (tp->addr == i) 523 return (tp->name); 524 525 tp->addr = i; 526 tp->nxt = newhnamemem(); 527 528 (void)sprintf(buf, "%u", i); 529 tp->name = savestr(buf); 530 return (tp->name); 531} 532 533static void 534init_servarray(void) 535{ 536 struct servent *sv; 537 register struct hnamemem *table; 538 register int i; 539 char buf[sizeof("0000000000")]; 540 541 while ((sv = getservent()) != NULL) { 542 int port = ntohs(sv->s_port); 543 i = port & (HASHNAMESIZE-1); 544 if (strcmp(sv->s_proto, "tcp") == 0) 545 table = &tporttable[i]; 546 else if (strcmp(sv->s_proto, "udp") == 0) 547 table = &uporttable[i]; 548 else 549 continue; 550 551 while (table->name) 552 table = table->nxt; 553 if (nflag) { 554 (void)sprintf(buf, "%d", port); 555 table->name = savestr(buf); 556 } else 557 table->name = savestr(sv->s_name); 558 table->addr = port; 559 table->nxt = newhnamemem(); 560 } 561 endservent(); 562} 563 564/*XXX from libbpfc.a */ 565extern struct eproto { 566 char *s; 567 u_short p; 568} eproto_db[]; 569 570static void 571init_eprotoarray(void) 572{ 573 register int i; 574 register struct hnamemem *table; 575 576 for (i = 0; eproto_db[i].s; i++) { 577 int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1); 578 table = &eprototable[j]; 579 while (table->name) 580 table = table->nxt; 581 table->name = eproto_db[i].s; 582 table->addr = ntohs(eproto_db[i].p); 583 table->nxt = newhnamemem(); 584 } 585} 586 587/* 588 * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet 589 * types. 590 */ 591static void 592init_protoidarray(void) 593{ 594 register int i; 595 register struct protoidmem *tp; 596 u_char protoid[5]; 597 598 protoid[0] = 0; 599 protoid[1] = 0; 600 protoid[2] = 0; 601 for (i = 0; eproto_db[i].s; i++) { 602 u_short etype = htons(eproto_db[i].p); 603 604 memcpy((char *)&protoid[3], (char *)&etype, 2); 605 tp = lookup_protoid(protoid); 606 tp->p_name = savestr(eproto_db[i].s); 607 } 608} 609 610static struct etherlist { 611 u_char addr[6]; 612 char *name; 613} etherlist[] = { 614 {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" }, 615 {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL } 616}; 617 618/* 619 * Initialize the ethers hash table. We take two different approaches 620 * depending on whether or not the system provides the ethers name 621 * service. If it does, we just wire in a few names at startup, 622 * and etheraddr_string() fills in the table on demand. If it doesn't, 623 * then we suck in the entire /etc/ethers file at startup. The idea 624 * is that parsing the local file will be fast, but spinning through 625 * all the ethers entries via NIS & next_etherent might be very slow. 626 * 627 * XXX pcap_next_etherent doesn't belong in the pcap interface, but 628 * since the pcap module already does name-to-address translation, 629 * it's already does most of the work for the ethernet address-to-name 630 * translation, so we just pcap_next_etherent as a convenience. 631 */ 632static void 633init_etherarray(void) 634{ 635 register struct etherlist *el; 636 register struct enamemem *tp; 637#ifdef HAVE_ETHER_NTOHOST 638 char name[256]; 639#else 640 register struct pcap_etherent *ep; 641 register FILE *fp; 642 643 /* Suck in entire ethers file */ 644 fp = fopen(PCAP_ETHERS_FILE, "r"); 645 if (fp != NULL) { 646 while ((ep = pcap_next_etherent(fp)) != NULL) { 647 tp = lookup_emem(ep->addr); 648 tp->e_name = savestr(ep->name); 649 } 650 (void)fclose(fp); 651 } 652#endif 653 654 /* Hardwire some ethernet names */ 655 for (el = etherlist; el->name != NULL; ++el) { 656 tp = lookup_emem(el->addr); 657 /* Don't override existing name */ 658 if (tp->e_name != NULL) 659 continue; 660 661#ifdef HAVE_ETHER_NTOHOST 662 /* Use yp/nis version of name if available */ 663 if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) { 664 tp->e_name = savestr(name); 665 continue; 666 } 667#endif 668 tp->e_name = el->name; 669 } 670} 671 672static struct tok llcsap_db[] = { 673 { LLCSAP_NULL, "null" }, 674 { LLCSAP_8021B_I, "802.1b-gsap" }, 675 { LLCSAP_8021B_G, "802.1b-isap" }, 676 { LLCSAP_IP, "ip-sap" }, 677 { LLCSAP_PROWAYNM, "proway-nm" }, 678 { LLCSAP_8021D, "802.1d" }, 679 { LLCSAP_RS511, "eia-rs511" }, 680 { LLCSAP_ISO8208, "x.25/llc2" }, 681 { LLCSAP_PROWAY, "proway" }, 682 { LLCSAP_ISONS, "iso-clns" }, 683 { LLCSAP_GLOBAL, "global" }, 684 { 0, NULL } 685}; 686 687static void 688init_llcsaparray(void) 689{ 690 register int i; 691 register struct hnamemem *table; 692 693 for (i = 0; llcsap_db[i].s != NULL; i++) { 694 table = &llcsaptable[llcsap_db[i].v]; 695 while (table->name) 696 table = table->nxt; 697 table->name = llcsap_db[i].s; 698 table->addr = llcsap_db[i].v; 699 table->nxt = newhnamemem(); 700 } 701} 702 703/* 704 * Initialize the address to name translation machinery. We map all 705 * non-local IP addresses to numeric addresses if fflag is true (i.e., 706 * to prevent blocking on the nameserver). localnet is the IP address 707 * of the local network. mask is its subnet mask. 708 */ 709void
|
700init_addrtoname(int fflag, u_int32_t localnet, u_int32_t mask)
| 710init_addrtoname(u_int32_t localnet, u_int32_t mask)
|
701{ 702 netmask = mask; 703 if (fflag) { 704 f_localnet = localnet; 705 f_netmask = mask; 706 } 707 if (nflag) 708 /* 709 * Simplest way to suppress names. 710 */ 711 return; 712 713 init_etherarray(); 714 init_servarray(); 715 init_eprotoarray(); 716 init_llcsaparray(); 717 init_protoidarray(); 718} 719 720char * 721dnaddr_string(u_short dnaddr) 722{ 723 register struct hnamemem *tp; 724 725 for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0; 726 tp = tp->nxt) 727 if (tp->addr == dnaddr) 728 return (tp->name); 729 730 tp->addr = dnaddr; 731 tp->nxt = newhnamemem(); 732 if (nflag) 733 tp->name = dnnum_string(dnaddr); 734 else 735 tp->name = dnname_string(dnaddr); 736 737 return(tp->name); 738} 739 740/* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */ 741struct hnamemem * 742newhnamemem(void) 743{ 744 register struct hnamemem *p; 745 static struct hnamemem *ptr = NULL; 746 static u_int num = 0; 747 748 if (num <= 0) { 749 num = 64; 750 ptr = (struct hnamemem *)calloc(num, sizeof (*ptr)); 751 if (ptr == NULL) 752 error("newhnamemem: calloc"); 753 } 754 --num; 755 p = ptr++; 756 return (p); 757}
| 711{ 712 netmask = mask; 713 if (fflag) { 714 f_localnet = localnet; 715 f_netmask = mask; 716 } 717 if (nflag) 718 /* 719 * Simplest way to suppress names. 720 */ 721 return; 722 723 init_etherarray(); 724 init_servarray(); 725 init_eprotoarray(); 726 init_llcsaparray(); 727 init_protoidarray(); 728} 729 730char * 731dnaddr_string(u_short dnaddr) 732{ 733 register struct hnamemem *tp; 734 735 for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0; 736 tp = tp->nxt) 737 if (tp->addr == dnaddr) 738 return (tp->name); 739 740 tp->addr = dnaddr; 741 tp->nxt = newhnamemem(); 742 if (nflag) 743 tp->name = dnnum_string(dnaddr); 744 else 745 tp->name = dnname_string(dnaddr); 746 747 return(tp->name); 748} 749 750/* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */ 751struct hnamemem * 752newhnamemem(void) 753{ 754 register struct hnamemem *p; 755 static struct hnamemem *ptr = NULL; 756 static u_int num = 0; 757 758 if (num <= 0) { 759 num = 64; 760 ptr = (struct hnamemem *)calloc(num, sizeof (*ptr)); 761 if (ptr == NULL) 762 error("newhnamemem: calloc"); 763 } 764 --num; 765 p = ptr++; 766 return (p); 767}
|