117683Spst/*
217683Spst * Copyright (c) 1990, 1993, 1994, 1995, 1996
317683Spst *	The Regents of the University of California.  All rights reserved.
417683Spst *
517683Spst * Redistribution and use in source and binary forms, with or without
617683Spst * modification, are permitted provided that: (1) source code distributions
717683Spst * retain the above copyright notice and this paragraph in its entirety, (2)
817683Spst * distributions including binary code include the above copyright notice and
917683Spst * this paragraph in its entirety in the documentation or other materials
1017683Spst * provided with the distribution, and (3) all advertising materials mentioning
1117683Spst * features or use of this software display the following acknowledgement:
1217683Spst * ``This product includes software developed by the University of California,
1317683Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1417683Spst * the University nor the names of its contributors may be used to endorse
1517683Spst * or promote products derived from this software without specific prior
1617683Spst * written permission.
1717683Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1817683Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1917683Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2017683Spst */
2117683Spst
2217683Spst#ifndef lint
23127664Sbmsstatic const char rcsid[] _U_ =
24214518Srpaulo    "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.23 2006-10-04 18:09:22 guy Exp $ (LBL)";
2517683Spst#endif
2617683Spst
2775107Sfenner#ifdef HAVE_CONFIG_H
2875107Sfenner#include "config.h"
2975107Sfenner#endif
3075107Sfenner
31214518Srpaulo#ifdef WIN32
32214518Srpaulo#include <pcap-stdinc.h>
33214518Srpaulo#else /* WIN32 */
34214518Srpaulo#if HAVE_INTTYPES_H
35214518Srpaulo#include <inttypes.h>
36214518Srpaulo#elif HAVE_STDINT_H
37214518Srpaulo#include <stdint.h>
38214518Srpaulo#endif
39214518Srpaulo#ifdef HAVE_SYS_BITYPES_H
40214518Srpaulo#include <sys/bitypes.h>
41214518Srpaulo#endif
4217683Spst#include <sys/types.h>
43214518Srpaulo#endif /* WIN32 */
4417683Spst
4517683Spst#include <ctype.h>
4617683Spst#include <memory.h>
4717683Spst#include <stdio.h>
4817683Spst#include <string.h>
4917683Spst
5017683Spst#include "pcap-int.h"
5117683Spst
52190225Srpaulo#include <pcap/namedb.h>
5317683Spst
5417683Spst#ifdef HAVE_OS_PROTO_H
5517683Spst#include "os-proto.h"
5617683Spst#endif
5717683Spst
5817683Spststatic inline int xdtoi(int);
5917683Spststatic inline int skip_space(FILE *);
6017683Spststatic inline int skip_line(FILE *);
6117683Spst
6217683Spst/* Hex digit to integer. */
6317683Spststatic inline int
6417683Spstxdtoi(c)
6517683Spst	register int c;
6617683Spst{
6717683Spst	if (isdigit(c))
6817683Spst		return c - '0';
6917683Spst	else if (islower(c))
7017683Spst		return c - 'a' + 10;
7117683Spst	else
7217683Spst		return c - 'A' + 10;
7317683Spst}
7417683Spst
7517683Spststatic inline int
7617683Spstskip_space(f)
7717683Spst	FILE *f;
7817683Spst{
7917683Spst	int c;
8017683Spst
8117683Spst	do {
8217683Spst		c = getc(f);
8317683Spst	} while (isspace(c) && c != '\n');
8417683Spst
8517683Spst	return c;
8617683Spst}
8717683Spst
8817683Spststatic inline int
8917683Spstskip_line(f)
9017683Spst	FILE *f;
9117683Spst{
9217683Spst	int c;
9317683Spst
9417683Spst	do
9517683Spst		c = getc(f);
9617683Spst	while (c != '\n' && c != EOF);
9717683Spst
9817683Spst	return c;
9917683Spst}
10017683Spst
10117683Spststruct pcap_etherent *
10217683Spstpcap_next_etherent(FILE *fp)
10317683Spst{
10417683Spst	register int c, d, i;
10517683Spst	char *bp;
10617683Spst	static struct pcap_etherent e;
10717683Spst
10817683Spst	memset((char *)&e, 0, sizeof(e));
10917683Spst	do {
11017683Spst		/* Find addr */
11117683Spst		c = skip_space(fp);
11217683Spst		if (c == '\n')
11317683Spst			continue;
11417683Spst
11517683Spst		/* If this is a comment, or first thing on line
11617683Spst		   cannot be etehrnet address, skip the line. */
11717683Spst		if (!isxdigit(c)) {
11817683Spst			c = skip_line(fp);
11917683Spst			continue;
12017683Spst		}
12117683Spst
12217683Spst		/* must be the start of an address */
12317683Spst		for (i = 0; i < 6; i += 1) {
12417683Spst			d = xdtoi(c);
12517683Spst			c = getc(fp);
12617683Spst			if (isxdigit(c)) {
12717683Spst				d <<= 4;
12817683Spst				d |= xdtoi(c);
12917683Spst				c = getc(fp);
13017683Spst			}
13117683Spst			e.addr[i] = d;
13217683Spst			if (c != ':')
13317683Spst				break;
13417683Spst			c = getc(fp);
13517683Spst		}
13617683Spst		if (c == EOF)
13717683Spst			break;
13817683Spst
13917683Spst		/* Must be whitespace */
14017683Spst		if (!isspace(c)) {
14117683Spst			c = skip_line(fp);
14217683Spst			continue;
14317683Spst		}
14417683Spst		c = skip_space(fp);
14517683Spst
14617683Spst		/* hit end of line... */
14717683Spst		if (c == '\n')
14817683Spst			continue;
14917683Spst
15017683Spst		if (c == '#') {
15117683Spst			c = skip_line(fp);
15217683Spst			continue;
15317683Spst		}
15417683Spst
15517683Spst		/* pick up name */
15617683Spst		bp = e.name;
15717683Spst		/* Use 'd' to prevent buffer overflow. */
15817683Spst		d = sizeof(e.name) - 1;
15917683Spst		do {
16017683Spst			*bp++ = c;
16117683Spst			c = getc(fp);
16217683Spst		} while (!isspace(c) && c != EOF && --d > 0);
16317683Spst		*bp = '\0';
16417683Spst
16517683Spst		/* Eat trailing junk */
16617683Spst		if (c != '\n')
16717683Spst			(void)skip_line(fp);
16817683Spst
16917683Spst		return &e;
17017683Spst
17117683Spst	} while (c != EOF);
17217683Spst
17317683Spst	return (NULL);
17417683Spst}
175