build: check for fopencookie() in configure
[netsniff-ng-new.git] / lookup.c
blobeb5a45fdb025f11d77500e3190122ab053df2d1f
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Copyright 2014, 2015 Tobias Klauser
5 * Subject to the GPL, version 2.
6 */
8 #include <errno.h>
9 #include <stdbool.h>
10 #include <stdio.h>
11 #include <string.h>
13 #include "hash.h"
14 #include "str.h"
15 #include "lookup.h"
16 #include "xmalloc.h"
18 static bool lookup_initialized[LT_MAX];
19 static struct hash_table lookup_tables[LT_MAX];
20 static const char * const lookup_files[] = {
21 [LT_PORTS_UDP] = ETCDIRE_STRING "/udp.conf",
22 [LT_PORTS_TCP] = ETCDIRE_STRING "/tcp.conf",
23 [LT_ETHERTYPES] = ETCDIRE_STRING "/ether.conf",
24 [LT_OUI] = ETCDIRE_STRING "/oui.conf",
27 struct lookup_entry {
28 unsigned int id;
29 char *str;
30 struct lookup_entry *next;
33 void lookup_init(enum lookup_type which)
35 FILE *fp;
36 char buff[128], *ptr, *end;
37 const char *file;
38 struct hash_table *table;
39 struct lookup_entry *p;
40 void **pos;
42 bug_on(which >= LT_MAX);
43 if (lookup_initialized[which])
44 return;
45 table = &lookup_tables[which];
46 file = lookup_files[which];
48 fp = fopen(file, "r");
49 if (!fp) {
50 fprintf(stderr, "Cannot open %s: %s."
51 "Port name resolution won't be available.\n",
52 file, strerror(errno));
53 return;
56 memset(buff, 0, sizeof(buff));
58 while (fgets(buff, sizeof(buff), fp) != NULL) {
59 buff[sizeof(buff) - 1] = 0;
60 ptr = buff;
62 p = xmalloc(sizeof(*p));
63 p->id = strtol(ptr, &end, 0);
64 /* not a valid line, skip */
65 if (p->id == 0 && end == ptr) {
66 xfree(p);
67 continue;
70 ptr = strstr(buff, ", ");
71 /* likewise */
72 if (!ptr) {
73 xfree(p);
74 continue;
77 ptr += strlen(", ");
78 ptr = strtrim_right(ptr, '\n');
79 ptr = strtrim_right(ptr, ' ');
81 p->str = xstrdup(ptr);
82 p->next = NULL;
84 pos = insert_hash(p->id, p, table);
85 if (pos) {
86 p->next = *pos;
87 *pos = p;
90 memset(buff, 0, sizeof(buff));
93 fclose(fp);
94 lookup_initialized[which] = true;
97 static int __lookup_cleanup_single(void *ptr)
99 struct lookup_entry *tmp, *p = ptr;
101 if (!ptr)
102 return 0;
104 while ((tmp = p->next)) {
105 xfree(p->str);
106 xfree(p);
107 p = tmp;
110 xfree(p->str);
111 xfree(p);
113 return 0;
116 void lookup_cleanup(enum lookup_type which)
118 struct hash_table *table;
120 bug_on(which >= LT_MAX);
121 if (!lookup_initialized[which])
122 return;
123 table = &lookup_tables[which];
125 for_each_hash(table, __lookup_cleanup_single);
126 free_hash(table);
127 lookup_initialized[which] = false;
130 static inline const char *__lookup_inline(unsigned int id, struct hash_table *tbl)
132 struct lookup_entry *entry = lookup_hash(id, tbl);
134 while (entry && id != entry->id)
135 entry = entry->next;
137 return (entry && id == entry->id ? entry->str : NULL);
140 const char *lookup_ether_type(unsigned int id)
142 return __lookup_inline(id, &lookup_tables[LT_ETHERTYPES]);
145 const char *lookup_port_udp(unsigned int id)
147 return __lookup_inline(id, &lookup_tables[LT_PORTS_UDP]);
150 const char *lookup_port_tcp(unsigned int id)
152 return __lookup_inline(id, &lookup_tables[LT_PORTS_TCP]);
155 const char *lookup_vendor(unsigned int id)
157 return __lookup_inline(id, &lookup_tables[LT_OUI]);