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