etherent.c revision 17683
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
23static char rcsid[] =
24    "@(#) $Header: etherent.c,v 1.19 96/07/15 00:48:47 leres 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
43static inline int xdtoi(int);
44static inline int skip_space(FILE *);
45static inline int skip_line(FILE *);
46
47/* Hex digit to integer. */
48static inline int
49xdtoi(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
60static inline int
61skip_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
73static inline int
74skip_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
86struct pcap_etherent *
87pcap_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