]> The Tcpdump Group git mirrors - libpcap/blob - pcap-dag.c
Don't check for NULL in cleanup routines, and don't pass NULL to them.
[libpcap] / pcap-dag.c
1 /*
2 * pcap-dag.c: Packet capture interface for Emulex EndaceDAG cards.
3 *
4 * The functionality of this code attempts to mimic that of pcap-linux as much
5 * as possible. This code is compiled in several different ways depending on
6 * whether DAG_ONLY and HAVE_DAG_API are defined. If HAVE_DAG_API is not
7 * defined it should not get compiled in, otherwise if DAG_ONLY is defined then
8 * the 'dag_' function calls are renamed to 'pcap_' equivalents. If DAG_ONLY
9 * is not defined then nothing is altered - the dag_ functions will be
10 * called as required from their pcap-linux/bpf equivalents.
11 *
12 * Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
13 * Modifications: Jesper Peterson
14 * Koryn Grant
15 * Stephen Donnelly <stephen.donnelly@emulex.com>
16 */
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include <sys/param.h> /* optionally get BSD define */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27
28 #include "pcap-int.h"
29
30 #include <ctype.h>
31 #include <netinet/in.h>
32 #include <sys/mman.h>
33 #include <sys/socket.h>
34 #include <sys/types.h>
35 #include <unistd.h>
36
37 struct mbuf; /* Squelch compiler warnings on some platforms for */
38 struct rtentry; /* declarations in <net/if.h> */
39 #include <net/if.h>
40
41 #include "dagnew.h"
42 #include "dagapi.h"
43 #include "dagpci.h"
44
45 #include "pcap-dag.h"
46
47 /*
48 * DAG devices have names beginning with "dag", followed by a number
49 * from 0 to DAG_MAX_BOARDS, then optionally a colon and a stream number
50 * from 0 to DAG_STREAM_MAX.
51 */
52 #ifndef DAG_MAX_BOARDS
53 #define DAG_MAX_BOARDS 32
54 #endif
55
56 #define ATM_CELL_SIZE 52
57 #define ATM_HDR_SIZE 4
58
59 /*
60 * A header containing additional MTP information.
61 */
62 #define MTP2_SENT_OFFSET 0 /* 1 byte */
63 #define MTP2_ANNEX_A_USED_OFFSET 1 /* 1 byte */
64 #define MTP2_LINK_NUMBER_OFFSET 2 /* 2 bytes */
65 #define MTP2_HDR_LEN 4 /* length of the header */
66
67 #define MTP2_ANNEX_A_NOT_USED 0
68 #define MTP2_ANNEX_A_USED 1
69 #define MTP2_ANNEX_A_USED_UNKNOWN 2
70
71 /* SunATM pseudo header */
72 struct sunatm_hdr {
73 unsigned char flags; /* destination and traffic type */
74 unsigned char vpi; /* VPI */
75 unsigned short vci; /* VCI */
76 };
77
78 /*
79 * Private data for capturing on DAG devices.
80 */
81 struct pcap_dag {
82 struct pcap_stat stat;
83 #ifdef HAVE_DAG_STREAMS_API
84 u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */
85 u_char *dag_mem_top; /* DAG card current memory top pointer */
86 #else /* HAVE_DAG_STREAMS_API */
87 void *dag_mem_base; /* DAG card memory base address */
88 u_int dag_mem_bottom; /* DAG card current memory bottom offset */
89 u_int dag_mem_top; /* DAG card current memory top offset */
90 #endif /* HAVE_DAG_STREAMS_API */
91 int dag_fcs_bits; /* Number of checksum bits from link layer */
92 int dag_offset_flags; /* Flags to pass to dag_offset(). */
93 int dag_stream; /* DAG stream number */
94 int dag_timeout; /* timeout specified to pcap_open_live.
95 * Same as in linux above, introduce
96 * generally? */
97 };
98
99 typedef struct pcap_dag_node {
100 struct pcap_dag_node *next;
101 pcap_t *p;
102 pid_t pid;
103 } pcap_dag_node_t;
104
105 static pcap_dag_node_t *pcap_dags = NULL;
106 static int atexit_handler_installed = 0;
107 static const unsigned short endian_test_word = 0x0100;
108
109 #define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word))
110
111 #define MAX_DAG_PACKET 65536
112
113 static unsigned char TempPkt[MAX_DAG_PACKET];
114
115 static int dag_setfilter(pcap_t *p, struct bpf_program *fp);
116 static int dag_stats(pcap_t *p, struct pcap_stat *ps);
117 static int dag_set_datalink(pcap_t *p, int dlt);
118 static int dag_get_datalink(pcap_t *p);
119 static int dag_setnonblock(pcap_t *p, int nonblock, char *errbuf);
120
121 static void
122 delete_pcap_dag(pcap_t *p)
123 {
124 pcap_dag_node_t *curr = NULL, *prev = NULL;
125
126 for (prev = NULL, curr = pcap_dags; curr != NULL && curr->p != p; prev = curr, curr = curr->next) {
127 /* empty */
128 }
129
130 if (curr != NULL && curr->p == p) {
131 if (prev != NULL) {
132 prev->next = curr->next;
133 } else {
134 pcap_dags = curr->next;
135 }
136 }
137 }
138
139 /*
140 * Performs a graceful shutdown of the DAG card, frees dynamic memory held
141 * in the pcap_t structure, and closes the file descriptor for the DAG card.
142 */
143
144 static void
145 dag_platform_cleanup(pcap_t *p)
146 {
147 struct pcap_dag *pd = p->pr;
148
149 #ifdef HAVE_DAG_STREAMS_API
150 if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
151 fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
152
153 if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
154 fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
155 #else
156 if(dag_stop(p->fd) < 0)
157 fprintf(stderr,"dag_stop: %s\n", strerror(errno));
158 #endif /* HAVE_DAG_STREAMS_API */
159 if(p->fd != -1) {
160 if(dag_close(p->fd) < 0)
161 fprintf(stderr,"dag_close: %s\n", strerror(errno));
162 p->fd = -1;
163 }
164 delete_pcap_dag(p);
165 pcap_cleanup_live_common(p);
166 /* Note: don't need to call close(p->fd) here as dag_close(p->fd) does this. */
167 }
168
169 static void
170 atexit_handler(void)
171 {
172 while (pcap_dags != NULL) {
173 if (pcap_dags->pid == getpid()) {
174 if (pcap_dags->p != NULL)
175 dag_platform_cleanup(pcap_dags->p);
176 } else {
177 delete_pcap_dag(pcap_dags->p);
178 }
179 }
180 }
181
182 static int
183 new_pcap_dag(pcap_t *p)
184 {
185 pcap_dag_node_t *node = NULL;
186
187 if ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) {
188 return -1;
189 }
190
191 if (!atexit_handler_installed) {
192 atexit(atexit_handler);
193 atexit_handler_installed = 1;
194 }
195
196 node->next = pcap_dags;
197 node->p = p;
198 node->pid = getpid();
199
200 pcap_dags = node;
201
202 return 0;
203 }
204
205 static unsigned int
206 dag_erf_ext_header_count(uint8_t * erf, size_t len)
207 {
208 uint32_t hdr_num = 0;
209 uint8_t hdr_type;
210
211 /* basic sanity checks */
212 if ( erf == NULL )
213 return 0;
214 if ( len < 16 )
215 return 0;
216
217 /* check if we have any extension headers */
218 if ( (erf[8] & 0x80) == 0x00 )
219 return 0;
220
221 /* loop over the extension headers */
222 do {
223
224 /* sanity check we have enough bytes */
225 if ( len < (24 + (hdr_num * 8)) )
226 return hdr_num;
227
228 /* get the header type */
229 hdr_type = erf[(16 + (hdr_num * 8))];
230 hdr_num++;
231
232 } while ( hdr_type & 0x80 );
233
234 return hdr_num;
235 }
236
237 /*
238 * Read at most max_packets from the capture stream and call the callback
239 * for each of them. Returns the number of packets handled, -1 if an
240 * error occured, or -2 if we were told to break out of the loop.
241 */
242 static int
243 dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
244 {
245 struct pcap_dag *pd = p->priv;
246 unsigned int processed = 0;
247 int flags = pd->dag_offset_flags;
248 unsigned int nonblocking = flags & DAGF_NONBLOCK;
249 unsigned int num_ext_hdr = 0;
250 unsigned int ticks_per_second;
251
252 /* Get the next bufferful of packets (if necessary). */
253 while (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size) {
254
255 /*
256 * Has "pcap_breakloop()" been called?
257 */
258 if (p->break_loop) {
259 /*
260 * Yes - clear the flag that indicates that
261 * it has, and return -2 to indicate that
262 * we were told to break out of the loop.
263 */
264 p->break_loop = 0;
265 return -2;
266 }
267
268 #ifdef HAVE_DAG_STREAMS_API
269 /* dag_advance_stream() will block (unless nonblock is called)
270 * until 64kB of data has accumulated.
271 * If to_ms is set, it will timeout before 64kB has accumulated.
272 * We wait for 64kB because processing a few packets at a time
273 * can cause problems at high packet rates (>200kpps) due
274 * to inefficiencies.
275 * This does mean if to_ms is not specified the capture may 'hang'
276 * for long periods if the data rate is extremely slow (<64kB/sec)
277 * If non-block is specified it will return immediately. The user
278 * is then responsible for efficiency.
279 */
280 if ( NULL == (pd->dag_mem_top = dag_advance_stream(p->fd, pd->dag_stream, &(pd->dag_mem_bottom))) ) {
281 return -1;
282 }
283 #else
284 /* dag_offset does not support timeouts */
285 pd->dag_mem_top = dag_offset(p->fd, &(pd->dag_mem_bottom), flags);
286 #endif /* HAVE_DAG_STREAMS_API */
287
288 if (nonblocking && (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
289 {
290 /* Pcap is configured to process only available packets, and there aren't any, return immediately. */
291 return 0;
292 }
293
294 if(!nonblocking &&
295 pd->dag_timeout &&
296 (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
297 {
298 /* Blocking mode, but timeout set and no data has arrived, return anyway.*/
299 return 0;
300 }
301
302 }
303
304 /* Process the packets. */
305 while (pd->dag_mem_top - pd->dag_mem_bottom >= dag_record_size) {
306
307 unsigned short packet_len = 0;
308 int caplen = 0;
309 struct pcap_pkthdr pcap_header;
310
311 #ifdef HAVE_DAG_STREAMS_API
312 dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom);
313 #else
314 dag_record_t *header = (dag_record_t *)(pd->dag_mem_base + pd->dag_mem_bottom);
315 #endif /* HAVE_DAG_STREAMS_API */
316
317 u_char *dp = ((u_char *)header); /* + dag_record_size; */
318 unsigned short rlen;
319
320 /*
321 * Has "pcap_breakloop()" been called?
322 */
323 if (p->break_loop) {
324 /*
325 * Yes - clear the flag that indicates that
326 * it has, and return -2 to indicate that
327 * we were told to break out of the loop.
328 */
329 p->break_loop = 0;
330 return -2;
331 }
332
333 rlen = ntohs(header->rlen);
334 if (rlen < dag_record_size)
335 {
336 strncpy(p->errbuf, "dag_read: record too small", PCAP_ERRBUF_SIZE);
337 return -1;
338 }
339 pd->dag_mem_bottom += rlen;
340
341 /* Count lost packets. */
342 switch((header->type & 0x7f)) {
343 /* in these types the color value overwrites the lctr */
344 case TYPE_COLOR_HDLC_POS:
345 case TYPE_COLOR_ETH:
346 case TYPE_DSM_COLOR_HDLC_POS:
347 case TYPE_DSM_COLOR_ETH:
348 case TYPE_COLOR_MC_HDLC_POS:
349 case TYPE_COLOR_HASH_ETH:
350 case TYPE_COLOR_HASH_POS:
351 break;
352
353 default:
354 if (header->lctr) {
355 if (pd->stat.ps_drop > (UINT_MAX - ntohs(header->lctr))) {
356 pd->stat.ps_drop = UINT_MAX;
357 } else {
358 pd->stat.ps_drop += ntohs(header->lctr);
359 }
360 }
361 }
362
363 if ((header->type & 0x7f) == TYPE_PAD) {
364 continue;
365 }
366
367 num_ext_hdr = dag_erf_ext_header_count(dp, rlen);
368
369 /* ERF encapsulation */
370 /* The Extensible Record Format is not dropped for this kind of encapsulation,
371 * and will be handled as a pseudo header by the decoding application.
372 * The information carried in the ERF header and in the optional subheader (if present)
373 * could be merged with the libpcap information, to offer a better decoding.
374 * The packet length is
375 * o the length of the packet on the link (header->wlen),
376 * o plus the length of the ERF header (dag_record_size), as the length of the
377 * pseudo header will be adjusted during the decoding,
378 * o plus the length of the optional subheader (if present).
379 *
380 * The capture length is header.rlen and the byte stuffing for alignment will be dropped
381 * if the capture length is greater than the packet length.
382 */
383 if (p->linktype == DLT_ERF) {
384 packet_len = ntohs(header->wlen) + dag_record_size;
385 caplen = rlen;
386 switch ((header->type & 0x7f)) {
387 case TYPE_MC_AAL5:
388 case TYPE_MC_ATM:
389 case TYPE_MC_HDLC:
390 case TYPE_MC_RAW_CHANNEL:
391 case TYPE_MC_RAW:
392 case TYPE_MC_AAL2:
393 case TYPE_COLOR_MC_HDLC_POS:
394 packet_len += 4; /* MC header */
395 break;
396
397 case TYPE_COLOR_HASH_ETH:
398 case TYPE_DSM_COLOR_ETH:
399 case TYPE_COLOR_ETH:
400 case TYPE_ETH:
401 packet_len += 2; /* ETH header */
402 break;
403 } /* switch type */
404
405 /* Include ERF extension headers */
406 packet_len += (8 * num_ext_hdr);
407
408 if (caplen > packet_len) {
409 caplen = packet_len;
410 }
411 } else {
412 /* Other kind of encapsulation according to the header Type */
413
414 /* Skip over generic ERF header */
415 dp += dag_record_size;
416 /* Skip over extension headers */
417 dp += 8 * num_ext_hdr;
418
419 switch((header->type & 0x7f)) {
420 case TYPE_ATM:
421 case TYPE_AAL5:
422 if (header->type == TYPE_AAL5) {
423 packet_len = ntohs(header->wlen);
424 caplen = rlen - dag_record_size;
425 }
426 case TYPE_MC_ATM:
427 if (header->type == TYPE_MC_ATM) {
428 caplen = packet_len = ATM_CELL_SIZE;
429 dp+=4;
430 }
431 case TYPE_MC_AAL5:
432 if (header->type == TYPE_MC_AAL5) {
433 packet_len = ntohs(header->wlen);
434 caplen = rlen - dag_record_size - 4;
435 dp+=4;
436 }
437 /* Skip over extension headers */
438 caplen -= (8 * num_ext_hdr);
439
440 if (header->type == TYPE_ATM) {
441 caplen = packet_len = ATM_CELL_SIZE;
442 }
443 if (p->linktype == DLT_SUNATM) {
444 struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp;
445 unsigned long rawatm;
446
447 rawatm = ntohl(*((unsigned long *)dp));
448 sunatm->vci = htons((rawatm >> 4) & 0xffff);
449 sunatm->vpi = (rawatm >> 20) & 0x00ff;
450 sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) |
451 ((sunatm->vpi == 0 && sunatm->vci == htons(5)) ? 6 :
452 ((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 :
453 ((dp[ATM_HDR_SIZE] == 0xaa &&
454 dp[ATM_HDR_SIZE+1] == 0xaa &&
455 dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1)));
456
457 } else {
458 packet_len -= ATM_HDR_SIZE;
459 caplen -= ATM_HDR_SIZE;
460 dp += ATM_HDR_SIZE;
461 }
462 break;
463
464 case TYPE_COLOR_HASH_ETH:
465 case TYPE_DSM_COLOR_ETH:
466 case TYPE_COLOR_ETH:
467 case TYPE_ETH:
468 packet_len = ntohs(header->wlen);
469 packet_len -= (pd->dag_fcs_bits >> 3);
470 caplen = rlen - dag_record_size - 2;
471 /* Skip over extension headers */
472 caplen -= (8 * num_ext_hdr);
473 if (caplen > packet_len) {
474 caplen = packet_len;
475 }
476 dp += 2;
477 break;
478
479 case TYPE_COLOR_HASH_POS:
480 case TYPE_DSM_COLOR_HDLC_POS:
481 case TYPE_COLOR_HDLC_POS:
482 case TYPE_HDLC_POS:
483 packet_len = ntohs(header->wlen);
484 packet_len -= (pd->dag_fcs_bits >> 3);
485 caplen = rlen - dag_record_size;
486 /* Skip over extension headers */
487 caplen -= (8 * num_ext_hdr);
488 if (caplen > packet_len) {
489 caplen = packet_len;
490 }
491 break;
492
493 case TYPE_COLOR_MC_HDLC_POS:
494 case TYPE_MC_HDLC:
495 packet_len = ntohs(header->wlen);
496 packet_len -= (pd->dag_fcs_bits >> 3);
497 caplen = rlen - dag_record_size - 4;
498 /* Skip over extension headers */
499 caplen -= (8 * num_ext_hdr);
500 if (caplen > packet_len) {
501 caplen = packet_len;
502 }
503 /* jump the MC_HDLC_HEADER */
504 dp += 4;
505 #ifdef DLT_MTP2_WITH_PHDR
506 if (p->linktype == DLT_MTP2_WITH_PHDR) {
507 /* Add the MTP2 Pseudo Header */
508 caplen += MTP2_HDR_LEN;
509 packet_len += MTP2_HDR_LEN;
510
511 TempPkt[MTP2_SENT_OFFSET] = 0;
512 TempPkt[MTP2_ANNEX_A_USED_OFFSET] = MTP2_ANNEX_A_USED_UNKNOWN;
513 *(TempPkt+MTP2_LINK_NUMBER_OFFSET) = ((header->rec.mc_hdlc.mc_header>>16)&0x01);
514 *(TempPkt+MTP2_LINK_NUMBER_OFFSET+1) = ((header->rec.mc_hdlc.mc_header>>24)&0xff);
515 memcpy(TempPkt+MTP2_HDR_LEN, dp, caplen);
516 dp = TempPkt;
517 }
518 #endif
519 break;
520
521 case TYPE_IPV4:
522 case TYPE_IPV6:
523 packet_len = ntohs(header->wlen);
524 caplen = rlen - dag_record_size;
525 /* Skip over extension headers */
526 caplen -= (8 * num_ext_hdr);
527 if (caplen > packet_len) {
528 caplen = packet_len;
529 }
530 break;
531
532 /* These types have no matching 'native' DLT, but can be used with DLT_ERF above */
533 case TYPE_MC_RAW:
534 case TYPE_MC_RAW_CHANNEL:
535 case TYPE_IP_COUNTER:
536 case TYPE_TCP_FLOW_COUNTER:
537 case TYPE_INFINIBAND:
538 case TYPE_RAW_LINK:
539 case TYPE_INFINIBAND_LINK:
540 default:
541 /* Unhandled ERF type.
542 * Ignore rather than generating error
543 */
544 continue;
545 } /* switch type */
546
547 } /* ERF encapsulation */
548
549 if (caplen > p->snapshot)
550 caplen = p->snapshot;
551
552 /* Run the packet filter if there is one. */
553 if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
554
555 /* convert between timestamp formats */
556 register unsigned long long ts;
557
558 if (IS_BIGENDIAN()) {
559 ts = SWAPLL(header->ts);
560 } else {
561 ts = header->ts;
562 }
563
564 switch (p->opt.tstamp_precision) {
565 case PCAP_TSTAMP_PRECISION_NANO:
566 ticks_per_second = 1000000000;
567 break;
568 case PCAP_TSTAMP_PRECISION_MICRO:
569 default:
570 ticks_per_second = 1000000;
571 break;
572
573 }
574 pcap_header.ts.tv_sec = ts >> 32;
575 ts = (ts & 0xffffffffULL) * ticks_per_second;
576 ts += 0x80000000; /* rounding */
577 pcap_header.ts.tv_usec = ts >> 32;
578 if (pcap_header.ts.tv_usec >= ticks_per_second) {
579 pcap_header.ts.tv_usec -= ticks_per_second;
580 pcap_header.ts.tv_sec++;
581 }
582
583 /* Fill in our own header data */
584 pcap_header.caplen = caplen;
585 pcap_header.len = packet_len;
586
587 /* Count the packet. */
588 pd->stat.ps_recv++;
589
590 /* Call the user supplied callback function */
591 callback(user, &pcap_header, dp);
592
593 /* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
594 processed++;
595 if (processed == cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
596 {
597 /* Reached the user-specified limit. */
598 return cnt;
599 }
600 }
601 }
602
603 return processed;
604 }
605
606 static int
607 dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
608 {
609 strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards",
610 PCAP_ERRBUF_SIZE);
611 return (-1);
612 }
613
614 /*
615 * Get a handle for a live capture from the given DAG device. Passing a NULL
616 * device will result in a failure. The promisc flag is ignored because DAG
617 * cards are always promiscuous. The to_ms parameter is used in setting the
618 * API polling parameters.
619 *
620 * snaplen is now also ignored, until we get per-stream slen support. Set
621 * slen with approprite DAG tool BEFORE pcap_activate().
622 *
623 * See also pcap(3).
624 */
625 static int dag_activate(pcap_t* handle)
626 {
627 struct pcap_dag *handlep = handle->priv;
628 #if 0
629 char conf[30]; /* dag configure string */
630 #endif
631 char *s;
632 int n;
633 daginf_t* daginf;
634 char * newDev = NULL;
635 char * device = handle->opt.source;
636 #ifdef HAVE_DAG_STREAMS_API
637 uint32_t mindata;
638 struct timeval maxwait;
639 struct timeval poll;
640 #endif
641
642 if (device == NULL) {
643 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
644 return -1;
645 }
646
647 /* Initialize some components of the pcap structure. */
648
649 #ifdef HAVE_DAG_STREAMS_API
650 newDev = (char *)malloc(strlen(device) + 16);
651 if (newDev == NULL) {
652 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
653 goto fail;
654 }
655
656 /* Parse input name to get dag device and stream number if provided */
657 if (dag_parse_name(device, newDev, strlen(device) + 16, &handlep->dag_stream) < 0) {
658 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno));
659 goto fail;
660 }
661 device = newDev;
662
663 if (handlep->dag_stream%2) {
664 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n");
665 goto fail;
666 }
667 #else
668 if (strncmp(device, "/dev/", 5) != 0) {
669 newDev = (char *)malloc(strlen(device) + 5);
670 if (newDev == NULL) {
671 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
672 goto fail;
673 }
674 strcpy(newDev, "/dev/");
675 strcat(newDev, device);
676 device = newDev;
677 }
678 #endif /* HAVE_DAG_STREAMS_API */
679
680 /* setup device parameters */
681 if((handle->fd = dag_open((char *)device)) < 0) {
682 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
683 goto fail;
684 }
685
686 #ifdef HAVE_DAG_STREAMS_API
687 /* Open requested stream. Can fail if already locked or on error */
688 if (dag_attach_stream(handle->fd, handlep->dag_stream, 0, 0) < 0) {
689 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno));
690 goto failclose;
691 }
692
693 /* Set up default poll parameters for stream
694 * Can be overridden by pcap_set_nonblock()
695 */
696 if (dag_get_stream_poll(handle->fd, handlep->dag_stream,
697 &mindata, &maxwait, &poll) < 0) {
698 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
699 goto faildetach;
700 }
701
702 if (handle->opt.immediate) {
703 /* Call callback immediately.
704 * XXX - is this the right way to handle this?
705 */
706 mindata = 0;
707 } else {
708 /* Amount of data to collect in Bytes before calling callbacks.
709 * Important for efficiency, but can introduce latency
710 * at low packet rates if to_ms not set!
711 */
712 mindata = 65536;
713 }
714
715 /* Obey opt.timeout (was to_ms) if supplied. This is a good idea!
716 * Recommend 10-100ms. Calls will time out even if no data arrived.
717 */
718 maxwait.tv_sec = handle->opt.timeout/1000;
719 maxwait.tv_usec = (handle->opt.timeout%1000) * 1000;
720
721 if (dag_set_stream_poll(handle->fd, handlep->dag_stream,
722 mindata, &maxwait, &poll) < 0) {
723 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
724 goto faildetach;
725 }
726
727 #else
728 if((handlep->dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
729 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
730 goto failclose;
731 }
732
733 #endif /* HAVE_DAG_STREAMS_API */
734
735 /* XXX Not calling dag_configure() to set slen; this is unsafe in
736 * multi-stream environments as the gpp config is global.
737 * Once the firmware provides 'per-stream slen' this can be supported
738 * again via the Config API without side-effects */
739 #if 0
740 /* set the card snap length to the specified snaplen parameter */
741 /* This is a really bad idea, as different cards have different
742 * valid slen ranges. Should fix in Config API. */
743 if (handle->snapshot == 0 || handle->snapshot > MAX_DAG_SNAPLEN) {
744 handle->snapshot = MAX_DAG_SNAPLEN;
745 } else if (snaplen < MIN_DAG_SNAPLEN) {
746 handle->snapshot = MIN_DAG_SNAPLEN;
747 }
748 /* snap len has to be a multiple of 4 */
749 pcap_snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
750
751 if(dag_configure(handle->fd, conf) < 0) {
752 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno));
753 goto faildetach;
754 }
755 #endif
756
757 #ifdef HAVE_DAG_STREAMS_API
758 if(dag_start_stream(handle->fd, handlep->dag_stream) < 0) {
759 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno));
760 goto faildetach;
761 }
762 #else
763 if(dag_start(handle->fd) < 0) {
764 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno));
765 goto failclose;
766 }
767 #endif /* HAVE_DAG_STREAMS_API */
768
769 /*
770 * Important! You have to ensure bottom is properly
771 * initialized to zero on startup, it won't give you
772 * a compiler warning if you make this mistake!
773 */
774 handlep->dag_mem_bottom = 0;
775 handlep->dag_mem_top = 0;
776
777 /*
778 * Find out how many FCS bits we should strip.
779 * First, query the card to see if it strips the FCS.
780 */
781 daginf = dag_info(handle->fd);
782 if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code)) {
783 /* DAG 4.2S and 4.23S already strip the FCS. Stripping the final word again truncates the packet. */
784 handlep->dag_fcs_bits = 0;
785
786 /* Note that no FCS will be supplied. */
787 handle->linktype_ext = LT_FCS_DATALINK_EXT(0);
788 } else {
789 /*
790 * Start out assuming it's 32 bits.
791 */
792 handlep->dag_fcs_bits = 32;
793
794 /* Allow an environment variable to override. */
795 if ((s = getenv("ERF_FCS_BITS")) != NULL) {
796 if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
797 handlep->dag_fcs_bits = n;
798 } else {
799 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
800 "pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
801 goto failstop;
802 }
803 }
804
805 /*
806 * Did the user request that they not be stripped?
807 */
808 if ((s = getenv("ERF_DONT_STRIP_FCS")) != NULL) {
809 /* Yes. Note the number of bytes that will be
810 supplied. */
811 handle->linktype_ext = LT_FCS_DATALINK_EXT(handlep->dag_fcs_bits/16);
812
813 /* And don't strip them. */
814 handlep->dag_fcs_bits = 0;
815 }
816 }
817
818 handlep->dag_timeout = handle->opt.timeout;
819
820 handle->linktype = -1;
821 if (dag_get_datalink(handle) < 0)
822 goto failstop;
823
824 handle->bufsize = 0;
825
826 if (new_pcap_dag(handle) < 0) {
827 pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
828 goto failstop;
829 }
830
831 /*
832 * "select()" and "poll()" don't work on DAG device descriptors.
833 */
834 handle->selectable_fd = -1;
835
836 if (newDev != NULL) {
837 free((char *)newDev);
838 }
839
840 handle->read_op = dag_read;
841 handle->inject_op = dag_inject;
842 handle->setfilter_op = dag_setfilter;
843 handle->setdirection_op = NULL; /* Not implemented.*/
844 handle->set_datalink_op = dag_set_datalink;
845 handle->getnonblock_op = pcap_getnonblock_fd;
846 handle->setnonblock_op = dag_setnonblock;
847 handle->stats_op = dag_stats;
848 handle->cleanup_op = dag_platform_cleanup;
849 handlep->stat.ps_drop = 0;
850 handlep->stat.ps_recv = 0;
851 handlep->stat.ps_ifdrop = 0;
852 return 0;
853
854 #ifdef HAVE_DAG_STREAMS_API
855 failstop:
856 if (dag_stop_stream(handle->fd, handlep->dag_stream) < 0) {
857 fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
858 }
859
860 faildetach:
861 if (dag_detach_stream(handle->fd, handlep->dag_stream) < 0)
862 fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
863 #else
864 failstop:
865 if (dag_stop(handle->fd) < 0)
866 fprintf(stderr,"dag_stop: %s\n", strerror(errno));
867 #endif /* HAVE_DAG_STREAMS_API */
868
869 failclose:
870 if (dag_close(handle->fd) < 0)
871 fprintf(stderr,"dag_close: %s\n", strerror(errno));
872 delete_pcap_dag(handle);
873
874 fail:
875 pcap_cleanup_live_common(handle);
876 if (newDev != NULL) {
877 free((char *)newDev);
878 }
879
880 return PCAP_ERROR;
881 }
882
883 pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
884 {
885 const char *cp;
886 char *cpend;
887 long devnum;
888 pcap_t *p;
889 #ifdef HAVE_DAG_STREAMS_API
890 long stream = 0;
891 #endif
892
893 /* Does this look like a DAG device? */
894 cp = strrchr(device, '/');
895 if (cp == NULL)
896 cp = device;
897 /* Does it begin with "dag"? */
898 if (strncmp(cp, "dag", 3) != 0) {
899 /* Nope, doesn't begin with "dag" */
900 *is_ours = 0;
901 return NULL;
902 }
903 /* Yes - is "dag" followed by a number from 0 to DAG_MAX_BOARDS-1 */
904 cp += 3;
905 devnum = strtol(cp, &cpend, 10);
906 #ifdef HAVE_DAG_STREAMS_API
907 if (*cpend == ':') {
908 /* Followed by a stream number. */
909 stream = strtol(++cpend, &cpend, 10);
910 }
911 #endif
912 if (cpend == cp || *cpend != '\0') {
913 /* Not followed by a number. */
914 *is_ours = 0;
915 return NULL;
916 }
917 if (devnum < 0 || devnum >= DAG_MAX_BOARDS) {
918 /* Followed by a non-valid number. */
919 *is_ours = 0;
920 return NULL;
921 }
922 #ifdef HAVE_DAG_STREAMS_API
923 if (stream <0 || stream >= DAG_STREAM_MAX) {
924 /* Followed by a non-valid stream number. */
925 *is_ours = 0;
926 return NULL;
927 }
928 #endif
929
930 /* OK, it's probably ours. */
931 *is_ours = 1;
932
933 p = pcap_create_common(device, ebuf, sizeof (struct pcap_dag));
934 if (p == NULL)
935 return NULL;
936
937 p->activate_op = dag_activate;
938
939 /*
940 * We claim that we support microsecond and nanosecond time
941 * stamps.
942 *
943 * XXX Our native precision is 2^-32s, but libpcap doesn't support
944 * power of two precisions yet. We can convert to either MICRO or NANO.
945 */
946 p->tstamp_precision_count = 2;
947 p->tstamp_precision_list = malloc(2 * sizeof(u_int));
948 if (p->tstamp_precision_list == NULL) {
949 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
950 pcap_strerror(errno));
951 pcap_close(p);
952 return NULL;
953 }
954 p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
955 p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
956 return p;
957 }
958
959 static int
960 dag_stats(pcap_t *p, struct pcap_stat *ps) {
961 struct pcap_dag *pd = p->priv;
962
963 /* This needs to be filled out correctly. Hopefully a dagapi call will
964 provide all necessary information.
965 */
966 /*pd->stat.ps_recv = 0;*/
967 /*pd->stat.ps_drop = 0;*/
968
969 *ps = pd->stat;
970
971 return 0;
972 }
973
974 /*
975 * Previously we just generated a list of all possible names and let
976 * pcap_add_if() attempt to open each one, but with streams this adds up
977 * to 81 possibilities which is inefficient.
978 *
979 * Since we know more about the devices we can prune the tree here.
980 * pcap_add_if() will still retest each device but the total number of
981 * open attempts will still be much less than the naive approach.
982 */
983 int
984 dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
985 {
986 char name[12]; /* XXX - pick a size */
987 int ret = 0;
988 int c;
989 char dagname[DAGNAME_BUFSIZE];
990 int dagstream;
991 int dagfd;
992 dag_card_inf_t *inf;
993 char *description;
994
995 /* Try all the DAGs 0-DAG_MAX_BOARDS */
996 for (c = 0; c < DAG_MAX_BOARDS; c++) {
997 pcap_snprintf(name, 12, "dag%d", c);
998 if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
999 {
1000 return -1;
1001 }
1002 description = NULL;
1003 if ( (dagfd = dag_open(dagname)) >= 0 ) {
1004 if ((inf = dag_pciinfo(dagfd)))
1005 description = dag_device_name(inf->device_code, 1);
1006 if (pcap_add_if(devlistp, name, 0, description, errbuf) == -1) {
1007 /*
1008 * Failure.
1009 */
1010 ret = -1;
1011 }
1012 #ifdef HAVE_DAG_STREAMS_API
1013 {
1014 int stream, rxstreams;
1015 rxstreams = dag_rx_get_stream_count(dagfd);
1016 for(stream=0;stream<DAG_STREAM_MAX;stream+=2) {
1017 if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
1018 dag_detach_stream(dagfd, stream);
1019
1020 pcap_snprintf(name, 10, "dag%d:%d", c, stream);
1021 if (pcap_add_if(devlistp, name, 0, description, errbuf) == -1) {
1022 /*
1023 * Failure.
1024 */
1025 ret = -1;
1026 }
1027
1028 rxstreams--;
1029 if(rxstreams <= 0) {
1030 break;
1031 }
1032 }
1033 }
1034 }
1035 #endif /* HAVE_DAG_STREAMS_API */
1036 dag_close(dagfd);
1037 }
1038
1039 }
1040 return (ret);
1041 }
1042
1043 /*
1044 * Installs the given bpf filter program in the given pcap structure. There is
1045 * no attempt to store the filter in kernel memory as that is not supported
1046 * with DAG cards.
1047 */
1048 static int
1049 dag_setfilter(pcap_t *p, struct bpf_program *fp)
1050 {
1051 if (!p)
1052 return -1;
1053 if (!fp) {
1054 strncpy(p->errbuf, "setfilter: No filter specified",
1055 sizeof(p->errbuf));
1056 return -1;
1057 }
1058
1059 /* Make our private copy of the filter */
1060
1061 if (install_bpf_program(p, fp) < 0)
1062 return -1;
1063
1064 return (0);
1065 }
1066
1067 static int
1068 dag_set_datalink(pcap_t *p, int dlt)
1069 {
1070 p->linktype = dlt;
1071
1072 return (0);
1073 }
1074
1075 static int
1076 dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
1077 {
1078 struct pcap_dag *pd = p->priv;
1079
1080 /*
1081 * Set non-blocking mode on the FD.
1082 * XXX - is that necessary? If not, don't bother calling it,
1083 * and have a "dag_getnonblock()" function that looks at
1084 * "pd->dag_offset_flags".
1085 */
1086 if (pcap_setnonblock_fd(p, nonblock, errbuf) < 0)
1087 return (-1);
1088 #ifdef HAVE_DAG_STREAMS_API
1089 {
1090 uint32_t mindata;
1091 struct timeval maxwait;
1092 struct timeval poll;
1093
1094 if (dag_get_stream_poll(p->fd, pd->dag_stream,
1095 &mindata, &maxwait, &poll) < 0) {
1096 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
1097 return -1;
1098 }
1099
1100 /* Amount of data to collect in Bytes before calling callbacks.
1101 * Important for efficiency, but can introduce latency
1102 * at low packet rates if to_ms not set!
1103 */
1104 if(nonblock)
1105 mindata = 0;
1106 else
1107 mindata = 65536;
1108
1109 if (dag_set_stream_poll(p->fd, pd->dag_stream,
1110 mindata, &maxwait, &poll) < 0) {
1111 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
1112 return -1;
1113 }
1114 }
1115 #endif /* HAVE_DAG_STREAMS_API */
1116 if (nonblock) {
1117 pd->dag_offset_flags |= DAGF_NONBLOCK;
1118 } else {
1119 pd->dag_offset_flags &= ~DAGF_NONBLOCK;
1120 }
1121 return (0);
1122 }
1123
1124 static int
1125 dag_get_datalink(pcap_t *p)
1126 {
1127 struct pcap_dag *pd = p->priv;
1128 int index=0, dlt_index=0;
1129 uint8_t types[255];
1130
1131 memset(types, 0, 255);
1132
1133 if (p->dlt_list == NULL && (p->dlt_list = malloc(255*sizeof(*(p->dlt_list)))) == NULL) {
1134 (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", pcap_strerror(errno));
1135 return (-1);
1136 }
1137
1138 p->linktype = 0;
1139
1140 #ifdef HAVE_DAG_GET_STREAM_ERF_TYPES
1141 /* Get list of possible ERF types for this card */
1142 if (dag_get_stream_erf_types(p->fd, pd->dag_stream, types, 255) < 0) {
1143 pcap_snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_stream_erf_types: %s", pcap_strerror(errno));
1144 return (-1);
1145 }
1146
1147 while (types[index]) {
1148
1149 #elif defined HAVE_DAG_GET_ERF_TYPES
1150 /* Get list of possible ERF types for this card */
1151 if (dag_get_erf_types(p->fd, types, 255) < 0) {
1152 pcap_snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_erf_types: %s", pcap_strerror(errno));
1153 return (-1);
1154 }
1155
1156 while (types[index]) {
1157 #else
1158 /* Check the type through a dagapi call. */
1159 types[index] = dag_linktype(p->fd);
1160
1161 {
1162 #endif
1163 switch((types[index] & 0x7f)) {
1164
1165 case TYPE_HDLC_POS:
1166 case TYPE_COLOR_HDLC_POS:
1167 case TYPE_DSM_COLOR_HDLC_POS:
1168 case TYPE_COLOR_HASH_POS:
1169
1170 if (p->dlt_list != NULL) {
1171 p->dlt_list[dlt_index++] = DLT_CHDLC;
1172 p->dlt_list[dlt_index++] = DLT_PPP_SERIAL;
1173 p->dlt_list[dlt_index++] = DLT_FRELAY;
1174 }
1175 if(!p->linktype)
1176 p->linktype = DLT_CHDLC;
1177 break;
1178
1179 case TYPE_ETH:
1180 case TYPE_COLOR_ETH:
1181 case TYPE_DSM_COLOR_ETH:
1182 case TYPE_COLOR_HASH_ETH:
1183 /*
1184 * This is (presumably) a real Ethernet capture; give it a
1185 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
1186 * that an application can let you choose it, in case you're
1187 * capturing DOCSIS traffic that a Cisco Cable Modem
1188 * Termination System is putting out onto an Ethernet (it
1189 * doesn't put an Ethernet header onto the wire, it puts raw
1190 * DOCSIS frames out on the wire inside the low-level
1191 * Ethernet framing).
1192 */
1193 if (p->dlt_list != NULL) {
1194 p->dlt_list[dlt_index++] = DLT_EN10MB;
1195 p->dlt_list[dlt_index++] = DLT_DOCSIS;
1196 }
1197 if(!p->linktype)
1198 p->linktype = DLT_EN10MB;
1199 break;
1200
1201 case TYPE_ATM:
1202 case TYPE_AAL5:
1203 case TYPE_MC_ATM:
1204 case TYPE_MC_AAL5:
1205 if (p->dlt_list != NULL) {
1206 p->dlt_list[dlt_index++] = DLT_ATM_RFC1483;
1207 p->dlt_list[dlt_index++] = DLT_SUNATM;
1208 }
1209 if(!p->linktype)
1210 p->linktype = DLT_ATM_RFC1483;
1211 break;
1212
1213 case TYPE_COLOR_MC_HDLC_POS:
1214 case TYPE_MC_HDLC:
1215 if (p->dlt_list != NULL) {
1216 p->dlt_list[dlt_index++] = DLT_CHDLC;
1217 p->dlt_list[dlt_index++] = DLT_PPP_SERIAL;
1218 p->dlt_list[dlt_index++] = DLT_FRELAY;
1219 p->dlt_list[dlt_index++] = DLT_MTP2;
1220 p->dlt_list[dlt_index++] = DLT_MTP2_WITH_PHDR;
1221 p->dlt_list[dlt_index++] = DLT_LAPD;
1222 }
1223 if(!p->linktype)
1224 p->linktype = DLT_CHDLC;
1225 break;
1226
1227 case TYPE_IPV4:
1228 case TYPE_IPV6:
1229 if(!p->linktype)
1230 p->linktype = DLT_RAW;
1231 break;
1232
1233 case TYPE_LEGACY:
1234 case TYPE_MC_RAW:
1235 case TYPE_MC_RAW_CHANNEL:
1236 case TYPE_IP_COUNTER:
1237 case TYPE_TCP_FLOW_COUNTER:
1238 case TYPE_INFINIBAND:
1239 case TYPE_RAW_LINK:
1240 case TYPE_INFINIBAND_LINK:
1241 default:
1242 /* Libpcap cannot deal with these types yet */
1243 /* Add no 'native' DLTs, but still covered by DLT_ERF */
1244 break;
1245
1246 } /* switch */
1247 index++;
1248 }
1249
1250 p->dlt_list[dlt_index++] = DLT_ERF;
1251
1252 p->dlt_count = dlt_index;
1253
1254 if(!p->linktype)
1255 p->linktype = DLT_ERF;
1256
1257 return p->linktype;
1258 }