etherent.c revision 190225
110854Svaleriep/*
214434Svaleriep * Copyright (c) 1990, 1993, 1994, 1995, 1996
310854Svaleriep *	The Regents of the University of California.  All rights reserved.
410854Svaleriep *
510854Svaleriep * Redistribution and use in source and binary forms, with or without
610854Svaleriep * modification, are permitted provided that: (1) source code distributions
710854Svaleriep * retain the above copyright notice and this paragraph in its entirety, (2)
810854Svaleriep * distributions including binary code include the above copyright notice and
910854Svaleriep * this paragraph in its entirety in the documentation or other materials
1010854Svaleriep * provided with the distribution, and (3) all advertising materials mentioning
1110854Svaleriep * features or use of this software display the following acknowledgement:
1210854Svaleriep * ``This product includes software developed by the University of California,
1310854Svaleriep * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1410854Svaleriep * the University nor the names of its contributors may be used to endorse
1510854Svaleriep * or promote products derived from this software without specific prior
1610854Svaleriep * written permission.
1710854Svaleriep * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1810854Svaleriep * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1910854Svaleriep * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2010854Svaleriep */
2110854Svaleriep
2210854Svaleriep#ifndef lint
2310854Svaleriepstatic const char rcsid[] _U_ =
2410854Svaleriep    "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.23 2006/10/04 18:09:22 guy Exp $ (LBL)";
2510854Svaleriep#endif
2614434Svaleriep
2710854Svaleriep#ifdef HAVE_CONFIG_H
2811822Sdarcy#include "config.h"
2910854Svaleriep#endif
3010854Svaleriep
3110854Svaleriep#include <sys/types.h>
3210854Svaleriep
3310854Svaleriep#include <ctype.h>
3410854Svaleriep#include <memory.h>
3510854Svaleriep#include <stdio.h>
3610854Svaleriep#include <string.h>
3710854Svaleriep
3810854Svaleriep#include "pcap-int.h"
3910854Svaleriep
4010854Svaleriep#include <pcap/namedb.h>
4110854Svaleriep
4210854Svaleriep#ifdef HAVE_OS_PROTO_H
4314434Svaleriep#include "os-proto.h"
4410854Svaleriep#endif
4510854Svaleriep
4614434Svaleriepstatic inline int xdtoi(int);
4714434Svaleriepstatic inline int skip_space(FILE *);
4814434Svaleriepstatic inline int skip_line(FILE *);
4914434Svaleriep
5014434Svaleriep/* Hex digit to integer. */
5110854Svaleriepstatic inline int
5210854Svaleriepxdtoi(c)
5310854Svaleriep	register int c;
5410854Svaleriep{
5510854Svaleriep	if (isdigit(c))
5610854Svaleriep		return c - '0';
5714434Svaleriep	else if (islower(c))
5810854Svaleriep		return c - 'a' + 10;
5910854Svaleriep	else
6010854Svaleriep		return c - 'A' + 10;
6110854Svaleriep}
6210854Svaleriep
6314434Svaleriepstatic inline int
6414434Svaleriepskip_space(f)
6510854Svaleriep	FILE *f;
6614434Svaleriep{
6710854Svaleriep	int c;
6814434Svaleriep
6914434Svaleriep	do {
7014434Svaleriep		c = getc(f);
7114434Svaleriep	} while (isspace(c) && c != '\n');
7214434Svaleriep
7314434Svaleriep	return c;
7410854Svaleriep}
7514434Svaleriep
7614434Svaleriepstatic inline int
7714434Svaleriepskip_line(f)
7814434Svaleriep	FILE *f;
7910854Svaleriep{
8014434Svaleriep	int c;
8114434Svaleriep
8214434Svaleriep	do
8314434Svaleriep		c = getc(f);
8414434Svaleriep	while (c != '\n' && c != EOF);
8514434Svaleriep
8614434Svaleriep	return c;
8714434Svaleriep}
8814434Svaleriep
8914434Svaleriepstruct pcap_etherent *
9014434Svalerieppcap_next_etherent(FILE *fp)
9114434Svaleriep{
9214434Svaleriep	register int c, d, i;
9310854Svaleriep	char *bp;
9414434Svaleriep	static struct pcap_etherent e;
9514434Svaleriep
9614434Svaleriep	memset((char *)&e, 0, sizeof(e));
9710854Svaleriep	do {
9814434Svaleriep		/* Find addr */
9910854Svaleriep		c = skip_space(fp);
10010854Svaleriep		if (c == '\n')
10110854Svaleriep			continue;
10214434Svaleriep
10310854Svaleriep		/* If this is a comment, or first thing on line
10414434Svaleriep		   cannot be etehrnet address, skip the line. */
10514434Svaleriep		if (!isxdigit(c)) {
10610854Svaleriep			c = skip_line(fp);
10714434Svaleriep			continue;
10814434Svaleriep		}
10914434Svaleriep
11014434Svaleriep		/* must be the start of an address */
11114434Svaleriep		for (i = 0; i < 6; i += 1) {
11214434Svaleriep			d = xdtoi(c);
11314434Svaleriep			c = getc(fp);
11414434Svaleriep			if (isxdigit(c)) {
11514434Svaleriep				d <<= 4;
11614434Svaleriep				d |= xdtoi(c);
11714434Svaleriep				c = getc(fp);
11814434Svaleriep			}
11914434Svaleriep			e.addr[i] = d;
12014434Svaleriep			if (c != ':')
12110854Svaleriep				break;
12214434Svaleriep			c = getc(fp);
12314434Svaleriep		}
12414434Svaleriep		if (c == EOF)
12514434Svaleriep			break;
12614434Svaleriep
12714434Svaleriep		/* Must be whitespace */
12814434Svaleriep		if (!isspace(c)) {
12914434Svaleriep			c = skip_line(fp);
13014434Svaleriep			continue;
13114434Svaleriep		}
13214434Svaleriep		c = skip_space(fp);
13314434Svaleriep
13414434Svaleriep		/* hit end of line... */
13514434Svaleriep		if (c == '\n')
13614434Svaleriep			continue;
13714434Svaleriep
13814434Svaleriep		if (c == '#') {
13914434Svaleriep			c = skip_line(fp);
14014434Svaleriep			continue;
14114434Svaleriep		}
14214434Svaleriep
14310854Svaleriep		/* pick up name */
14410854Svaleriep		bp = e.name;
14510854Svaleriep		/* Use 'd' to prevent buffer overflow. */
14610854Svaleriep		d = sizeof(e.name) - 1;
14710854Svaleriep		do {
14810854Svaleriep			*bp++ = c;
14910854Svaleriep			c = getc(fp);
15010854Svaleriep		} while (!isspace(c) && c != EOF && --d > 0);
15110854Svaleriep		*bp = '\0';
152
153		/* Eat trailing junk */
154		if (c != '\n')
155			(void)skip_line(fp);
156
157		return &e;
158
159	} while (c != EOF);
160
161	return (NULL);
162}
163