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