~ubuntu-branches/ubuntu/natty/ntop/natty

« back to all changes in this revision

Viewing changes to vendor.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2005-01-30 21:59:13 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20050130215913-xc3ke963bw49b3k4
Tags: 2:3.0-5
* Updated README.Debian file so users will understand what to do at
  install, closes: #291794, #287802.
* Updated ntop init script to give better output.
* Also changed log directory from /var/lib/ntop to /var/log/ntop,
  closes: #252352.
* Quoted the interface list to allow whitespace, closes: #267248.
* Added a couple of logcheck ignores, closes: #269321, #269319.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 1998-2004 Luca Deri <deri@ntop.org>
 
3
 *
 
4
 *                          http://www.ntop.org/
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, write to the Free Software
 
18
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
19
 */
 
20
 
 
21
/*
 
22
 * NOTE: About the tables in this program and vendortable.h...
 
23
 *
 
24
 *   IPX SAP
 
25
 *       The official list is maintained by iana at
 
26
 *             http://www.iana.org/assignments/novell-sap-numbers
 
27
 *
 
28
 *       While there is Makefile code to download and rebuild the structure (make dnsapt sapt),
 
29
 *       as of 01-2003, it doesn't work.
 
30
 *
 
31
 *       The file format has been changed, the sapt.sed file is lost, and besides it builds a
 
32
 *       saptable.h file which you would manually have to insert into vendor.c.
 
33
 *
 
34
 *       OTOP, Novell doesn't change things very often.
 
35
 *
 
36
 *   Vendor
 
37
 *       The official list is updated daily at http://standards.ieee.org/regauth/oui/oui.txt
 
38
 *       The vendor table data does change, frequently, albeit irrelevantly to most of us.
 
39
 *       The ntop version of oui.txt is updated infrequently.
 
40
 *
 
41
 *       To update (if say, you're seeing a lot of unknown values), download the list:
 
42
 *
 
43
 *           $ make dnvt
 
44
 *
 
45
 *       Warning: the mac address list frequently discussed on the 'net at
 
46
 *       http://www.cavebear.com/CaveBear/Ethernet/vendor.html hasn't been
 
47
 *       updated since 1999.
 
48
 *
 
49
 *       If you want to save (disk) space, an oui.txt customized with only the ones
 
50
 *       you really need is certainly possible.
 
51
 *
 
52
 *   Special MAC
 
53
 *       The special mac table is referenced - lookupHost() in hash.c calls
 
54
 *       getSpecialMacInfo() in util.c - each time a new (pseudo) local host
 
55
 *       is found.
 
56
 *
 
57
 *       I (Burton) am unaware of any official or even pseudo-offical list.
 
58
 *
 
59
 *       A 'special' MAC is one that's assigned (often in an RFC, IEEE standard,
 
60
 *       by consensus or in some other unusual way).  It doesn't represent a PHYSICAL
 
61
 *       device or manufacturer.
 
62
 *
 
63
 *       It's a mess...
 
64
 *
 
65
 *       For example, 0x0180C2-000000 through -00000f, are reserved in
 
66
 *       "ANSI/IEEE Standard 802.1D (1998 edition)".  See page 70 in
 
67
 *       http://standards.ieee.org/getieee802/download/802.1D-1998.pdf
 
68
 *
 
69
 *       For example, the 2nd bit of a MAC address denotes an LAA, a Locally Assigned
 
70
 *       Address value.  See IEEE 802.3-2002 (or earlier versions).
 
71
 *       Because bits are xmitted low to high , this stream, 0100000000000000...
 
72
 *       is MAC address 0x02000000.  (See RFC 1638)
 
73
 *
 
74
 *       These don't represent a manufacturer, but are values arbitrarily
 
75
 *       set by some network admin...
 
76
 *
 
77
 *       Also, see http://www.iana.org/assignments/ppp-numbers for CF0000xxxxxx
 
78
 */
 
79
 
 
80
/*
 
81
 * NOTE: About optimzing hash size...
 
82
 *
 
83
 *   See the #define TEST_HASHSIZE_xxxxxx's below.
 
84
 *
 
85
 *   Enabling it may run for a bit, as it tests each possible odd value from
 
86
 *   some low number up to whatever the MAX_ value is in globals-defines.h.
 
87
 *   (Testing will stop if a zero collision value is found).
 
88
 *
 
89
 *   Testing will produce a running list, showing the best so far.
 
90
 *
 
91
 *       TEST_HASHSIZE: Testing specialMacHash...wait
 
92
 *       TEST_HASHSIZE: specialMacHash  51  16
 
93
 *       TEST_HASHSIZE: specialMacHash  53  13
 
94
 *       TEST_HASHSIZE: specialMacHash  55  11
 
95
 *       TEST_HASHSIZE: specialMacHash  65   8
 
96
 *       TEST_HASHSIZE: specialMacHash  79   5
 
97
 *       TEST_HASHSIZE: specialMacHash 125   3
 
98
 *       TEST_HASHSIZE: specialMacHash 133   2
 
99
 *       TEST_HASHSIZE: specialMacHash 141   1
 
100
 *       TEST_HASHSIZE: specialMacHash BEST is 0 collisions, size 167
 
101
 *
 
102
 *   The ipxsap table is referenced only for reporting - so a few collisions
 
103
 *   isn't a huge deal.
 
104
 */
 
105
 
 
106
typedef struct {
 
107
  unsigned long ipxsapId;
 
108
  char* ipxsapName;
 
109
} IPXSAPInfo;
 
110
 
 
111
#include "ntop.h"
 
112
 
 
113
static char* macInputFiles[] = {
 
114
  "specialMAC.txt",
 
115
  "oui.txt",
 
116
  NULL
 
117
};
 
118
 
 
119
static IPXSAPInfo ipxSAP[] = {
 
120
  { 0x0000,     "Unknown" },
 
121
  { 0x0001,     "User" },
 
122
  { 0x0002,     "User Group" },
 
123
  { 0x0003,     "Print Queue" },
 
124
  { 0x0004,     "File server" },
 
125
  { 0x0005,     "Job server" },
 
126
  { 0x0007,     "Print server" },
 
127
  { 0x0008,     "Archive server" },
 
128
  { 0x0009,     "Archive server" },
 
129
  { 0x000a,     "Job queue" },
 
130
  { 0x000b,     "Administration" },
 
131
  { 0x0021,     "NAS SNA gateway" },
 
132
  { 0x0024,     "Remote bridge" },
 
133
  { 0x0026,     "Bridge server" },
 
134
  { 0x0027,     "TCP/IP gateway" },
 
135
  { 0x002d,     "Time Synchronization VAP" },
 
136
  { 0x002e,     "Archive Server Dynamic SAP" },
 
137
  { 0x0047,     "Advertising print server" },
 
138
  { 0x004b,     "Btrieve VAP 5.0" },
 
139
  { 0x004c,     "SQL VAP" },
 
140
  { 0x0050,     "Btrieve VAP" },
 
141
  { 0x0053,     "Print Queue VAP" },
 
142
  { 0x007a,     "TES NetWare for VMS" },
 
143
  { 0x0098,     "NetWare access server" },
 
144
  { 0x009a,     "Named Pipes server" },
 
145
  { 0x009e,     "Portable NetWare Unix" },
 
146
  { 0x0107,     "NetWare 386" },
 
147
  { 0x0111,     "Test server" },
 
148
  { 0x0133,     "NetWare Name Service" },
 
149
  { 0x0166,     "NetWare management" },
 
150
  { 0x023f,     "SMS Testing and Development" },
 
151
  { 0x026a,     "NetWare management" },
 
152
  { 0x026b,     "Time synchronization" },
 
153
  { 0x027b,     "NetWare Management Agent" },
 
154
  { 0x0278,     "NetWare Directory server" },
 
155
  { 0x030c,     "HP LaserJet / Quick Silver" },
 
156
  { 0x0355,     "Arcada Software" },
 
157
  { 0x0361,     "NETINELO" },
 
158
  { 0x037e,     "Powerchute UPS Monitoring" },
 
159
  { 0x03e1,     "UnixWare Application Server" },
 
160
  { 0x044c,     "Archive" },
 
161
  { 0x055d,     "Attachmate SNA gateway" },
 
162
  { 0x0610,     "Adaptec SCSI Management" },
 
163
  { 0x0640,     "NT Server-RPC/GW for NW/Win95 User Level Sec" },
 
164
  { 0x064e,     "NT Server-IIS" },
 
165
  { 0x0810,     "ELAN License Server Demo" },
 
166
  { 0x8002,     "Intel NetPort Print Server" },
 
167
  { 0x0000,     NULL }
 
168
};
 
169
 
 
170
IPXSAPInfo* ipxSAPhash[MAX_IPXSAP_NAME_HASH];
 
171
 
 
172
 
 
173
 
 
174
/* *********************************** */
 
175
 
 
176
static int addIPXSAPTableEntry(IPXSAPInfo* theMacHash[],
 
177
                               IPXSAPInfo* entry,
 
178
                               u_int tableLen) {
 
179
  u_int idx;
 
180
  unsigned long ipxsapValue;
 
181
  int hashLoadCollisions=0;
 
182
 
 
183
#ifdef PARM_USE_MACHASH_INVERT
 
184
  ipxsapValue = 256*256*(unsigned long)(entry->ipxsapId & 0xff)
 
185
    + 256*(unsigned long)((entry->ipxsapId >> 8) & 0xff)
 
186
    + (unsigned long)((entry->ipxsapId >> 16) & 0xff);
 
187
#else
 
188
  idx = (u_int)(entry->ipxsapId % tableLen);
 
189
#endif
 
190
  idx = (u_int)((u_int)ipxsapValue % tableLen);
 
191
 
 
192
#ifdef DEBUG
 
193
  traceEvent(CONST_TRACE_INFO, "DEBUG: addIPXSAPTableEntry(%06x, %s) gives %ld (mod %d = %d)",
 
194
         entry->ipxsapId,
 
195
         entry->ipxsapName,
 
196
         ipxsapValue,
 
197
         tableLen,
 
198
         idx);
 
199
#endif
 
200
 
 
201
  /* Count # of collisions during load - only ONCE per item */
 
202
  if(theMacHash[idx] != NULL) {
 
203
      hashLoadCollisions++;
 
204
#ifdef DEBUG
 
205
      traceEvent(CONST_TRACE_INFO, "DEBUG: HashLoad Collision - %d %x '%s",
 
206
                                   idx, entry->ipxsapId, entry->ipxsapName);
 
207
#endif
 
208
  }
 
209
 
 
210
  for(;;) {
 
211
    if(theMacHash[idx] == NULL) {
 
212
      theMacHash[idx] = entry;
 
213
      break;
 
214
    }
 
215
    idx = (idx+1)%tableLen;
 
216
  }
 
217
 
 
218
  return hashLoadCollisions;
 
219
}
 
220
 
 
221
/* *********************************** */
 
222
 
 
223
char* getSAPInfo(u_int16_t sapInfo, short encodeString) {
 
224
  u_int idx;
 
225
  unsigned long ipxsapValue = (unsigned long)sapInfo;
 
226
  IPXSAPInfo* cursor;
 
227
 
 
228
  idx = (u_int)((u_int)sapInfo % MAX_IPXSAP_NAME_HASH);
 
229
 
 
230
  for(;;) {
 
231
    cursor = ipxSAPhash[idx];
 
232
 
 
233
    if(ipxSAPhash[idx] == NULL) {
 
234
      /* Unknown vendor */
 
235
      return("");
 
236
    } else if(ipxSAPhash[idx] != NULL) {
 
237
      if(ipxSAPhash[idx]->ipxsapId == ipxsapValue) {
 
238
        if(encodeString) {
 
239
          static char ipxsapName[256];
 
240
          int a, b;
 
241
 
 
242
          for(a=0, b=0; ipxSAPhash[idx]->ipxsapName[a] != '\0'; a++)
 
243
            if(ipxSAPhash[idx]->ipxsapName[a] == ' ') {
 
244
              ipxsapName[b++] = '&';
 
245
              ipxsapName[b++] = 'n';
 
246
              ipxsapName[b++] = 'b';
 
247
              ipxsapName[b++] = 's';
 
248
              ipxsapName[b++] = 'p';
 
249
              ipxsapName[b++] = ';';
 
250
            } else
 
251
              ipxsapName[b++] = ipxSAPhash[idx]->ipxsapName[a];
 
252
 
 
253
          ipxsapName[b] = '\0';
 
254
          return(ipxsapName);
 
255
        } else
 
256
          return(ipxSAPhash[idx]->ipxsapName);
 
257
      }
 
258
    }
 
259
 
 
260
    idx = (idx+1)%MAX_IPXSAP_NAME_HASH;
 
261
  }
 
262
 
 
263
  return(""); /* NOTREACHED */
 
264
}
 
265
 
 
266
/* *********************************** */
 
267
 
 
268
static char* getMACInfo(int special, u_char* ethAddress, short encodeString) {
 
269
  datum key_data, data_data;
 
270
  static char tmpBuf[96];
 
271
  char *workBuf;
 
272
  char etherbuf[LEN_ETHERNET_ADDRESS_DISPLAY];
 
273
 
 
274
  workBuf = etheraddr_string(ethAddress, etherbuf);
 
275
  memcpy(&tmpBuf, workBuf, LEN_ETHERNET_ADDRESS_DISPLAY+1);
 
276
#ifdef VENDOR_DEBUG
 
277
  traceEvent(CONST_TRACE_INFO, "VENDOR_DEBUG: %slookup '%s'",
 
278
                               special == 1 ? "special " : "", tmpBuf);
 
279
#endif
 
280
 
 
281
  if(special == TRUE) {
 
282
 
 
283
      /* Search the database for the specified MAC address - full 48 bit */
 
284
 
 
285
      key_data.dptr = tmpBuf;
 
286
      key_data.dsize = strlen(tmpBuf)+1;
 
287
 
 
288
#ifdef VENDOR_DEBUG
 
289
      traceEvent(CONST_TRACE_INFO, "VENDOR_DEBUG: Fetching 48bit '%s'", tmpBuf);
 
290
#endif
 
291
 
 
292
      data_data = gdbm_fetch(myGlobals.macPrefixFile, key_data);
 
293
      
 
294
      if(data_data.dptr == NULL) {
 
295
        /* Maybe this is just the initial MAC (e.g 00:11:22) */
 
296
        if(key_data.dsize > 8) {
 
297
          key_data.dptr[8] = '\0';
 
298
          key_data.dsize   = 9;
 
299
        }
 
300
      }
 
301
 
 
302
      if((data_data.dptr != NULL) && (((MACInfo*)data_data.dptr)->isSpecial = 's')) {
 
303
        strncpy(tmpBuf, ((MACInfo*)data_data.dptr)->vendorName, sizeof(tmpBuf));
 
304
        free(data_data.dptr);
 
305
        myGlobals.numVendorLookupFound48bit++;
 
306
        return(tmpBuf);
 
307
      }
 
308
  }
 
309
 
 
310
  /* Try the 24 bit */
 
311
 
 
312
  tmpBuf[LEN_ETHERNET_VENDOR_DISPLAY-1] = '\0';   /* Mask off left 24 bits */
 
313
  key_data.dptr = tmpBuf;
 
314
  key_data.dsize = strlen(tmpBuf)+1;
 
315
 
 
316
#ifdef VENDOR_DEBUG
 
317
  traceEvent(CONST_TRACE_INFO, "VENDOR_DEBUG: Fetching 24bit '%s'", tmpBuf);
 
318
#endif
 
319
 
 
320
  data_data = gdbm_fetch(myGlobals.macPrefixFile, key_data);
 
321
 
 
322
  if(data_data.dptr != NULL) {
 
323
    if(((special == TRUE)  && (((MACInfo*)data_data.dptr)->isSpecial = 's')) ||
 
324
       ((special == FALSE) && (((MACInfo*)data_data.dptr)->isSpecial != 's'))) {
 
325
      strncpy(tmpBuf, ((MACInfo*)data_data.dptr)->vendorName, sizeof(tmpBuf));
 
326
      free(data_data.dptr);
 
327
      myGlobals.numVendorLookupFound24bit++;
 
328
      return(tmpBuf);
 
329
    }
 
330
  }
 
331
 
 
332
 
 
333
  /* Hand coded for LAA/Multicast */
 
334
  if(((ethAddress[5] & 0x01) == 0) && ((ethAddress[6] & 0x01) == 0)) {
 
335
    /*
 
336
      This is a dummy MAC that instead contains an IP addresses
 
337
      in the first four bytes
 
338
 
 
339
      Example: 0D:68:2B:C1:00:00
 
340
    */
 
341
    return("");
 
342
  }
 
343
 
 
344
 /* Hand coded for LAA/Multicast */
 
345
  if((ethAddress[0] & 0x01) != 0) {
 
346
    myGlobals.numVendorLookupFoundMulticast++;
 
347
    return("Multicast");
 
348
  }
 
349
 
 
350
  if((ethAddress[0] & 0x02) != 0) {
 
351
    myGlobals.numVendorLookupFoundLAA++;
 
352
    return("LAA (Locally assigned address)");
 
353
  }
 
354
 
 
355
  traceEvent(CONST_TRACE_NOISY, "MAC prefix '%s' not found in vendor database", tmpBuf);
 
356
 
 
357
  return("");
 
358
}
 
359
 
 
360
/* *********************************** */
 
361
 
 
362
char* getVendorInfo(u_char* ethAddress, short encodeString) {
 
363
  char* ret;
 
364
 
 
365
  if(memcmp(ethAddress, myGlobals.otherHostEntry->ethAddress, LEN_ETHERNET_ADDRESS) == 0)
 
366
    return("");
 
367
 
 
368
  ret = getMACInfo(1, ethAddress, encodeString);
 
369
  myGlobals.numVendorLookupCalls++;
 
370
 
 
371
  if((ret != NULL) && (ret[0] != '\0'))
 
372
    return(ret);
 
373
  else
 
374
    return("");
 
375
}
 
376
 
 
377
/* *********************************** */
 
378
 
 
379
char* getSpecialMacInfo(HostTraffic* el, short encodeString) {
 
380
  char* ret = getMACInfo(1, (u_char*)&(el->ethAddress), encodeString);
 
381
  myGlobals.numVendorLookupSpecialCalls++;
 
382
 
 
383
  if((ret != NULL) && (ret[0] != '\0'))
 
384
    return(ret);
 
385
  else
 
386
    return("");
 
387
}
 
388
 
 
389
/* *********************************** */
 
390
 
 
391
void createVendorTable(struct stat *dbStat) {
 
392
  int idx, numRead, numLoaded;
 
393
  FILE *fd = NULL;
 
394
  char tmpLine[LEN_GENERAL_WORK_BUFFER];
 
395
  char tmpMACkey[LEN_ETHERNET_ADDRESS_DISPLAY+1];
 
396
  char *tmpMAC, *tmpTag1, *tmpTag2, *tmpVendor, *strtokState;
 
397
  struct macInfo macInfoEntry;
 
398
  datum data_data, key_data;
 
399
  u_char compressedFormat;
 
400
 
 
401
#ifdef TEST_HASHSIZE_IPXSAP
 
402
  {
 
403
    int i, j, best, besti;
 
404
 
 
405
    traceEvent(CONST_TRACE_ALWAYSDISPLAY, "TEST_HASHSIZE: Testing ipxSAP (%s) from 51 -> %d...wait",
 
406
#ifdef PARM_USE_MACHASH_INVERT
 
407
               "invert",
 
408
#else
 
409
               "normal",
 
410
#endif
 
411
               MAX_IPXSAP_NAME_HASH);
 
412
    best=99999;
 
413
    besti=0;
 
414
    for (i=51; i<=MAX_IPXSAP_NAME_HASH; i += 2) {
 
415
      j=0;
 
416
      for(idx=0; ipxSAP[idx].ipxsapName != NULL; idx++)
 
417
        j += addIPXSAPTableEntry(ipxSAPhash, &ipxSAP[idx], i);
 
418
      if(j == 0) {
 
419
        best=0;
 
420
        besti=i;
 
421
        break;
 
422
      } else if( j < best ) {
 
423
        best = j;
 
424
        besti = i;
 
425
        traceEvent(CONST_TRACE_ALWAYSDISPLAY, "TEST_HASHSIZE: ipxSAP %3d %3d", i, j);
 
426
      }
 
427
      memset(ipxSAPhash, 0, sizeof(ipxSAPhash));
 
428
    }
 
429
    traceEvent(CONST_TRACE_ALWAYSDISPLAY, "TEST_HASHSIZE: ipxSAP BEST is %d collisions, size %d", best, besti);
 
430
  }
 
431
#endif
 
432
 
 
433
  myGlobals.ipxsapHashLoadSize = sizeof(ipxSAPhash);
 
434
  for(idx=0; ipxSAP[idx].ipxsapName != NULL; idx++) {
 
435
    myGlobals.ipxsapHashLoadSize += sizeof(IPXSAPInfo) + strlen(ipxSAP[idx].ipxsapName);
 
436
    myGlobals.ipxsapHashLoadCollisions +=
 
437
      addIPXSAPTableEntry(ipxSAPhash, &ipxSAP[idx], MAX_IPXSAP_NAME_HASH);
 
438
  }
 
439
 
 
440
  /*
 
441
   * Ok, so we've loaded the static table.
 
442
   * Now load the gdbm database for the real stuff
 
443
   *   (database was created and opened in initGdbm() in initialize.c)
 
444
   *
 
445
   *  Here's a sample entry from oui.txt:
 
446
 
 
447
   OUI                             Organization
 
448
   company_id                      Organization
 
449
   Address
 
450
 
 
451
 
 
452
   00-00-00   (hex)                XEROX CORPORATION
 
453
   000000     (base 16)            XEROX CORPORATION
 
454
   M/S 105-50C
 
455
   800 PHILLIPS ROAD
 
456
   WEBSTER NY 14580
 
457
 
 
458
   *  and from (our, specially created) special.txt:
 
459
 
 
460
   018024        (special 24)      Kalpana Etherswitch
 
461
   0180C2000000  (special 48)      Bridge Sp. Tree/OSI Route
 
462
 
 
463
   *  We use the (base 16) as our key and add similar values for special
 
464
   *  mac entries so we could co-mingled them.
 
465
   *
 
466
   *  Note that any line without the 2nd word of '(base' or '(special' is
 
467
   *  simply ignored - allows comments if you're careful.
 
468
   *
 
469
   */
 
470
 
 
471
  traceEvent(CONST_TRACE_INFO, "VENDOR: Loading MAC address table.");
 
472
  for(idx=0; macInputFiles[idx] != NULL; idx++) {
 
473
    fd=checkForInputFile("VENDOR",
 
474
                         "MAC address table",
 
475
                         macInputFiles[idx], 
 
476
                         dbStat,
 
477
                         &compressedFormat);
 
478
    if(fd != NULL) {
 
479
      numLoaded=0;
 
480
      numRead=0;
 
481
      while(readInputFile(fd,
 
482
                          "VENDOR", 
 
483
                          FALSE,
 
484
                          compressedFormat,
 
485
                          5000,
 
486
                          tmpLine, sizeof(tmpLine),
 
487
                          &numRead) == 0) {
 
488
 
 
489
            myGlobals.numVendorLookupRead++;
 
490
            if( (strstr(tmpLine, "(base") == NULL) &&
 
491
                (strstr(tmpLine, "(special") == NULL) ) {
 
492
              continue;
 
493
            }
 
494
            tmpMAC = strtok_r(tmpLine, " \t", &strtokState);
 
495
            if(tmpMAC == NULL) continue;
 
496
            tmpTag1 = strtok_r(NULL, " \t", &strtokState);
 
497
            if(tmpTag1 == NULL) continue;
 
498
            if((strcmp(tmpTag1, "(base") == 0) || (strcmp(tmpTag1, "(special") == 0)) {
 
499
              tmpTag2 = strtok_r(NULL, " \t", &strtokState);
 
500
              if(tmpTag2 == NULL) continue;
 
501
              tmpVendor = strtok_r(NULL, "\n", &strtokState);
 
502
              if(tmpVendor == NULL) continue;
 
503
              /* Skip leading blanks and tabs*/
 
504
              while ( (tmpVendor[0] == ' ') || (tmpVendor[0] == '\t') ) tmpVendor++;
 
505
              memset(&macInfoEntry, 0, sizeof(macInfoEntry));
 
506
              if(strcmp(tmpTag1, "(special") == 0) {
 
507
                macInfoEntry.isSpecial = 's';
 
508
              } else {
 
509
                macInfoEntry.isSpecial = 'r';
 
510
              }
 
511
              memcpy(&(macInfoEntry.vendorName[0]),
 
512
                     tmpVendor,
 
513
                     min(strlen(tmpVendor)+1, sizeof(macInfoEntry.vendorName)-1));
 
514
              data_data.dptr = (void*)(&macInfoEntry);
 
515
              data_data.dsize = sizeof(macInfoEntry);
 
516
              tmpMACkey[0]='\0';
 
517
              strncat(tmpMACkey, tmpMAC, 2);
 
518
              strncat(tmpMACkey, ":", (sizeof(tmpMACkey) - strlen(tmpMACkey) - 1));
 
519
              strncat(tmpMACkey, tmpMAC+2, 2);
 
520
              strncat(tmpMACkey, ":", (sizeof(tmpMACkey) - strlen(tmpMACkey) - 1));
 
521
              strncat(tmpMACkey, tmpMAC+4, 2);
 
522
              if(strcmp(tmpTag2, "48)") == 0) {
 
523
                /* special 48 - full tag */
 
524
                strncat(tmpMACkey, ":", (sizeof(tmpMACkey) - strlen(tmpMACkey) - 1));
 
525
                strncat(tmpMACkey, tmpMAC+6, 2);
 
526
                strncat(tmpMACkey, ":", (sizeof(tmpMACkey) - strlen(tmpMACkey) - 1));
 
527
                strncat(tmpMACkey, tmpMAC+8, 2);
 
528
                strncat(tmpMACkey, ":", (sizeof(tmpMACkey) - strlen(tmpMACkey) - 1));
 
529
                strncat(tmpMACkey, tmpMAC+10, 2);
 
530
              }
 
531
              key_data.dptr = tmpMACkey;
 
532
              key_data.dsize = strlen(tmpMACkey)+1;
 
533
              if(gdbm_store(myGlobals.macPrefixFile, key_data, data_data, GDBM_REPLACE) != 0) {
 
534
                traceEvent(CONST_TRACE_WARNING,
 
535
                           "VENDOR: unable to add record '%s': {%d, %s} - skipped",
 
536
                           tmpMACkey, macInfoEntry.isSpecial, macInfoEntry.vendorName);
 
537
              } else {
 
538
                numLoaded++;
 
539
                myGlobals.numVendorLookupAdded++;
 
540
                if(macInfoEntry.isSpecial == 's')
 
541
                  myGlobals.numVendorLookupAddedSpecial++;
 
542
#ifdef VENDOR_DEBUG
 
543
                traceEvent(CONST_TRACE_INFO, "VENDOR_DEBUG: Added '%s': {%c, %s}",
 
544
                           tmpMACkey, macInfoEntry.isSpecial, macInfoEntry.vendorName);
 
545
#endif
 
546
              }
 
547
            }
 
548
      } /* while ! eof */
 
549
 
 
550
      traceEvent(CONST_TRACE_INFO, "VENDOR: ...loaded %d records", numLoaded);
 
551
 
 
552
    } else {
 
553
      traceEvent(CONST_TRACE_INFO, 
 
554
                 "VENDOR: ntop continues ok");
 
555
    }
 
556
 
 
557
  } /* for macInputFiles */
 
558
 
 
559
}
 
560