/*1* Copyright (c) 1990, 1993, 1994, 1995, 19962* The Regents of the University of California. All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that: (1) source code distributions6* retain the above copyright notice and this paragraph in its entirety, (2)7* distributions including binary code include the above copyright notice and8* this paragraph in its entirety in the documentation or other materials9* provided with the distribution, and (3) all advertising materials mentioning10* features or use of this software display the following acknowledgement:11* ``This product includes software developed by the University of California,12* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of13* the University nor the names of its contributors may be used to endorse14* or promote products derived from this software without specific prior15* written permission.16* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED17* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF18* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.19*/2021#include <config.h>2223#include <pcap-types.h>2425#include <memory.h>26#include <stdio.h>27#include <string.h>2829#include "pcap-int.h"3031#include <pcap/namedb.h>3233#include "thread-local.h"3435#ifdef HAVE_OS_PROTO_H36#include "os-proto.h"37#endif3839static inline int skip_space(FILE *);40static inline int skip_line(FILE *);4142/* Hex digit to integer. */43static inline u_char44xdtoi(u_char c)45{46if (c >= '0' && c <= '9')47return (u_char)(c - '0');48else if (c >= 'a' && c <= 'f')49return (u_char)(c - 'a' + 10);50else51return (u_char)(c - 'A' + 10);52}5354/*55* Skip linear white space (space and tab) and any CRs before LF.56* Stop when we hit a non-white-space character or an end-of-line LF.57*/58static inline int59skip_space(FILE *f)60{61int c;6263do {64c = getc(f);65} while (c == ' ' || c == '\t' || c == '\r');6667return c;68}6970static inline int71skip_line(FILE *f)72{73int c;7475do76c = getc(f);77while (c != '\n' && c != EOF);7879return c;80}8182struct pcap_etherent *83pcap_next_etherent(FILE *fp)84{85register int c, i;86u_char d;87char *bp;88size_t namesize;89static thread_local struct pcap_etherent e;9091memset((char *)&e, 0, sizeof(e));92for (;;) {93/* Find addr */94c = skip_space(fp);95if (c == EOF)96return (NULL);97if (c == '\n')98continue;99100/* If this is a comment, or first thing on line101cannot be Ethernet address, skip the line. */102if (!PCAP_ISXDIGIT(c)) {103c = skip_line(fp);104if (c == EOF)105return (NULL);106continue;107}108109/* must be the start of an address */110for (i = 0; i < 6; i += 1) {111d = xdtoi((u_char)c);112c = getc(fp);113if (c == EOF)114return (NULL);115if (PCAP_ISXDIGIT(c)) {116d <<= 4;117d |= xdtoi((u_char)c);118c = getc(fp);119if (c == EOF)120return (NULL);121}122e.addr[i] = d;123if (c != ':')124break;125c = getc(fp);126if (c == EOF)127return (NULL);128}129130/* Must be whitespace */131if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {132c = skip_line(fp);133if (c == EOF)134return (NULL);135continue;136}137c = skip_space(fp);138if (c == EOF)139return (NULL);140141/* hit end of line... */142if (c == '\n')143continue;144145if (c == '#') {146c = skip_line(fp);147if (c == EOF)148return (NULL);149continue;150}151152/* pick up name */153bp = e.name;154/* Use 'namesize' to prevent buffer overflow. */155namesize = sizeof(e.name) - 1;156do {157*bp++ = (u_char)c;158c = getc(fp);159if (c == EOF)160return (NULL);161} while (c != ' ' && c != '\t' && c != '\r' && c != '\n'162&& --namesize != 0);163*bp = '\0';164165/* Eat trailing junk */166if (c != '\n')167(void)skip_line(fp);168169return &e;170}171}172173174