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