etherent.c revision 190225
1145256Sjkoshy/*
2183266Sjkoshy * Copyright (c) 1990, 1993, 1994, 1995, 1996
3174395Sjkoshy *	The Regents of the University of California.  All rights reserved.
4145256Sjkoshy *
5145256Sjkoshy * Redistribution and use in source and binary forms, with or without
6174395Sjkoshy * modification, are permitted provided that: (1) source code distributions
7174395Sjkoshy * retain the above copyright notice and this paragraph in its entirety, (2)
8174395Sjkoshy * distributions including binary code include the above copyright notice and
9145256Sjkoshy * this paragraph in its entirety in the documentation or other materials
10145256Sjkoshy * provided with the distribution, and (3) all advertising materials mentioning
11145256Sjkoshy * features or use of this software display the following acknowledgement:
12145256Sjkoshy * ``This product includes software developed by the University of California,
13145256Sjkoshy * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14145256Sjkoshy * the University nor the names of its contributors may be used to endorse
15145256Sjkoshy * or promote products derived from this software without specific prior
16145256Sjkoshy * written permission.
17145256Sjkoshy * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18145256Sjkoshy * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19145256Sjkoshy * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20145256Sjkoshy */
21145256Sjkoshy
22145256Sjkoshy#ifndef lint
23145256Sjkoshystatic const char rcsid[] _U_ =
24145256Sjkoshy    "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.23 2006/10/04 18:09:22 guy Exp $ (LBL)";
25145256Sjkoshy#endif
26145256Sjkoshy
27145256Sjkoshy#ifdef HAVE_CONFIG_H
28145256Sjkoshy#include "config.h"
29145256Sjkoshy#endif
30145256Sjkoshy
31145256Sjkoshy#include <sys/types.h>
32145256Sjkoshy
33145256Sjkoshy#include <ctype.h>
34145256Sjkoshy#include <memory.h>
35196224Sjhb#include <stdio.h>
36145256Sjkoshy#include <string.h>
37145256Sjkoshy
38145338Smarcel#include "pcap-int.h"
39145256Sjkoshy
40145256Sjkoshy#include <pcap/namedb.h>
41145256Sjkoshy
42145256Sjkoshy#ifdef HAVE_OS_PROTO_H
43196224Sjhb#include "os-proto.h"
44196224Sjhb#endif
45174395Sjkoshy
46147191Sjkoshystatic inline int xdtoi(int);
47185341Sjkimstatic inline int skip_space(FILE *);
48145256Sjkoshystatic inline int skip_line(FILE *);
49147191Sjkoshy
50147191Sjkoshy/* Hex digit to integer. */
51145256Sjkoshystatic inline int
52145256Sjkoshyxdtoi(c)
53145256Sjkoshy	register int c;
54147191Sjkoshy{
55147191Sjkoshy	if (isdigit(c))
56147191Sjkoshy		return c - '0';
57147191Sjkoshy	else if (islower(c))
58147191Sjkoshy		return c - 'a' + 10;
59147191Sjkoshy	else
60147191Sjkoshy		return c - 'A' + 10;
61147191Sjkoshy}
62147191Sjkoshy
63147191Sjkoshystatic inline int
64147191Sjkoshyskip_space(f)
65147191Sjkoshy	FILE *f;
66147191Sjkoshy{
67147191Sjkoshy	int c;
68147191Sjkoshy
69147191Sjkoshy	do {
70145256Sjkoshy		c = getc(f);
71145256Sjkoshy	} while (isspace(c) && c != '\n');
72145256Sjkoshy
73145256Sjkoshy	return c;
74145256Sjkoshy}
75145256Sjkoshy
76145256Sjkoshystatic inline int
77145256Sjkoshyskip_line(f)
78145256Sjkoshy	FILE *f;
79145256Sjkoshy{
80145256Sjkoshy	int c;
81145256Sjkoshy
82145256Sjkoshy	do
83145256Sjkoshy		c = getc(f);
84145256Sjkoshy	while (c != '\n' && c != EOF);
85145256Sjkoshy
86145256Sjkoshy	return c;
87145256Sjkoshy}
88145256Sjkoshy
89145256Sjkoshystruct pcap_etherent *
90145256Sjkoshypcap_next_etherent(FILE *fp)
91145256Sjkoshy{
92145256Sjkoshy	register int c, d, i;
93145256Sjkoshy	char *bp;
94145256Sjkoshy	static struct pcap_etherent e;
95145256Sjkoshy
96145256Sjkoshy	memset((char *)&e, 0, sizeof(e));
97145256Sjkoshy	do {
98145256Sjkoshy		/* Find addr */
99145256Sjkoshy		c = skip_space(fp);
100145256Sjkoshy		if (c == '\n')
101145256Sjkoshy			continue;
102145256Sjkoshy
103145256Sjkoshy		/* If this is a comment, or first thing on line
104145256Sjkoshy		   cannot be etehrnet address, skip the line. */
105145256Sjkoshy		if (!isxdigit(c)) {
106145256Sjkoshy			c = skip_line(fp);
107145256Sjkoshy			continue;
108145256Sjkoshy		}
109145256Sjkoshy
110145256Sjkoshy		/* must be the start of an address */
111145256Sjkoshy		for (i = 0; i < 6; i += 1) {
112145256Sjkoshy			d = xdtoi(c);
113145256Sjkoshy			c = getc(fp);
114145256Sjkoshy			if (isxdigit(c)) {
115183717Sjkoshy				d <<= 4;
116183717Sjkoshy				d |= xdtoi(c);
117183717Sjkoshy				c = getc(fp);
118183717Sjkoshy			}
119183717Sjkoshy			e.addr[i] = d;
120145256Sjkoshy			if (c != ':')
121145256Sjkoshy				break;
122145256Sjkoshy			c = getc(fp);
123145256Sjkoshy		}
124145256Sjkoshy		if (c == EOF)
125145256Sjkoshy			break;
126145256Sjkoshy
127145256Sjkoshy		/* Must be whitespace */
128145256Sjkoshy		if (!isspace(c)) {
129183717Sjkoshy			c = skip_line(fp);
130183717Sjkoshy			continue;
131183717Sjkoshy		}
132183717Sjkoshy		c = skip_space(fp);
133183717Sjkoshy
134183717Sjkoshy		/* hit end of line... */
135183717Sjkoshy		if (c == '\n')
136183717Sjkoshy			continue;
137183717Sjkoshy
138183717Sjkoshy		if (c == '#') {
139183717Sjkoshy			c = skip_line(fp);
140183717Sjkoshy			continue;
141183717Sjkoshy		}
142183717Sjkoshy
143183717Sjkoshy		/* pick up name */
144183717Sjkoshy		bp = e.name;
145183717Sjkoshy		/* Use 'd' to prevent buffer overflow. */
146145256Sjkoshy		d = sizeof(e.name) - 1;
147145256Sjkoshy		do {
148145256Sjkoshy			*bp++ = c;
149145256Sjkoshy			c = getc(fp);
150145256Sjkoshy		} while (!isspace(c) && c != EOF && --d > 0);
151145256Sjkoshy		*bp = '\0';
152145256Sjkoshy
153145256Sjkoshy		/* Eat trailing junk */
154145256Sjkoshy		if (c != '\n')
155145256Sjkoshy			(void)skip_line(fp);
156145256Sjkoshy
157145256Sjkoshy		return &e;
158145256Sjkoshy
159145256Sjkoshy	} while (c != EOF);
160145256Sjkoshy
161145256Sjkoshy	return (NULL);
162145256Sjkoshy}
163145256Sjkoshy