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