etherent.c revision 214518
1266692Sgshapiro/*
2132943Sgshapiro * Copyright (c) 1990, 1993, 1994, 1995, 1996
3132943Sgshapiro *	The Regents of the University of California.  All rights reserved.
4132943Sgshapiro *
5132943Sgshapiro * Redistribution and use in source and binary forms, with or without
6132943Sgshapiro * modification, are permitted provided that: (1) source code distributions
7132943Sgshapiro * retain the above copyright notice and this paragraph in its entirety, (2)
8132943Sgshapiro * distributions including binary code include the above copyright notice and
9132943Sgshapiro * this paragraph in its entirety in the documentation or other materials
10132943Sgshapiro * provided with the distribution, and (3) all advertising materials mentioning
11132943Sgshapiro * features or use of this software display the following acknowledgement:
12173340Sgshapiro * ``This product includes software developed by the University of California,
13285303Sgshapiro * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14285303Sgshapiro * the University nor the names of its contributors may be used to endorse
15285303Sgshapiro * or promote products derived from this software without specific prior
16285303Sgshapiro * written permission.
17285303Sgshapiro * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18285303Sgshapiro * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19285303Sgshapiro * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20285303Sgshapiro */
21285303Sgshapiro
22285303Sgshapiro#ifndef lint
23285303Sgshapirostatic const char rcsid[] _U_ =
24285303Sgshapiro    "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.23 2006-10-04 18:09:22 guy Exp $ (LBL)";
25285303Sgshapiro#endif
26285303Sgshapiro
27285303Sgshapiro#ifdef HAVE_CONFIG_H
28285303Sgshapiro#include "config.h"
29285303Sgshapiro#endif
30285303Sgshapiro
31285303Sgshapiro#ifdef WIN32
32285303Sgshapiro#include <pcap-stdinc.h>
33285303Sgshapiro#else /* WIN32 */
34285303Sgshapiro#if HAVE_INTTYPES_H
35285303Sgshapiro#include <inttypes.h>
36285303Sgshapiro#elif HAVE_STDINT_H
37285303Sgshapiro#include <stdint.h>
38285303Sgshapiro#endif
39285303Sgshapiro#ifdef HAVE_SYS_BITYPES_H
40285303Sgshapiro#include <sys/bitypes.h>
41285303Sgshapiro#endif
42285303Sgshapiro#include <sys/types.h>
43285303Sgshapiro#endif /* WIN32 */
44285303Sgshapiro
45285303Sgshapiro#include <ctype.h>
46285303Sgshapiro#include <memory.h>
47285303Sgshapiro#include <stdio.h>
48285303Sgshapiro#include <string.h>
49285303Sgshapiro
50285303Sgshapiro#include "pcap-int.h"
51285303Sgshapiro
52285303Sgshapiro#include <pcap/namedb.h>
53285303Sgshapiro
54285303Sgshapiro#ifdef HAVE_OS_PROTO_H
55285303Sgshapiro#include "os-proto.h"
56285303Sgshapiro#endif
57285303Sgshapiro
58285303Sgshapirostatic inline int xdtoi(int);
59285303Sgshapirostatic inline int skip_space(FILE *);
60285303Sgshapirostatic inline int skip_line(FILE *);
61285303Sgshapiro
62285303Sgshapiro/* Hex digit to integer. */
63285303Sgshapirostatic inline int
64285303Sgshapiroxdtoi(c)
65285303Sgshapiro	register int c;
66285303Sgshapiro{
67285303Sgshapiro	if (isdigit(c))
68285303Sgshapiro		return c - '0';
69285303Sgshapiro	else if (islower(c))
70285303Sgshapiro		return c - 'a' + 10;
71285303Sgshapiro	else
72285303Sgshapiro		return c - 'A' + 10;
73285303Sgshapiro}
74285303Sgshapiro
75285303Sgshapirostatic inline int
76285303Sgshapiroskip_space(f)
77285303Sgshapiro	FILE *f;
78285303Sgshapiro{
79285303Sgshapiro	int c;
80285303Sgshapiro
81285303Sgshapiro	do {
82285303Sgshapiro		c = getc(f);
83285303Sgshapiro	} while (isspace(c) && c != '\n');
84285303Sgshapiro
85285303Sgshapiro	return c;
86285303Sgshapiro}
87285303Sgshapiro
88285303Sgshapirostatic inline int
89285303Sgshapiroskip_line(f)
90285303Sgshapiro	FILE *f;
91285303Sgshapiro{
92285303Sgshapiro	int c;
93285303Sgshapiro
94285303Sgshapiro	do
95285303Sgshapiro		c = getc(f);
96285303Sgshapiro	while (c != '\n' && c != EOF);
97285303Sgshapiro
98285303Sgshapiro	return c;
99285303Sgshapiro}
100285303Sgshapiro
101285303Sgshapirostruct pcap_etherent *
102285303Sgshapiropcap_next_etherent(FILE *fp)
103285303Sgshapiro{
104285303Sgshapiro	register int c, d, i;
105285303Sgshapiro	char *bp;
106285303Sgshapiro	static struct pcap_etherent e;
107285303Sgshapiro
108285303Sgshapiro	memset((char *)&e, 0, sizeof(e));
109249729Sgshapiro	do {
110249729Sgshapiro		/* Find addr */
111249729Sgshapiro		c = skip_space(fp);
112132943Sgshapiro		if (c == '\n')
113249729Sgshapiro			continue;
114249729Sgshapiro
115249729Sgshapiro		/* If this is a comment, or first thing on line
116132943Sgshapiro		   cannot be etehrnet address, skip the line. */
117132943Sgshapiro		if (!isxdigit(c)) {
118249729Sgshapiro			c = skip_line(fp);
119249729Sgshapiro			continue;
120249729Sgshapiro		}
121249729Sgshapiro
122249729Sgshapiro		/* must be the start of an address */
123249729Sgshapiro		for (i = 0; i < 6; i += 1) {
124249729Sgshapiro			d = xdtoi(c);
125249729Sgshapiro			c = getc(fp);
126249729Sgshapiro			if (isxdigit(c)) {
127249729Sgshapiro				d <<= 4;
128249729Sgshapiro				d |= xdtoi(c);
129249729Sgshapiro				c = getc(fp);
130249729Sgshapiro			}
131249729Sgshapiro			e.addr[i] = d;
132249729Sgshapiro			if (c != ':')
133249729Sgshapiro				break;
134249729Sgshapiro			c = getc(fp);
135249729Sgshapiro		}
136249729Sgshapiro		if (c == EOF)
137249729Sgshapiro			break;
138132943Sgshapiro
139132943Sgshapiro		/* Must be whitespace */
140132943Sgshapiro		if (!isspace(c)) {
141249729Sgshapiro			c = skip_line(fp);
142132943Sgshapiro			continue;
143249729Sgshapiro		}
144249729Sgshapiro		c = skip_space(fp);
145249729Sgshapiro
146132943Sgshapiro		/* hit end of line... */
147132943Sgshapiro		if (c == '\n')
148249729Sgshapiro			continue;
149132943Sgshapiro
150249729Sgshapiro		if (c == '#') {
151132943Sgshapiro			c = skip_line(fp);
152249729Sgshapiro			continue;
153249729Sgshapiro		}
154249729Sgshapiro
155249729Sgshapiro		/* pick up name */
156249729Sgshapiro		bp = e.name;
157249729Sgshapiro		/* Use 'd' to prevent buffer overflow. */
158249729Sgshapiro		d = sizeof(e.name) - 1;
159249729Sgshapiro		do {
160249729Sgshapiro			*bp++ = c;
161249729Sgshapiro			c = getc(fp);
162249729Sgshapiro		} while (!isspace(c) && c != EOF && --d > 0);
163249729Sgshapiro		*bp = '\0';
164249729Sgshapiro
165249729Sgshapiro		/* Eat trailing junk */
166249729Sgshapiro		if (c != '\n')
167249729Sgshapiro			(void)skip_line(fp);
168249729Sgshapiro
169132943Sgshapiro		return &e;
170249729Sgshapiro
171132943Sgshapiro	} while (c != EOF);
172132943Sgshapiro
173249729Sgshapiro	return (NULL);
174249729Sgshapiro}
175173340Sgshapiro