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