1 /* 2 * Copyright (c) 1990, 1993, 1994, 1995, 1996 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22 #ifdef HAVE_CONFIG_H 23 #include <config.h> 24 #endif 25 26 #include <pcap-types.h> 27 28 #include <memory.h> 29 #include <stdio.h> 30 #include <string.h> 31 32 #include "pcap-int.h" 33 34 #include <pcap/namedb.h> 35 36 #ifdef HAVE_OS_PROTO_H 37 #include "os-proto.h" 38 #endif 39 40 static inline int skip_space(FILE *); 41 static inline int skip_line(FILE *); 42 43 /* Hex digit to integer. */ 44 static inline u_char 45 xdtoi(u_char c) 46 { 47 if (c >= '0' && c <= '9') 48 return (u_char)(c - '0'); 49 else if (c >= 'a' && c <= 'f') 50 return (u_char)(c - 'a' + 10); 51 else 52 return (u_char)(c - 'A' + 10); 53 } 54 55 /* 56 * Skip linear white space (space and tab) and any CRs before LF. 57 * Stop when we hit a non-white-space character or an end-of-line LF. 58 */ 59 static inline int 60 skip_space(FILE *f) 61 { 62 int c; 63 64 do { 65 c = getc(f); 66 } while (c == ' ' || c == '\t' || c == '\r'); 67 68 return c; 69 } 70 71 static inline int 72 skip_line(FILE *f) 73 { 74 int c; 75 76 do 77 c = getc(f); 78 while (c != '\n' && c != EOF); 79 80 return c; 81 } 82 83 struct pcap_etherent * 84 pcap_next_etherent(FILE *fp) 85 { 86 register int c, i; 87 u_char d; 88 char *bp; 89 size_t namesize; 90 static struct pcap_etherent e; 91 92 memset((char *)&e, 0, sizeof(e)); 93 for (;;) { 94 /* Find addr */ 95 c = skip_space(fp); 96 if (c == EOF) 97 return (NULL); 98 if (c == '\n') 99 continue; 100 101 /* If this is a comment, or first thing on line 102 cannot be Ethernet address, skip the line. */ 103 if (!PCAP_ISXDIGIT(c)) { 104 c = skip_line(fp); 105 if (c == EOF) 106 return (NULL); 107 continue; 108 } 109 110 /* must be the start of an address */ 111 for (i = 0; i < 6; i += 1) { 112 d = xdtoi((u_char)c); 113 c = getc(fp); 114 if (c == EOF) 115 return (NULL); 116 if (PCAP_ISXDIGIT(c)) { 117 d <<= 4; 118 d |= xdtoi((u_char)c); 119 c = getc(fp); 120 if (c == EOF) 121 return (NULL); 122 } 123 e.addr[i] = d; 124 if (c != ':') 125 break; 126 c = getc(fp); 127 if (c == EOF) 128 return (NULL); 129 } 130 131 /* Must be whitespace */ 132 if (c != ' ' && c != '\t' && c != '\r' && c != '\n') { 133 c = skip_line(fp); 134 if (c == EOF) 135 return (NULL); 136 continue; 137 } 138 c = skip_space(fp); 139 if (c == EOF) 140 return (NULL); 141 142 /* hit end of line... */ 143 if (c == '\n') 144 continue; 145 146 if (c == '#') { 147 c = skip_line(fp); 148 if (c == EOF) 149 return (NULL); 150 continue; 151 } 152 153 /* pick up name */ 154 bp = e.name; 155 /* Use 'namesize' to prevent buffer overflow. */ 156 namesize = sizeof(e.name) - 1; 157 do { 158 *bp++ = (u_char)c; 159 c = getc(fp); 160 if (c == EOF) 161 return (NULL); 162 } while (c != ' ' && c != '\t' && c != '\r' && c != '\n' 163 && --namesize != 0); 164 *bp = '\0'; 165 166 /* Eat trailing junk */ 167 if (c != '\n') 168 (void)skip_line(fp); 169 170 return &e; 171 } 172 } 173