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