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