133965Sjdp/* 2218822Sdim * Copyright (c) 1990, 1993, 1994, 1995, 1996 3218822Sdim * The Regents of the University of California. All rights reserved. 433965Sjdp * 5218822Sdim * Redistribution and use in source and binary forms, with or without 633965Sjdp * modification, are permitted provided that: (1) source code distributions 7218822Sdim * retain the above copyright notice and this paragraph in its entirety, (2) 8218822Sdim * distributions including binary code include the above copyright notice and 9218822Sdim * this paragraph in its entirety in the documentation or other materials 10218822Sdim * provided with the distribution, and (3) all advertising materials mentioning 1133965Sjdp * features or use of this software display the following acknowledgement: 12218822Sdim * ``This product includes software developed by the University of California, 13218822Sdim * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14218822Sdim * the University nor the names of its contributors may be used to endorse 15218822Sdim * or promote products derived from this software without specific prior 1633965Sjdp * written permission. 17218822Sdim * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18218822Sdim * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19218822Sdim * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20218822Sdim */ 2133965Sjdp 2277298Sobrien#ifdef HAVE_CONFIG_H 2338889Sjdp#include <config.h> 2438889Sjdp#endif 2538889Sjdp 2638889Sjdp#include <pcap-types.h> 2777298Sobrien 2833965Sjdp#include <ctype.h> 2933965Sjdp#include <memory.h> 3033965Sjdp#include <stdio.h> 3133965Sjdp#include <string.h> 3233965Sjdp 3377298Sobrien#include "pcap-int.h" 34218822Sdim 3533965Sjdp#include <pcap/namedb.h> 3633965Sjdp 3733965Sjdp#ifdef HAVE_OS_PROTO_H 3877298Sobrien#include "os-proto.h" 3933965Sjdp#endif 4033965Sjdp 4133965Sjdpstatic inline int skip_space(FILE *); 4233965Sjdpstatic inline int skip_line(FILE *); 4333965Sjdp 4477298Sobrien/* Hex digit to integer. */ 4533965Sjdpstatic inline u_char 4633965Sjdpxdtoi(u_char c) 4733965Sjdp{ 48218822Sdim if (isdigit(c)) 4933965Sjdp return (u_char)(c - '0'); 5033965Sjdp else if (islower(c)) 5133965Sjdp return (u_char)(c - 'a' + 10); 5233965Sjdp else 53218822Sdim return (u_char)(c - 'A' + 10); 5433965Sjdp} 5533965Sjdp 5633965Sjdpstatic inline int 5733965Sjdpskip_space(FILE *f) 5833965Sjdp{ 5933965Sjdp int c; 6033965Sjdp 6133965Sjdp do { 6233965Sjdp c = getc(f); 6333965Sjdp } while (isspace(c) && c != '\n'); 6433965Sjdp 6533965Sjdp return c; 66218822Sdim} 67218822Sdim 68218822Sdimstatic inline int 6933965Sjdpskip_line(FILE *f) 7033965Sjdp{ 7133965Sjdp int c; 7233965Sjdp 7333965Sjdp do 7433965Sjdp c = getc(f); 7533965Sjdp while (c != '\n' && c != EOF); 7633965Sjdp 77130561Sobrien return c; 78218822Sdim} 7933965Sjdp 8033965Sjdpstruct pcap_etherent * 8133965Sjdppcap_next_etherent(FILE *fp) 8233965Sjdp{ 8333965Sjdp register int c, i; 8433965Sjdp u_char d; 8533965Sjdp char *bp; 8633965Sjdp size_t namesize; 8733965Sjdp static struct pcap_etherent e; 8833965Sjdp 8933965Sjdp memset((char *)&e, 0, sizeof(e)); 9033965Sjdp for (;;) { 91218822Sdim /* Find addr */ 9233965Sjdp c = skip_space(fp); 9333965Sjdp if (c == EOF) 9433965Sjdp return (NULL); 9533965Sjdp if (c == '\n') 9633965Sjdp continue; 97218822Sdim 98218822Sdim /* If this is a comment, or first thing on line 99218822Sdim cannot be Ethernet address, skip the line. */ 100218822Sdim if (!isxdigit(c)) { 101218822Sdim c = skip_line(fp); 102218822Sdim if (c == EOF) 103218822Sdim return (NULL); 104218822Sdim continue; 105218822Sdim } 10633965Sjdp 10733965Sjdp /* must be the start of an address */ 10833965Sjdp for (i = 0; i < 6; i += 1) { 10933965Sjdp d = xdtoi((u_char)c); 11033965Sjdp c = getc(fp); 11133965Sjdp if (c == EOF) 11233965Sjdp return (NULL); 11333965Sjdp if (isxdigit(c)) { 11433965Sjdp d <<= 4; 11533965Sjdp d |= xdtoi((u_char)c); 116218822Sdim c = getc(fp); 11733965Sjdp if (c == EOF) 118130561Sobrien return (NULL); 11933965Sjdp } 120 e.addr[i] = d; 121 if (c != ':') 122 break; 123 c = getc(fp); 124 if (c == EOF) 125 return (NULL); 126 } 127 128 /* Must be whitespace */ 129 if (!isspace(c)) { 130 c = skip_line(fp); 131 if (c == EOF) 132 return (NULL); 133 continue; 134 } 135 c = skip_space(fp); 136 if (c == EOF) 137 return (NULL); 138 139 /* hit end of line... */ 140 if (c == '\n') 141 continue; 142 143 if (c == '#') { 144 c = skip_line(fp); 145 if (c == EOF) 146 return (NULL); 147 continue; 148 } 149 150 /* pick up name */ 151 bp = e.name; 152 /* Use 'namesize' to prevent buffer overflow. */ 153 namesize = sizeof(e.name) - 1; 154 do { 155 *bp++ = (u_char)c; 156 c = getc(fp); 157 if (c == EOF) 158 return (NULL); 159 } while (!isspace(c) && --namesize != 0); 160 *bp = '\0'; 161 162 /* Eat trailing junk */ 163 if (c != '\n') 164 (void)skip_line(fp); 165 166 return &e; 167 } 168} 169