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