~ubuntu-branches/ubuntu/precise/xprobe/precise

« back to all changes in this revision

Viewing changes to libs-external/USI++/src/datalink.cc

  • Committer: Bazaar Package Importer
  • Author(s): Richard Atterer
  • Date: 2005-08-17 13:43:07 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20050817134307-7n4f1dq66uapcj9y
Tags: 0.3-1
New upstream version

Show diffs side-by-side

added added

removed removed

Lines of Context:
190
190
        char ebuf[PCAP_ERRBUF_SIZE];
191
191
        memset(ebuf, 0, PCAP_ERRBUF_SIZE);
192
192
        
193
 
        if ((d_pd = pcap_open_live(dev, d_snaplen, promisc, 500, ebuf)) == NULL) {
194
 
                die(ebuf, STDERR, 1);
195
 
        }
196
 
#ifdef HAVE_PCAP_SETNONBLOCK
197
 
                // make sure pcap_next() does not block
198
 
                if (pcap_setnonblock(d_pd, 1, ebuf) < 0) {
199
 
                        die(ebuf, STDERR, 1);
200
 
                }
201
 
#endif
 
193
        if ((d_pd = pcap_open_live(dev, d_snaplen, promisc, 500, ebuf)) == NULL) {
 
194
                die(ebuf, STDERR, 1);
 
195
        }
202
196
 
203
197
// Ehem, BSD workarounnd. BSD won't timeout on select()
204
198
// unless we force immediate return for read() (in pcap)
212
206
                die(ebuf, STDERR, 1);
213
207
        }
214
208
#endif        
215
 
        if (pcap_lookupnet(dev, &d_localnet, &d_netmask, ebuf) < 0) {
216
 
                snprintf(ebuf, sizeof(ebuf), "Pcap::init_device::pcap_lookupnet: %s\n",
 
209
        if (pcap_lookupnet(dev, &d_localnet, &d_netmask, ebuf) < 0) {
 
210
                snprintf(ebuf, sizeof(ebuf), "Pcap::init_device::pcap_lookupnet: %s\n",
217
211
                        pcap_geterr(d_pd));
218
212
                die(ebuf, STDERR, 1);
219
 
        }
 
213
        }
220
214
        
221
215
 
222
216
        /* The d_filter_string must be filled by derived classes, such
223
217
         * as IP, where the virtual init_device() simply sets d_filter_string
224
218
         * to "ip" and then calls Pcap::init_device().
225
219
         */
226
 
        if (pcap_compile(d_pd, &d_filter, d_filter_string, 1, d_netmask) < 0) {
227
 
                snprintf(ebuf, sizeof(ebuf), "Pcap::init_device::pcap_compile: %s\n",
228
 
                        pcap_geterr(d_pd));
229
 
                die(ebuf, STDERR, 1);
230
 
        }
231
 
        if (pcap_setfilter(d_pd, &d_filter) < 0) {
232
 
                snprintf(ebuf, sizeof(ebuf), "Pcap::init_device::pcap_setfilter: %s\n",
233
 
                        pcap_geterr(d_pd));
234
 
                die(ebuf, STDERR, 1);
235
 
        }
236
 
        if ((d_datalink = pcap_datalink(d_pd)) < 0) {
237
 
                snprintf(ebuf, sizeof(ebuf), "Pcap::init_device::pcap_d_datalink: %s\n",
238
 
                        pcap_geterr(d_pd));
239
 
                die(ebuf, STDERR, 1);
240
 
        }
 
220
        if (pcap_compile(d_pd, &d_filter, d_filter_string, 1, d_netmask) < 0) {
 
221
                snprintf(ebuf, sizeof(ebuf), "Pcap::init_device::pcap_compile: %s\n",
 
222
                pcap_geterr(d_pd));
 
223
                die(ebuf, STDERR, 1);
 
224
        }
 
225
        if (pcap_setfilter(d_pd, &d_filter) < 0) {
 
226
                snprintf(ebuf, sizeof(ebuf), "Pcap::init_device::pcap_setfilter: %s\n",
 
227
                        pcap_geterr(d_pd));
 
228
                die(ebuf, STDERR, 1);
 
229
        }
 
230
        if ((d_datalink = pcap_datalink(d_pd)) < 0) {
 
231
                snprintf(ebuf, sizeof(ebuf), "Pcap::init_device::pcap_d_datalink: %s\n",
 
232
                        pcap_geterr(d_pd));
 
233
                die(ebuf, STDERR, 1);
 
234
        }
241
235
 
242
 
        // turn d_datalink into d_framelen
243
 
        switch (d_datalink) {
244
 
        case DLT_EN10MB:
245
 
                d_framelen = sizeof(d_ether);
246
 
                break;
 
236
        // turn d_datalink into d_framelen
 
237
        switch (d_datalink) {
 
238
                case DLT_EN10MB:
 
239
                        d_framelen = sizeof(d_ether);
 
240
                break;
 
241
 
247
242
        case DLT_PPP:
248
 
                d_framelen = 4; /* shouldn't be 4 */
249
 
                break;
250
 
        case DLT_PPP_BSDOS:
251
 
                d_framelen = 24;
252
 
                break;
253
 
        case DLT_SLIP:
254
 
                d_framelen = 24;
255
 
                break;
256
 
        case DLT_RAW:
257
 
                d_framelen = 0;
258
 
                break;
259
 
 
260
 
        // loopback
 
243
                        d_framelen = 4; /* shouldn't be 4 */
 
244
                break;
 
245
                case DLT_PPP_BSDOS:
 
246
                        d_framelen = 24;
 
247
                        break;
 
248
                case DLT_SLIP:
 
249
                        d_framelen = 24;
 
250
                        break;
 
251
                case DLT_RAW:
 
252
                        d_framelen = 0;
 
253
                        break;
 
254
                // loopback
261
255
#ifdef DLT_LOOP
262
 
        case DLT_LOOP:
 
256
                case DLT_LOOP:
263
257
#endif
264
 
        case DLT_NULL:
265
 
                d_framelen = 4;
 
258
                case DLT_NULL:
 
259
                        d_framelen = 4;
266
260
                break;
267
261
#ifdef DLT_LINUX_SLL
268
 
    case DLT_LINUX_SLL:
269
 
        d_framelen = 16;
270
 
        break;          
 
262
                case DLT_LINUX_SLL:
 
263
                        d_framelen = 16;
 
264
                break;          
271
265
#endif
272
 
 
273
 
        default:
274
 
                printf("%d %d\n", d_datalink, DLT_RAW);
275
 
            fprintf(stderr, "Datalink type: %i not supported.  Report!\n", d_datalink);
276
 
                die("Pcap::init_device: Unknown d_datalink.\n", STDERR, 1);
277
 
        }
 
266
                default:
 
267
                        printf("%d %d\n", d_datalink, DLT_RAW);
 
268
                        fprintf(stderr, "Datalink type: %i not supported.  Report!\n", d_datalink);
 
269
                        die("Pcap::init_device: Unknown d_datalink.\n", STDERR, 1);
 
270
        }
278
271
       
279
272
        strncpy(d_dev, dev, sizeof(d_dev));
280
273
        d_has_promisc = promisc;
281
274
        d_snaplen = d_snaplen;
282
 
        return 0;
 
275
        set_nonblock();
 
276
        return 0;
283
277
}
284
278
 
285
279
 
296
290
        memset(d_filter_string, 0, sizeof(d_filter_string));
297
291
        snprintf(d_filter_string, sizeof(d_filter_string), "%s", s);
298
292
        
299
 
        if (pcap_compile(d_pd, &d_filter, d_filter_string, 1, d_netmask) < 0) {
300
 
                snprintf(ebuf, sizeof(ebuf), "Pcap::setfilter::pcap_compile: %s\n", pcap_geterr(d_pd));
 
293
        if (pcap_compile(d_pd, &d_filter, d_filter_string, 1, d_netmask) < 0) {
 
294
                snprintf(ebuf, sizeof(ebuf), "Pcap::setfilter::pcap_compile: %s\n", pcap_geterr(d_pd));
301
295
                die(ebuf, STDERR, 1);
302
 
        }
 
296
        }
303
297
 
304
 
        if (pcap_setfilter(d_pd, &d_filter) < 0) {
305
 
                snprintf(ebuf, sizeof(ebuf), "Pcap::setfilter::pcap_setfilter: %s\n", pcap_geterr(d_pd));
 
298
        if (pcap_setfilter(d_pd, &d_filter) < 0) {
 
299
                snprintf(ebuf, sizeof(ebuf), "Pcap::setfilter::pcap_setfilter: %s\n", pcap_geterr(d_pd));
306
300
                die(ebuf, STDERR, 1);
307
 
        }
308
 
        return 0;
 
301
        }
 
302
        set_nonblock();
 
303
        return 0;
309
304
}
310
305
 
311
306
int Pcap::sniffpack(void *s, size_t len)
349
344
                start = time(NULL);
350
345
 
351
346
        if (d_tv.tv_sec != 0 || d_tv.tv_usec != 0) { // timeout set
 
347
/*
352
348
                while ((tmp = (char*)pcap_next(d_pd, &d_phdr)) == NULL)
353
349
                        if ((time(NULL) - start) > d_tv.tv_sec) {
354
350
                                d_timeout = true;
355
351
                                start = 0;
356
352
                                return 0;
357
353
                        }
 
354
*/
 
355
                while (1) {
 
356
                        if ((time(NULL) - start) > d_tv.tv_sec) {
 
357
                                d_timeout = true;
 
358
                                start = 0;
 
359
                                return 0;
 
360
                        }
 
361
                        tmp = (char*)pcap_next(d_pd, &d_phdr);
 
362
                        if (tmp != NULL) {
 
363
                                break;
 
364
                        }
 
365
                }
358
366
        } else { // no timeout set, loop until we get some kind of packet
359
367
                while ((tmp = (char*)pcap_next(d_pd, &d_phdr)) == NULL)
360
368
                        ;
398
406
// give back layer2 frame
399
407
void *Pcap::get_frame(void *hwframe, size_t len)
400
408
{
401
 
       
402
 
        // switch over the hardware-layer of the packet 
 
409
        // switch over the hardware-layer of the packet 
403
410
        switch (d_datalink) {
404
 
        case DLT_EN10MB:
405
 
                memcpy(hwframe, &d_ether, (len<sizeof(d_ether)?len:sizeof(d_ether)));
406
 
                break;
407
 
        default:
408
 
                return NULL;
409
 
        }
410
 
        return hwframe;
 
411
        case DLT_EN10MB:
 
412
                        memcpy(hwframe, &d_ether, (len<sizeof(d_ether)?len:sizeof(d_ether)));
 
413
                break;
 
414
        default:
 
415
                return NULL;
 
416
        }
 
417
        return hwframe;
411
418
}
412
419
 
413
420
int Pcap::timeout(struct timeval tv)
422
429
        return d_timeout;
423
430
}
424
431
 
 
432
bool Pcap::set_nonblock()
 
433
{
 
434
#ifdef HAVE_PCAP_SETNONBLOCK
 
435
        char ebuf[PCAP_ERRBUF_SIZE];
 
436
        memset(ebuf, 0, PCAP_ERRBUF_SIZE);
 
437
        // make sure pcap_next() does not block
 
438
        if (pcap_setnonblock(d_pd, 1, ebuf) < 0) {
 
439
                die(ebuf, STDERR, 1);
 
440
        }
 
441
        return true;
 
442
#endif
 
443
}
 
444
 
 
445
int Pcap::get_nonblock()
 
446
{
 
447
#ifdef HAVE_PCAP_SETNONBLOCK
 
448
        int retval;
 
449
        char ebuf[PCAP_ERRBUF_SIZE];
 
450
        memset(ebuf, 0, PCAP_ERRBUF_SIZE);
 
451
        // make sure pcap_next() does not block
 
452
        if ((retval=pcap_getnonblock(d_pd, ebuf)) < 0) {
 
453
                die(ebuf, STDERR, 1);
 
454
        }
 
455
        return retval;
 
456
#endif
 
457
}
425
458
} // namespace usipp