Home | History | Annotate | Download | only in libpcap
      1 /*
      2  * Copyright (c) 1990, 1993, 1994, 1995, 1996
      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 
     22 #ifndef lint
     23 static const char rcsid[] _U_ =
     24     "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.22 2003/11/15 23:23:57 guy Exp $ (LBL)";
     25 #endif
     26 
     27 #ifdef HAVE_CONFIG_H
     28 #include "config.h"
     29 #endif
     30 
     31 #include <sys/types.h>
     32 
     33 #include <ctype.h>
     34 #include <memory.h>
     35 #include <stdio.h>
     36 #include <string.h>
     37 
     38 #include "pcap-int.h"
     39 
     40 #include <pcap-namedb.h>
     41 
     42 #ifdef HAVE_OS_PROTO_H
     43 #include "os-proto.h"
     44 #endif
     45 
     46 static inline int xdtoi(int);
     47 static inline int skip_space(FILE *);
     48 static inline int skip_line(FILE *);
     49 
     50 /* Hex digit to integer. */
     51 static inline int
     52 xdtoi(c)
     53 	register int c;
     54 {
     55 	if (isdigit(c))
     56 		return c - '0';
     57 	else if (islower(c))
     58 		return c - 'a' + 10;
     59 	else
     60 		return c - 'A' + 10;
     61 }
     62 
     63 static inline int
     64 skip_space(f)
     65 	FILE *f;
     66 {
     67 	int c;
     68 
     69 	do {
     70 		c = getc(f);
     71 	} while (isspace(c) && c != '\n');
     72 
     73 	return c;
     74 }
     75 
     76 static inline int
     77 skip_line(f)
     78 	FILE *f;
     79 {
     80 	int c;
     81 
     82 	do
     83 		c = getc(f);
     84 	while (c != '\n' && c != EOF);
     85 
     86 	return c;
     87 }
     88 
     89 struct pcap_etherent *
     90 pcap_next_etherent(FILE *fp)
     91 {
     92 	register int c, d, i;
     93 	char *bp;
     94 	static struct pcap_etherent e;
     95 
     96 	memset((char *)&e, 0, sizeof(e));
     97 	do {
     98 		/* Find addr */
     99 		c = skip_space(fp);
    100 		if (c == '\n')
    101 			continue;
    102 
    103 		/* If this is a comment, or first thing on line
    104 		   cannot be etehrnet address, skip the line. */
    105 		if (!isxdigit(c)) {
    106 			c = skip_line(fp);
    107 			continue;
    108 		}
    109 
    110 		/* must be the start of an address */
    111 		for (i = 0; i < 6; i += 1) {
    112 			d = xdtoi(c);
    113 			c = getc(fp);
    114 			if (isxdigit(c)) {
    115 				d <<= 4;
    116 				d |= xdtoi(c);
    117 				c = getc(fp);
    118 			}
    119 			e.addr[i] = d;
    120 			if (c != ':')
    121 				break;
    122 			c = getc(fp);
    123 		}
    124 		if (c == EOF)
    125 			break;
    126 
    127 		/* Must be whitespace */
    128 		if (!isspace(c)) {
    129 			c = skip_line(fp);
    130 			continue;
    131 		}
    132 		c = skip_space(fp);
    133 
    134 		/* hit end of line... */
    135 		if (c == '\n')
    136 			continue;
    137 
    138 		if (c == '#') {
    139 			c = skip_line(fp);
    140 			continue;
    141 		}
    142 
    143 		/* pick up name */
    144 		bp = e.name;
    145 		/* Use 'd' to prevent buffer overflow. */
    146 		d = sizeof(e.name) - 1;
    147 		do {
    148 			*bp++ = c;
    149 			c = getc(fp);
    150 		} while (!isspace(c) && c != EOF && --d > 0);
    151 		*bp = '\0';
    152 
    153 		/* Eat trailing junk */
    154 		if (c != '\n')
    155 			(void)skip_line(fp);
    156 
    157 		return &e;
    158 
    159 	} while (c != EOF);
    160 
    161 	return (NULL);
    162 }
    163