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