1 /* $OpenBSD: etherent.c,v 1.7 2004/01/27 06:58:03 tedu 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 <memory.h> 28 #include <stdio.h> 29 #include <string.h> 30 31 #include "pcap-int.h" 32 33 #include <pcap-namedb.h> 34 #ifdef HAVE_OS_PROTO_H 35 #include "os-proto.h" 36 #endif 37 38 static __inline int xdtoi(int); 39 static __inline int skip_space(FILE *); 40 static __inline int skip_line(FILE *); 41 42 /* Hex digit to integer. */ 43 static __inline int 44 xdtoi(c) 45 register int c; 46 { 47 if (isdigit(c)) 48 return c - '0'; 49 else if (islower(c)) 50 return c - 'a' + 10; 51 else 52 return c - 'A' + 10; 53 } 54 55 static __inline int 56 skip_space(f) 57 FILE *f; 58 { 59 int c; 60 61 do { 62 c = getc(f); 63 } while (isspace(c) && c != '\n'); 64 65 return c; 66 } 67 68 static __inline int 69 skip_line(f) 70 FILE *f; 71 { 72 int c; 73 74 do 75 c = getc(f); 76 while (c != '\n' && c != EOF); 77 78 return c; 79 } 80 81 struct pcap_etherent * 82 pcap_next_etherent(FILE *fp) 83 { 84 register int c, d, i; 85 char *bp; 86 static struct pcap_etherent e; 87 88 memset((char *)&e, 0, sizeof(e)); 89 do { 90 /* Find addr */ 91 c = skip_space(fp); 92 if (c == '\n') 93 continue; 94 95 /* If this is a comment, or first thing on line 96 cannot be etehrnet address, skip the line. */ 97 if (!isxdigit(c)) { 98 c = skip_line(fp); 99 continue; 100 } 101 102 /* must be the start of an address */ 103 for (i = 0; i < 6; i += 1) { 104 d = xdtoi(c); 105 c = getc(fp); 106 if (isxdigit(c)) { 107 d <<= 4; 108 d |= xdtoi(c); 109 c = getc(fp); 110 } 111 e.addr[i] = d; 112 if (c != ':') 113 break; 114 c = getc(fp); 115 } 116 if (c == EOF) 117 break; 118 119 /* Must be whitespace */ 120 if (!isspace(c)) { 121 c = skip_line(fp); 122 continue; 123 } 124 c = skip_space(fp); 125 126 /* hit end of line... */ 127 if (c == '\n') 128 continue; 129 130 if (c == '#') { 131 c = skip_line(fp); 132 continue; 133 } 134 135 /* pick up name */ 136 bp = e.name; 137 /* Use 'd' to prevent buffer overflow. */ 138 d = sizeof(e.name) - 1; 139 do { 140 *bp++ = c; 141 c = getc(fp); 142 } while (!isspace(c) && c != EOF && --d > 0); 143 *bp = '\0'; 144 145 /* Eat trailing junk */ 146 if (c != '\n') 147 (void)skip_line(fp); 148 149 return &e; 150 151 } while (c != EOF); 152 153 return (NULL); 154 } 155