1 /*        $NetBSD: pcap-sita.c,v 1.8 2024/09/02 15:33:37 christos Exp $         */
2 
3 /*
4  *  pcap-sita.c: Packet capture interface additions for SITA ACN devices
5  *
6  *  Copyright (c) 2007 Fulko Hew, SITA INC Canada, Inc <fulko.hew@sita.aero>
7  *
8  *  License: BSD
9  *
10  *  Redistribution and use in source and binary forms, with or without
11  *  modification, are permitted provided that the following conditions
12  *  are met:
13  *
14  *  1. Redistributions of source code must retain the above copyright
15  *     notice, this list of conditions and the following disclaimer.
16  *  2. Redistributions in binary form must reproduce the above copyright
17  *     notice, this list of conditions and the following disclaimer in
18  *     the documentation and/or other materials provided with the
19  *     distribution.
20  *  3. The names of the authors may not be used to endorse or promote
21  *     products derived from this software without specific prior
22  *     written permission.
23  *
24  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
25  *  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
26  *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27  */
28 
29 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: pcap-sita.c,v 1.8 2024/09/02 15:33:37 christos Exp $");
31 
32 #include <config.h>
33 
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <fcntl.h>
39 #include <errno.h>
40 #include <sys/time.h>
41 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <arpa/inet.h>
44 #include "pcap-int.h"
45 
46 #include "pcap-sita.h"
47 
48           /* non-configurable manifests follow */
49 
50 #define IOP_SNIFFER_PORT      49152                         /* TCP port on the IOP used for 'distributed pcap' usage */
51 #define MAX_LINE_SIZE                   255                                     /* max size of a buffer/line in /etc/hosts we allow */
52 #define MAX_CHASSIS                     8                                       /* number of chassis in an ACN site */
53 #define MAX_GEOSLOT                     8                                       /* max number of access units in an ACN site */
54 
55 #define FIND                            0
56 #define LIVE                            1
57 
58 typedef struct iface {
59           struct iface        *next;              /* a pointer to the next interface */
60           char                *name;              /* this interface's name */
61           char                *IOPname; /* this interface's name on an IOP */
62           uint32_t  iftype;             /* the type of interface (DLT values) */
63 } iface_t;
64 
65 typedef struct unit {
66           char                          *ip;                /* this unit's IP address (as extracted from /etc/hosts) */
67           int                           fd;                 /* the connection to this unit (if it exists) */
68           int                           find_fd;  /* a big kludge to avoid my programming limitations since I could have this unit open for findalldevs purposes */
69           int                           first_time;         /* 0 = just opened via acn_open_live(),  ie. the first time, NZ = nth time */
70           struct sockaddr_in  *serv_addr;         /* the address control block for comms to this unit */
71           int                           chassis;
72           int                           geoslot;
73           iface_t                       *iface;             /* a pointer to a linked list of interface structures */
74           char                          *imsg;              /* a pointer to an inbound message */
75           int                           len;                /* the current size of the inbound message */
76 } unit_t;
77 
78 /*
79  * Private data.
80  * Currently contains nothing.
81  */
82 struct pcap_sita {
83           int       dummy;
84 };
85 
86 static unit_t                 units[MAX_CHASSIS+1][MAX_GEOSLOT+1];    /* we use indexes of 1 through 8, but we reserve/waste index 0 */
87 static fd_set                 readfds;                                /* a place to store the file descriptors for the connections to the IOPs */
88 static int                    max_fs;
89 
90 pcap_if_t           *acn_if_list;                 /* pcap's list of available interfaces */
91 
dump_interface_list(void)92 static void dump_interface_list(void) {
93           pcap_if_t           *iff;
94           pcap_addr_t                   *addr;
95           int                           longest_name_len = 0;
96           char                          *n, *d, *f;
97           int                           if_number = 0;
98 
99           iff = acn_if_list;
100           while (iff) {
101                     if (iff->name && (strlen(iff->name) > longest_name_len)) longest_name_len = strlen(iff->name);
102                     iff = iff->next;
103           }
104           iff = acn_if_list;
105           printf("Interface List:\n");
106           while (iff) {
107                     n = (iff->name)                                                                 ? iff->name                             : "";
108                     d = (iff->description)                                                ? iff->description  : "";
109                     f = (iff->flags == PCAP_IF_LOOPBACK)    ? "L"                                   : "";
110                     printf("%3d: %*s %s '%s'\n", if_number++, longest_name_len, n, f, d);
111                     addr = iff->addresses;
112                     while (addr) {
113                               printf("%*s ", (5 + longest_name_len), "");                 /* add some indentation */
114                               printf("%15s  ", (addr->addr)           ? inet_ntoa(((struct sockaddr_in *)addr->addr)->sin_addr)             : "");
115                               printf("%15s  ", (addr->netmask)        ? inet_ntoa(((struct sockaddr_in *)addr->netmask)->sin_addr)          : "");
116                               printf("%15s  ", (addr->broadaddr)      ? inet_ntoa(((struct sockaddr_in *)addr->broadaddr)->sin_addr)        : "");
117                               printf("%15s  ", (addr->dstaddr)        ? inet_ntoa(((struct sockaddr_in *)addr->dstaddr)->sin_addr)          : "");
118                               printf("\n");
119                               addr = addr->next;
120                     }
121                     iff = iff->next;
122           }
123 }
124 
dump(unsigned char * ptr,int i,int indent)125 static void dump(unsigned char *ptr, int i, int indent) {
126           fprintf(stderr, "%*s", indent, " ");
127           for (; i > 0; i--) {
128                     fprintf(stderr, "%2.2x ", *ptr++);
129           }
130           fprintf(stderr, "\n");
131 }
132 
dump_interface_list_p(void)133 static void dump_interface_list_p(void) {
134           pcap_if_t           *iff;
135           pcap_addr_t                   *addr;
136           int                                     if_number = 0;
137 
138           iff = acn_if_list;
139           printf("Interface Pointer @ %p is %p:\n", &acn_if_list, iff);
140           while (iff) {
141                     printf("%3d: %p %p next: %p\n", if_number++, iff->name, iff->description, iff->next);
142                     dump((unsigned char *)iff, sizeof(pcap_if_t), 5);
143                     addr = iff->addresses;
144                     while (addr) {
145                               printf("          %p %p %p %p, next: %p\n", addr->addr, addr->netmask, addr->broadaddr, addr->dstaddr, addr->next);
146                               dump((unsigned char *)addr, sizeof(pcap_addr_t), 10);
147                               addr = addr->next;
148                     }
149                     iff = iff->next;
150           }
151 }
152 
dump_unit_table(void)153 static void dump_unit_table(void) {
154           int                 chassis, geoslot;
155           iface_t   *p;
156 
157           printf("%c:%c %s %s\n", 'C', 'S', "fd", "IP Address");
158           for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
159                     for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
160                               if (units[chassis][geoslot].ip != NULL)
161                                         printf("%d:%d %2d %s\n", chassis, geoslot, units[chassis][geoslot].fd, units[chassis][geoslot].ip);
162                               p = units[chassis][geoslot].iface;
163                               while (p) {
164                                         char *n = (p->name)                     ? p->name                     : "";
165                                         char *i = (p->IOPname)                  ? p->IOPname                  : "";
166                                         p = p->next;
167                                         printf("   %12s    -> %12s\n", i, n);
168                               }
169                     }
170           }
171 }
172 
find_unit_by_fd(int fd,int * chassis,int * geoslot,unit_t ** unit_ptr)173 static int find_unit_by_fd(int fd, int *chassis, int *geoslot, unit_t **unit_ptr) {
174           int                 c, s;
175 
176           for (c = 0; c <= MAX_CHASSIS; c++) {
177                     for (s = 0; s <= MAX_GEOSLOT; s++) {
178                               if (units[c][s].fd == fd || units[c][s].find_fd == fd) {
179                                         if (chassis)        *chassis = c;
180                                         if (geoslot)        *geoslot = s;
181                                         if (unit_ptr)       *unit_ptr = &units[c][s];
182                                         return 1;
183                               }
184                     }
185           }
186           return 0;
187 }
188 
read_client_nbytes(int fd,int count,unsigned char * buf)189 static int read_client_nbytes(int fd, int count, unsigned char *buf) {
190           unit_t                        *u;
191           int                                     chassis, geoslot;
192           int                                     len;
193 
194           find_unit_by_fd(fd, &chassis, &geoslot, &u);
195           while (count) {
196                     if ((len = recv(fd, buf, count, 0)) <= 0)         return -1;          /* read in whatever data was sent to us */
197                     count -= len;
198                     buf += len;
199           }                                                                                                                                                     /* till we have everything we are looking for */
200           return 0;
201 }
202 
empty_unit_iface(unit_t * u)203 static void empty_unit_iface(unit_t *u) {
204           iface_t   *p, *cur;
205 
206           cur = u->iface;
207           while (cur) {                                                                                                           /* loop over all the interface entries */
208                     if (cur->name)                          free(cur->name);                        /* throwing away the contents if they exist */
209                     if (cur->IOPname)             free(cur->IOPname);
210                     p = cur->next;
211                     free(cur);                                                                                                              /* then throw away the structure itself */
212                     cur = p;
213           }
214           u->iface = 0;                                                                                                           /* and finally remember that there are no remaining structure */
215 }
216 
empty_unit(int chassis,int geoslot)217 static void empty_unit(int chassis, int geoslot) {
218           unit_t    *u = &units[chassis][geoslot];
219 
220           empty_unit_iface(u);
221           if (u->imsg) {                                                                                                          /* then if an inbound message buffer exists */
222                     void *bigger_buffer;
223 
224                     bigger_buffer = (char *)realloc(u->imsg, 1);                                    /* and re-allocate the old large buffer into a new small one */
225                     if (bigger_buffer == NULL) {  /* oops, realloc call failed */
226                               fprintf(stderr, "Warning...call to realloc() failed, value of errno is %d\n", errno);
227                               return;
228                     }
229                     u->imsg = bigger_buffer;
230           }
231 }
232 
empty_unit_table(void)233 static void empty_unit_table(void) {
234           int                 chassis, geoslot;
235 
236           for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
237                     for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
238                               if (units[chassis][geoslot].ip != NULL) {
239                                         free(units[chassis][geoslot].ip);                           /* get rid of the malloc'ed space that holds the IP address */
240                                         units[chassis][geoslot].ip = 0;                                       /* then set the pointer to NULL */
241                               }
242                               empty_unit(chassis, geoslot);
243                     }
244           }
245 }
246 
find_nth_interface_name(int n)247 static char *find_nth_interface_name(int n) {
248           int                 chassis, geoslot;
249           iface_t   *p;
250           char      *last_name = 0;
251 
252           if (n < 0) n = 0;                                                                                                                 /* ensure we are working with a valid number */
253           for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {                          /* scan the table... */
254                     for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
255                               if (units[chassis][geoslot].ip != NULL) {
256                                         p = units[chassis][geoslot].iface;
257                                         while (p) {                                                                                                             /* and all interfaces... */
258                                                   if (p->IOPname) last_name = p->name;                        /* remembering the last name found */
259                                                   if (n-- == 0) return last_name;                                                 /* and if we hit the instance requested */
260                                                   p = p->next;
261                                         }
262                               }
263                     }
264           }
265                                                                                                               /* if we couldn't fine the selected entry */
266           if (last_name)      return last_name;             /* ... but we did have at least one entry... return the last entry found */
267           return "";                                                                                /* ... but if there wasn't any entry... return an empty string instead */
268 }
269 
acn_parse_hosts_file(char * errbuf)270 int acn_parse_hosts_file(char *errbuf) {                                        /* returns: -1 = error, 0 = OK */
271           FILE      *fp;
272           char      buf[MAX_LINE_SIZE];
273           char      *ptr, *ptr2;
274           int                 pos;
275           int                 chassis, geoslot;
276           unit_t    *u;
277 
278           empty_unit_table();
279           if ((fp = fopen("/etc/hosts", "r")) == NULL) {                                                                                              /* try to open the hosts file and if it fails */
280                     snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot open '/etc/hosts' for reading.");    /* return the nohostsfile error response */
281                     return -1;
282           }
283           while (fgets(buf, MAX_LINE_SIZE-1, fp)) {                             /* while looping over the file */
284 
285                     pos = strcspn(buf, "#\n\r");                                          /* find the first comment character or EOL */
286                     *(buf + pos) = '\0';                                                                      /* and clobber it and anything that follows it */
287 
288                     pos = strspn(buf, " \t");                                                       /* then find the first non-white space */
289                     if (pos == strlen(buf))                                                                   /* if there is nothing but white space on the line */
290                               continue;                                                                                 /* ignore that empty line */
291                     ptr = buf + pos;                                                                          /* and skip over any of that leading whitespace */
292 
293                     if ((ptr2 = strstr(ptr, "_I_")) == NULL)                    /* skip any lines that don't have names that look like they belong to IOPs */
294                               continue;
295                     if (*(ptr2 + 4) != '_')                                                                   /* and skip other lines that have names that don't look like ACN components */
296                               continue;
297                     *(ptr + strcspn(ptr, " \t")) = '\0';                        /* null terminate the IP address so its a standalone string */
298 
299                     chassis = *(ptr2 + 3) - '0';                                          /* extract the chassis number */
300                     geoslot = *(ptr2 + 5) - '0';                                          /* and geo-slot number */
301                     if (chassis < 1 || chassis > MAX_CHASSIS ||
302                               geoslot < 1 || geoslot > MAX_GEOSLOT) {           /* if the chassis and/or slot numbers appear to be bad... */
303                               snprintf(errbuf, PCAP_ERRBUF_SIZE, "Invalid ACN name in '/etc/hosts'.");        /* warn the user */
304                               continue;                                                                                                                                                                 /* and ignore the entry */
305                     }
306                     ptr2 = strdup(ptr);                                         /* copy the IP address into our malloc'ed memory */
307                     if (ptr2 == NULL) {
308                               pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
309                                   errno, "malloc");
310                               continue;
311                     }
312                     u = &units[chassis][geoslot];
313                     u->ip = ptr2;                                                                                       /* and remember the whole shebang */
314                     u->chassis = chassis;
315                     u->geoslot = geoslot;
316           }
317           fclose(fp);
318           if (*errbuf)        return -1;
319           else                          return 0;
320 }
321 
open_with_IOP(unit_t * u,int flag)322 static int open_with_IOP(unit_t  *u, int flag) {
323           int                                               sockfd;
324           char                                    *ip;
325 
326           if (u->serv_addr == NULL) {
327                     u->serv_addr = malloc(sizeof(struct sockaddr_in));
328 
329                     /* since we called malloc(), lets check to see if we actually got the memory    */
330                     if (u->serv_addr == NULL) {   /* oops, we didn't get the memory requested       */
331                               fprintf(stderr, "malloc() request for u->serv_addr failed, value of errno is: %d\n", errno);
332                               return 0;
333                     }
334 
335           }
336           ip = u->ip;
337           /* bzero() is deprecated, replaced with memset()  */
338           memset((char *)u->serv_addr, 0, sizeof(struct sockaddr_in));
339           u->serv_addr->sin_family                = AF_INET;
340           u->serv_addr->sin_addr.s_addr = inet_addr(ip);
341           u->serv_addr->sin_port                            = htons(IOP_SNIFFER_PORT);
342 
343           if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
344                     fprintf(stderr, "pcap can't open a socket for connecting to IOP at %s\n", ip);
345                     return 0;
346           }
347           if (connect(sockfd, (struct sockaddr *)u->serv_addr, sizeof(struct sockaddr_in)) < 0) {
348                     fprintf(stderr, "pcap can't connect to IOP at %s\n", ip);
349                     return 0;
350           }
351           if (flag == LIVE)   u->fd = sockfd;
352           else                                    u->find_fd = sockfd;
353           u->first_time = 0;
354           return sockfd;                          /* return the non-zero file descriptor as a 'success' indicator */
355 }
356 
close_with_IOP(int chassis,int geoslot,int flag)357 static void close_with_IOP(int chassis, int geoslot, int flag) {
358           int                 *id;
359 
360           if (flag == LIVE)   id = &units[chassis][geoslot].fd;
361           else                                    id = &units[chassis][geoslot].find_fd;
362 
363           if (*id) {                                                                                                    /* this was the last time, so... if we are connected... */
364                     close(*id);                                                                                         /* disconnect us */
365                     *id = 0;                                                                                  /* and forget that the descriptor exists because we are not open */
366           }
367 }
368 
pcap_cleanup_acn(pcap_t * handle)369 static void pcap_cleanup_acn(pcap_t *handle) {
370           int                 chassis, geoslot;
371           unit_t    *u;
372 
373           if (find_unit_by_fd(handle->fd, &chassis, &geoslot, &u) == 0)
374                     return;
375           close_with_IOP(chassis, geoslot, LIVE);
376           if (u)
377                     u->first_time = 0;
378           pcapint_cleanup_live_common(handle);
379 }
380 
send_to_fd(int fd,int len,unsigned char * str)381 static void send_to_fd(int fd, int len, unsigned char *str) {
382           int                 nwritten;
383           int                 chassis, geoslot;
384 
385           while (len > 0) {
386                     if ((nwritten = write(fd, str, len)) <= 0) {
387                               find_unit_by_fd(fd, &chassis, &geoslot, NULL);
388                               if (units[chassis][geoslot].fd == fd)                       close_with_IOP(chassis, geoslot, LIVE);
389                               else if (units[chassis][geoslot].find_fd == fd)   close_with_IOP(chassis, geoslot, FIND);
390                               empty_unit(chassis, geoslot);
391                               return;
392                     }
393                     len -= nwritten;
394                     str += nwritten;
395           }
396 }
397 
acn_freealldevs(void)398 static void acn_freealldevs(void) {
399 
400           pcap_if_t *iff, *next_iff;
401           pcap_addr_t         *addr, *next_addr;
402 
403           for (iff = acn_if_list; iff != NULL; iff = next_iff) {
404                     next_iff = iff->next;
405                     for (addr = iff->addresses; addr != NULL; addr = next_addr) {
406                               next_addr = addr->next;
407                               if (addr->addr)                         free(addr->addr);
408                               if (addr->netmask)            free(addr->netmask);
409                               if (addr->broadaddr)          free(addr->broadaddr);
410                               if (addr->dstaddr)            free(addr->dstaddr);
411                               free(addr);
412                     }
413                     if (iff->name)                          free(iff->name);
414                     if (iff->description)         free(iff->description);
415                     free(iff);
416           }
417 }
418 
nonUnified_IOP_port_name(char * buf,size_t bufsize,const char * proto,unit_t * u)419 static void nonUnified_IOP_port_name(char *buf, size_t bufsize, const char *proto, unit_t *u) {
420 
421           snprintf(buf, bufsize, "%s_%d_%d", proto, u->chassis, u->geoslot);
422 }
423 
unified_IOP_port_name(char * buf,size_t bufsize,const char * proto,unit_t * u,int IOPportnum)424 static void unified_IOP_port_name(char *buf, size_t bufsize, const char *proto, unit_t *u, int IOPportnum) {
425           int                           portnum;
426 
427           portnum = ((u->chassis - 1) * 64) + ((u->geoslot - 1) * 8) + IOPportnum + 1;
428           snprintf(buf, bufsize, "%s_%d", proto, portnum);
429 }
430 
translate_IOP_to_pcap_name(unit_t * u,char * IOPname,bpf_u_int32 iftype)431 static char *translate_IOP_to_pcap_name(unit_t *u, char *IOPname, bpf_u_int32 iftype) {
432           iface_t             *iface_ptr, *iface;
433           char                buf[32];
434           char                *proto;
435           char                *port;
436           int                           IOPportnum = 0;
437 
438           iface = malloc(sizeof(iface_t));                  /* get memory for a structure */
439           if (iface == NULL) {          /* oops, we didn't get the memory requested       */
440                     fprintf(stderr, "Error...couldn't allocate memory for interface structure...value of errno is: %d\n", errno);
441                     return NULL;
442           }
443           memset((char *)iface, 0, sizeof(iface_t));        /* bzero is deprecated(), replaced with memset() */
444 
445           iface->iftype = iftype;                                               /* remember the interface type of this interface */
446 
447           iface->IOPname = strdup(IOPname);                           /* copy it and stick it into the structure */
448         if (iface->IOPname == NULL) {    /* oops, we didn't get the memory requested     */
449                 fprintf(stderr, "Error...couldn't allocate memory for IOPname...value of errno is: %d\n", errno);
450                 return NULL;
451         }
452 
453           if (strncmp(IOPname, "lo", 2) == 0) {
454                     IOPportnum = atoi(&IOPname[2]);
455                     switch (iftype) {
456                               case DLT_EN10MB:
457                                         nonUnified_IOP_port_name(buf, sizeof buf, "lo", u);
458                                         break;
459                               default:
460                                         unified_IOP_port_name(buf, sizeof buf, "???", u, IOPportnum);
461                                         break;
462                     }
463           } else if (strncmp(IOPname, "eth", 3) == 0) {
464                     IOPportnum = atoi(&IOPname[3]);
465                     switch (iftype) {
466                               case DLT_EN10MB:
467                                         nonUnified_IOP_port_name(buf, sizeof buf, "eth", u);
468                                         break;
469                               default:
470                                         unified_IOP_port_name(buf, sizeof buf, "???", u, IOPportnum);
471                                         break;
472                     }
473           } else if (strncmp(IOPname, "wan", 3) == 0) {
474                     IOPportnum = atoi(&IOPname[3]);
475                     switch (iftype) {
476                               case DLT_SITA:
477                                         unified_IOP_port_name(buf, sizeof buf, "wan", u, IOPportnum);
478                                         break;
479                               default:
480                                         unified_IOP_port_name(buf, sizeof buf, "???", u, IOPportnum);
481                                         break;
482                     }
483           } else {
484                     fprintf(stderr, "Error... invalid IOP name %s\n", IOPname);
485                     return NULL;
486           }
487 
488           iface->name = strdup(buf);                                            /* make a copy and stick it into the structure */
489         if (iface->name == NULL) {    /* oops, we didn't get the memory requested     */
490                 fprintf(stderr, "Error...couldn't allocate memory for IOP port name...value of errno is: %d\n", errno);
491                 return NULL;
492         }
493 
494           if (u->iface == 0) {                                                  /* if this is the first name */
495                     u->iface = iface;                                           /* stick this entry at the head of the list */
496           } else {
497                     iface_ptr = u->iface;
498                     while (iface_ptr->next) {                         /* otherwise scan the list */
499                               iface_ptr = iface_ptr->next;  /* till we're at the last entry */
500                     }
501                     iface_ptr->next = iface;                          /* then tack this entry on the end of the list */
502           }
503           return iface->name;
504 }
505 
if_sort(char * s1,char * s2)506 static int if_sort(char *s1, char *s2) {
507           char      *s1_p2, *s2_p2;
508           char      str1[MAX_LINE_SIZE], str2[MAX_LINE_SIZE];
509           int                 s1_p1_len, s2_p1_len;
510           int                 retval;
511 
512           if ((s1_p2 = strchr(s1, '_'))) {        /* if an underscore is found... */
513                     s1_p1_len = s1_p2 - s1;                           /* the prefix length is the difference in pointers */
514                     s1_p2++;                                                    /* the suffix actually starts _after_ the underscore */
515           } else {                                                              /* otherwise... */
516                     s1_p1_len = strlen(s1);                           /* the prefix length is the length of the string itself */
517                     s1_p2 = 0;                                                            /* and there is no suffix */
518           }
519           if ((s2_p2 = strchr(s2, '_'))) {        /* now do the same for the second string */
520                     s2_p1_len = s2_p2 - s2;
521                     s2_p2++;
522           } else {
523                     s2_p1_len = strlen(s2);
524                     s2_p2 = 0;
525           }
526           strncpy(str1, s1, (s1_p1_len > sizeof(str1)) ? s1_p1_len : sizeof(str1));   *(str1 + s1_p1_len) = 0;
527           strncpy(str2, s2, (s2_p1_len > sizeof(str2)) ? s2_p1_len : sizeof(str2));   *(str2 + s2_p1_len) = 0;
528           retval = strcmp(str1, str2);
529           if (retval != 0) return retval;                   /* if they are not identical, then we can quit now and return the indication */
530           return strcmp(s1_p2, s2_p2);            /* otherwise we return the result of comparing the 2nd half of the string */
531 }
532 
sort_if_table(void)533 static void sort_if_table(void) {
534           pcap_if_t *p1, *p2, *prev, *temp;
535           int                           has_swapped;
536 
537           if (!acn_if_list) return;                                   /* nothing to do if the list is empty */
538 
539           while (1) {
540                     p1 = acn_if_list;                                           /* start at the head of the list */
541                     prev = 0;
542                     has_swapped = 0;
543                     while ((p2 = p1->next)) {
544                               if (if_sort(p1->name, p2->name) > 0) {
545                                         if (prev) {                                                 /* we are swapping things that are _not_ at the head of the list */
546                                                   temp = p2->next;
547                                                   prev->next = p2;
548                                                   p2->next = p1;
549                                                   p1->next = temp;
550                                         } else {                                          /* special treatment if we are swapping with the head of the list */
551                                                   temp = p2->next;
552                                                   acn_if_list= p2;
553                                                   p2->next = p1;
554                                                   p1->next = temp;
555                                         }
556                                         p1 = p2;
557                                         prev = p1;
558                                         has_swapped = 1;
559                               }
560                               prev = p1;
561                               p1 = p1->next;
562                     }
563                     if (has_swapped == 0)
564                               return;
565           }
566           return;
567 }
568 
process_client_data(char * errbuf)569 static int process_client_data (char *errbuf) {                                                                         /* returns: -1 = error, 0 = OK */
570           int                                               chassis, geoslot;
571           unit_t                                  *u;
572           pcap_if_t                     *iff, *prev_iff;
573           pcap_addr_t                             *addr, *prev_addr;
574           char                                    *ptr;
575           int                                               address_count;
576           struct sockaddr_in  *s;
577           char                                    *newname;
578           bpf_u_int32                                       interfaceType;
579           unsigned char                 flags;
580           void *bigger_buffer;
581 
582           prev_iff = 0;
583           for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
584                     for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {                                    /* now loop over all the devices */
585                               u = &units[chassis][geoslot];
586                               empty_unit_iface(u);
587                               ptr = u->imsg;                                                                                                                              /* point to the start of the msg for this IOP */
588                               while (ptr < (u->imsg + u->len)) {
589                                         if ((iff = malloc(sizeof(pcap_if_t))) == NULL) {
590                                                   pcapint_fmt_errmsg_for_errno(errbuf,
591                                                       PCAP_ERRBUF_SIZE, errno, "malloc");
592                                                   return -1;
593                                         }
594                                         memset((char *)iff, 0, sizeof(pcap_if_t)); /* bzero() is deprecated, replaced with memset() */
595                                         if (acn_if_list == 0)         acn_if_list = iff;                                          /* remember the head of the list */
596                                         if (prev_iff)                           prev_iff->next = iff;                                       /* insert a forward link */
597 
598                                         if (*ptr) {                                                                                                                                 /* if there is a count for the name */
599                                                   if ((iff->name = malloc(*ptr + 1)) == NULL) {                         /* get that amount of space */
600                                                             pcapint_fmt_errmsg_for_errno(errbuf,
601                                                                 PCAP_ERRBUF_SIZE, errno,
602                                                                 "malloc");
603                                                             return -1;
604                                                   }
605                                                   memcpy(iff->name, (ptr + 1), *ptr);                                                       /* copy the name into the malloc'ed space */
606                                                   *(iff->name + *ptr) = 0;                                                                            /* and null terminate the string */
607                                                   ptr += *ptr;                                                                                                            /* now move the pointer forwards by the length of the count plus the length of the string */
608                                         }
609                                         ptr++;
610 
611                                         if (*ptr) {                                                                                                                                 /* if there is a count for the description */
612                                                   if ((iff->description = malloc(*ptr + 1)) == NULL) {        /* get that amount of space */
613                                                             pcapint_fmt_errmsg_for_errno(errbuf,
614                                                                 PCAP_ERRBUF_SIZE, errno,
615                                                                 "malloc");
616                                                             return -1;
617                                                   }
618                                                   memcpy(iff->description, (ptr + 1), *ptr);                                      /* copy the name into the malloc'ed space */
619                                                   *(iff->description + *ptr) = 0;                                                                     /* and null terminate the string */
620                                                   ptr += *ptr;                                                                                                            /* now move the pointer forwards by the length of the count plus the length of the string */
621                                         }
622                                         ptr++;
623 
624                                         interfaceType = ntohl(*(bpf_u_int32 *)ptr);
625                                         ptr += 4;                                                                                                                         /* skip over the interface type */
626 
627                                         flags = *ptr++;
628                                         if (flags) iff->flags = PCAP_IF_LOOPBACK;                                                 /* if this is a loopback style interface, lets mark it as such */
629 
630                                         address_count = *ptr++;
631 
632                                         prev_addr = 0;
633                                         while (address_count--) {
634                                                   if ((addr = malloc(sizeof(pcap_addr_t))) == NULL) {
635                                                             pcapint_fmt_errmsg_for_errno(errbuf,
636                                                                 PCAP_ERRBUF_SIZE, errno,
637                                                                 "malloc");
638                                                             return -1;
639                                                   }
640                                                   memset((char *)addr, 0, sizeof(pcap_addr_t)); /* bzero() is deprecated, replaced with memset() */
641                                                   if (iff->addresses == 0) iff->addresses = addr;
642                                                   if (prev_addr) prev_addr->next = addr;                                                              /* insert a forward link */
643                                                   if (*ptr) {                                                                                                                                           /* if there is a count for the address */
644                                                             if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {               /* get that amount of space */
645                                                                       pcapint_fmt_errmsg_for_errno(errbuf,
646                                                                           PCAP_ERRBUF_SIZE,
647                                                                           errno, "malloc");
648                                                                       return -1;
649                                                             }
650                                                             memset((char *)s, 0, sizeof(struct sockaddr_in)); /* bzero() is deprecated, replaced with memset() */
651                                                             addr->addr = (struct sockaddr *)s;
652                                                             s->sin_family                 = AF_INET;
653                                                             s->sin_addr.s_addr  = *(bpf_u_int32 *)(ptr + 1);                      /* copy the address in */
654                                                             ptr += *ptr;                                                                                                  /* now move the pointer forwards according to the specified length of the address */
655                                                   }
656                                                   ptr++;                                                                                                                            /* then forwards one more for the 'length of the address' field */
657                                                   if (*ptr) {                                                                                                                       /* process any netmask */
658                                                             if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
659                                                                       pcapint_fmt_errmsg_for_errno(errbuf,
660                                                                           PCAP_ERRBUF_SIZE,
661                                                                           errno, "malloc");
662                                                                       return -1;
663                                                             }
664                                                             /* bzero() is deprecated, replaced with memset() */
665                                                             memset((char *)s, 0, sizeof(struct sockaddr_in));
666 
667                                                             addr->netmask = (struct sockaddr *)s;
668                                                             s->sin_family                 = AF_INET;
669                                                             s->sin_addr.s_addr  = *(bpf_u_int32*)(ptr + 1);
670                                                             ptr += *ptr;
671                                                   }
672                                                   ptr++;
673                                                   if (*ptr) {                                                                                                                       /* process any broadcast address */
674                                                             if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
675                                                                       pcapint_fmt_errmsg_for_errno(errbuf,
676                                                                           PCAP_ERRBUF_SIZE,
677                                                                           errno, "malloc");
678                                                                       return -1;
679                                                             }
680                                                             /* bzero() is deprecated, replaced with memset() */
681                                                             memset((char *)s, 0, sizeof(struct sockaddr_in));
682 
683                                                             addr->broadaddr = (struct sockaddr *)s;
684                                                             s->sin_family                 = AF_INET;
685                                                             s->sin_addr.s_addr  = *(bpf_u_int32*)(ptr + 1);
686                                                             ptr += *ptr;
687                                                   }
688                                                   ptr++;
689                                                   if (*ptr) {                                                                                                                       /* process any destination address */
690                                                             if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
691                                                                       pcapint_fmt_errmsg_for_errno(errbuf,
692                                                                           PCAP_ERRBUF_SIZE,
693                                                                           errno, "malloc");
694                                                                       return -1;
695                                                             }
696                                                             /* bzero() is deprecated, replaced with memset() */
697                                                             memset((char *)s, 0, sizeof(struct sockaddr_in));
698 
699                                                             addr->dstaddr = (struct sockaddr *)s;
700                                                             s->sin_family                 = AF_INET;
701                                                             s->sin_addr.s_addr  = *(bpf_u_int32*)(ptr + 1);
702                                                             ptr += *ptr;
703                                                   }
704                                                   ptr++;
705                                                   prev_addr = addr;
706                                         }
707                                         prev_iff = iff;
708 
709                                         newname = translate_IOP_to_pcap_name(u, iff->name, interfaceType);              /* add a translation entry and get a point to the mangled name */
710                                         bigger_buffer = realloc(iff->name, strlen(newname) + 1);
711                                         if (bigger_buffer == NULL) {  /* we now re-write the name stored in the interface list */
712                                                   pcapint_fmt_errmsg_for_errno(errbuf,
713                                                       PCAP_ERRBUF_SIZE, errno, "realloc");
714                                                   return -1;
715                                         }
716                                         iff->name = bigger_buffer;
717                                         strcpy(iff->name, newname);                                                                                                                 /* to this new name */
718                               }
719                     }
720           }
721           return 0;
722 }
723 
read_client_data(int fd)724 static int read_client_data (int fd) {
725           unsigned char       buf[256];
726           int                                     chassis, geoslot;
727           unit_t                        *u;
728           int                                     len;
729 
730           find_unit_by_fd(fd, &chassis, &geoslot, &u);
731 
732           if ((len = recv(fd, buf, sizeof(buf), 0)) <= 0)   return 0; /* read in whatever data was sent to us */
733 
734           if ((u->imsg = realloc(u->imsg, (u->len + len))) == NULL)   /* extend the buffer for the new data */
735                     return 0;
736           memcpy((u->imsg + u->len), buf, len);                                                     /* append the new data */
737           u->len += len;
738           return 1;
739 }
740 
wait_for_all_answers(void)741 static void wait_for_all_answers(void) {
742           int                 retval;
743           struct    timeval tv;
744           int                 fd;
745           int                 chassis, geoslot;
746 
747           tv.tv_sec = 2;
748           tv.tv_usec = 0;
749 
750           while (1) {
751                     int flag = 0;
752                     fd_set working_set;
753 
754                     for (fd = 0; fd <= max_fs; fd++) {                                                                            /* scan the list of descriptors we may be listening to */
755                               if (FD_ISSET(fd, &readfds)) flag = 1;                                                     /* and see if there are any still set */
756                     }
757                     if (flag == 0) return;                                                                                                            /* we are done, when they are all gone */
758 
759                     memcpy(&working_set, &readfds, sizeof(readfds));                                /* otherwise, we still have to listen for more stuff, till we timeout */
760                     retval = select(max_fs + 1, &working_set, NULL, NULL, &tv);
761                     if (retval == -1) {                                                                                                               /* an error occurred !!!!! */
762                               return;
763                     } else if (retval == 0) {                                                                                               /* timeout occurred, so process what we've got sofar and return */
764                               printf("timeout\n");
765                               return;
766                     } else {
767                               for (fd = 0; fd <= max_fs; fd++) {                                                                  /* scan the list of things to do, and do them */
768                                         if (FD_ISSET(fd, &working_set)) {
769                                                   if (read_client_data(fd) == 0) {                                                /* if the socket has closed */
770                                                             FD_CLR(fd, &readfds);                                                                     /* and descriptors we listen to for errors */
771                                                             find_unit_by_fd(fd, &chassis, &geoslot, NULL);
772                                                             close_with_IOP(chassis, geoslot, FIND);                     /* and close out connection to him */
773                                                   }
774                                         }
775                               }
776                     }
777           }
778 }
779 
get_error_response(int fd,char * errbuf)780 static char *get_error_response(int fd, char *errbuf) {               /* return a pointer on error, NULL on no error */
781           char      byte;
782           int                 len = 0;
783 
784           while (1) {
785                     recv(fd, &byte, 1, 0);                                                                    /* read another byte in */
786                     if (errbuf && (len++ < PCAP_ERRBUF_SIZE)) {                 /* and if there is still room in the buffer */
787                               *errbuf++ = byte;                                                               /* stick it in */
788                               *errbuf = '\0';                                                                           /* ensure the string is null terminated just in case we might exceed the buffer's size */
789                     }
790                     if (byte == '\0') {
791                               if (len > 1)        { return errbuf;    }
792                               else                          { return NULL;                }
793                     }
794           }
795 }
796 
acn_findalldevs(char * errbuf)797 int acn_findalldevs(char *errbuf) {                                                                           /* returns: -1 = error, 0 = OK */
798           int                 chassis, geoslot;
799           unit_t    *u;
800 
801           FD_ZERO(&readfds);
802           max_fs = 0;
803           for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
804                     for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
805                               u = &units[chassis][geoslot];
806                               if (u->ip && (open_with_IOP(u, FIND))) {                              /* connect to the remote IOP */
807                                         send_to_fd(u->find_fd, 1, (unsigned char *)"\0");
808                                         if (get_error_response(u->find_fd, errbuf))
809                                                   close_with_IOP(chassis, geoslot, FIND);
810                                         else {
811                                                   if (u->find_fd > max_fs)
812                                                             max_fs = u->find_fd;                                                                                /* remember the highest number currently in use */
813                                                   FD_SET(u->find_fd, &readfds);                                                   /* we are going to want to read this guy's response to */
814                                                   u->len = 0;
815                                                   send_to_fd(u->find_fd, 1, (unsigned char *)"Q");            /* this interface query request */
816                                         }
817                               }
818                     }
819           }
820           wait_for_all_answers();
821           if (process_client_data(errbuf))
822                     return -1;
823           sort_if_table();
824           return 0;
825 }
826 
pcap_stats_acn(pcap_t * handle,struct pcap_stat * ps)827 static int pcap_stats_acn(pcap_t *handle, struct pcap_stat *ps) {
828           unsigned char       buf[12];
829 
830           send_to_fd(handle->fd, 1, (unsigned char *)"S");                                                    /* send the get_stats command to the IOP */
831 
832           if (read_client_nbytes(handle->fd, sizeof(buf), buf) == -1) return -1;          /* try reading the required bytes */
833 
834           ps->ps_recv                   = ntohl(*(uint32_t *)&buf[0]);                                                                      /* break the buffer into its three 32 bit components */
835           ps->ps_drop                   = ntohl(*(uint32_t *)&buf[4]);
836           ps->ps_ifdrop       = ntohl(*(uint32_t *)&buf[8]);
837 
838           return 0;
839 }
840 
acn_open_live(const char * name,char * errbuf,int * linktype)841 static int acn_open_live(const char *name, char *errbuf, int *linktype) {                 /* returns 0 on error, else returns the file descriptor */
842           int                           chassis, geoslot;
843           unit_t              *u;
844           iface_t             *p;
845           pcap_if_list_t      devlist;
846 
847           pcapint_platform_finddevs(&devlist, errbuf);
848           for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {                                                                                                /* scan the table... */
849                     for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
850                               u = &units[chassis][geoslot];
851                               if (u->ip != NULL) {
852                                         p = u->iface;
853                                         while (p) {                                                                                                                                                                                   /* and all interfaces... */
854                                                   if (p->IOPname && p->name && (strcmp(p->name, name) == 0)) {                                        /* and if we found the interface we want... */
855                                                             *linktype = p->iftype;
856                                                             open_with_IOP(u, LIVE);                                                                                                                               /* start a connection with that IOP */
857                                                             send_to_fd(u->fd, strlen(p->IOPname)+1, (unsigned char *)p->IOPname); /* send the IOP's interface name, and a terminating null */
858                                                             if (get_error_response(u->fd, errbuf)) {
859                                                                       return -1;
860                                                             }
861                                                             return u->fd;                                                                                                                                                   /* and return that open descriptor */
862                                                   }
863                                                   p = p->next;
864                                         }
865                               }
866                     }
867           }
868           return -1;                                                                                                                                                                                                        /* if the interface wasn't found, return an error */
869 }
870 
acn_start_monitor(int fd,int snaplen,int timeout,int promiscuous,int direction)871 static void acn_start_monitor(int fd, int snaplen, int timeout, int promiscuous, int direction) {
872           unsigned char       buf[8];
873           unit_t                        *u;
874 
875           //printf("acn_start_monitor()\n");                                    // fulko
876           find_unit_by_fd(fd, NULL, NULL, &u);
877           if (u->first_time == 0) {
878                     buf[0]                                            = 'M';
879                     *(uint32_t *)&buf[1]          = htonl(snaplen);
880                     buf[5]                                            = timeout;
881                     buf[6]                                            = promiscuous;
882                     buf[7]                                            = direction;
883           //printf("acn_start_monitor() first time\n");                                   // fulko
884                     send_to_fd(fd, 8, buf);                                                                             /* send the start monitor command with its parameters to the IOP */
885                     u->first_time = 1;
886           }
887           //printf("acn_start_monitor() complete\n");                                     // fulko
888 }
889 
pcap_inject_acn(pcap_t * p,const void * buf _U_,int size _U_)890 static int pcap_inject_acn(pcap_t *p, const void *buf _U_, int size _U_) {
891           pcapint_strlcpy(p->errbuf, "Sending packets isn't supported on ACN adapters",
892               PCAP_ERRBUF_SIZE);
893           return (-1);
894 }
895 
pcap_setfilter_acn(pcap_t * handle,struct bpf_program * bpf)896 static int pcap_setfilter_acn(pcap_t *handle, struct bpf_program *bpf) {
897           int                                     fd = handle->fd;
898           int                                     count;
899           struct bpf_insn     *p;
900           uint16_t            shortInt;
901           uint32_t            longInt;
902 
903           send_to_fd(fd, 1, (unsigned char *)"F");                              /* BPF filter follows command */
904           count = bpf->bf_len;
905           longInt = htonl(count);
906           send_to_fd(fd, 4, (unsigned char *)&longInt);               /* send the instruction sequence count */
907           p = bpf->bf_insns;
908           while (count--) {                                                                                   /* followed by the list of instructions */
909                     shortInt = htons(p->code);
910                     longInt = htonl(p->k);
911                     send_to_fd(fd, 2, (unsigned char *)&shortInt);
912                     send_to_fd(fd, 1, (unsigned char *)&p->jt);
913                     send_to_fd(fd, 1, (unsigned char *)&p->jf);
914                     send_to_fd(fd, 4, (unsigned char *)&longInt);
915                     p++;
916           }
917           if (get_error_response(fd, NULL))
918                     return -1;
919           return 0;
920 }
921 
acn_read_n_bytes_with_timeout(pcap_t * handle,int count)922 static int acn_read_n_bytes_with_timeout(pcap_t *handle, int count) {
923           struct              timeval tv;
924           int                           retval, fd;
925           fd_set              r_fds;
926           fd_set              w_fds;
927           u_char              *bp;
928           int                           len = 0;
929           int                           offset = 0;
930 
931           tv.tv_sec = 5;
932           tv.tv_usec = 0;
933 
934           fd = handle->fd;
935           FD_ZERO(&r_fds);
936           FD_SET(fd, &r_fds);
937           memcpy(&w_fds, &r_fds, sizeof(r_fds));
938           bp = handle->bp;
939           while (count) {
940                     retval = select(fd + 1, &w_fds, NULL, NULL, &tv);
941                     if (retval == -1) {                                                                                                     /* an error occurred !!!!! */
942 //                            fprintf(stderr, "error during packet data read\n");
943                               return -1;                                                                                                    /* but we need to return a good indication to prevent unnecessary popups */
944                     } else if (retval == 0) {                                                                                     /* timeout occurred, so process what we've got sofar and return */
945 //                            fprintf(stderr, "timeout during packet data read\n");
946                               return -1;
947                     } else {
948                               if ((len = recv(fd, (bp + offset), count, 0)) <= 0) {
949 //                                      fprintf(stderr, "premature exit during packet data rx\n");
950                                         return -1;
951                               }
952                               count -= len;
953                               offset += len;
954                     }
955           }
956           return 0;
957 }
958 
pcap_read_acn(pcap_t * handle,int max_packets,pcap_handler callback,u_char * user)959 static int pcap_read_acn(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) {
960           #define HEADER_SIZE (4 * 4)
961           unsigned char                 packet_header[HEADER_SIZE];
962           struct pcap_pkthdr  pcap_header;
963 
964           //printf("pcap_read_acn()\n");                              // fulko
965           acn_start_monitor(handle->fd, handle->snapshot, handle->opt.timeout, handle->opt.promisc, handle->direction); /* maybe tell him to start monitoring */
966           //printf("pcap_read_acn() after start monitor\n");                              // fulko
967 
968           handle->bp = packet_header;
969           if (acn_read_n_bytes_with_timeout(handle, HEADER_SIZE) == -1) return 0;                             /* try to read a packet header in so we can get the sizeof the packet data */
970 
971           pcap_header.ts.tv_sec         = ntohl(*(uint32_t *)&packet_header[0]);                                        /* tv_sec */
972           pcap_header.ts.tv_usec        = ntohl(*(uint32_t *)&packet_header[4]);                                        /* tv_usec */
973           pcap_header.caplen            = ntohl(*(uint32_t *)&packet_header[8]);                                        /* caplen */
974           pcap_header.len                         = ntohl(*(uint32_t *)&packet_header[12]);                                       /* len */
975 
976           handle->bp = (u_char *)handle->buffer + handle->offset;                                                                                     /* start off the receive pointer at the right spot */
977           if (acn_read_n_bytes_with_timeout(handle, pcap_header.caplen) == -1) return 0;  /* then try to read in the rest of the data */
978 
979           callback(user, &pcap_header, handle->bp);                                                                                                   /* call the user supplied callback function */
980           return 1;
981 }
982 
pcap_activate_sita(pcap_t * handle)983 static int pcap_activate_sita(pcap_t *handle) {
984           int                 fd;
985 
986           if (handle->opt.rfmon) {
987                     /*
988                      * No monitor mode on SITA devices (they're not Wi-Fi
989                      * devices).
990                      */
991                     return PCAP_ERROR_RFMON_NOTSUP;
992           }
993 
994           /* Initialize some components of the pcap structure. */
995 
996           handle->inject_op = pcap_inject_acn;
997           handle->setfilter_op = pcap_setfilter_acn;
998           handle->setdirection_op = NULL; /* Not implemented */
999           handle->set_datalink_op = NULL;         /* can't change data link type */
1000           handle->getnonblock_op = pcapint_getnonblock_fd;
1001           handle->setnonblock_op = pcapint_setnonblock_fd;
1002           handle->cleanup_op = pcap_cleanup_acn;
1003           handle->read_op = pcap_read_acn;
1004           handle->stats_op = pcap_stats_acn;
1005 
1006           fd = acn_open_live(handle->opt.device, handle->errbuf,
1007               &handle->linktype);
1008           if (fd == -1)
1009                     return PCAP_ERROR;
1010 
1011           /*
1012            * Turn a negative snapshot value (invalid), a snapshot value of
1013            * 0 (unspecified), or a value bigger than the normal maximum
1014            * value, into the maximum allowed value.
1015            *
1016            * If some application really *needs* a bigger snapshot
1017            * length, we should just increase MAXIMUM_SNAPLEN.
1018            */
1019           if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
1020                     handle->snapshot = MAXIMUM_SNAPLEN;
1021 
1022           handle->fd = fd;
1023           handle->bufsize = handle->snapshot;
1024 
1025           /* Allocate the buffer */
1026 
1027           handle->buffer       = malloc(handle->bufsize + handle->offset);
1028           if (!handle->buffer) {
1029                     pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
1030                         errno, "malloc");
1031                     pcap_cleanup_acn(handle);
1032                     return PCAP_ERROR;
1033           }
1034 
1035           /*
1036            * "handle->fd" is a socket, so "select()" and "poll()"
1037            * should work on it.
1038            */
1039           handle->selectable_fd = handle->fd;
1040 
1041           return 0;
1042 }
1043 
pcapint_create_interface(const char * device _U_,char * ebuf)1044 pcap_t *pcapint_create_interface(const char *device _U_, char *ebuf) {
1045           pcap_t *p;
1046 
1047           p = PCAP_CREATE_COMMON(ebuf, struct pcap_sita);
1048           if (p == NULL)
1049                     return (NULL);
1050 
1051           p->activate_op = pcap_activate_sita;
1052           return (p);
1053 }
1054 
pcapint_platform_finddevs(pcap_if_list_t * devlistp,char * errbuf)1055 int pcapint_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf) {
1056 
1057           //printf("pcap_findalldevs()\n");                                     // fulko
1058 
1059           *alldevsp = 0;                                                                                                                    /* initialize the returned variables before we do anything */
1060           strcpy(errbuf, "");
1061           if (acn_parse_hosts_file(errbuf))                                                                   /* scan the hosts file for potential IOPs */
1062                     {
1063                     //printf("pcap_findalldevs() returning BAD after parse_hosts\n");                                   // fulko
1064                     return -1;
1065                     }
1066           //printf("pcap_findalldevs() got hostlist now finding devs\n");                                     // fulko
1067           if (acn_findalldevs(errbuf))                                                                        /* then ask the IOPs for their monitorable devices */
1068                     {
1069                     //printf("pcap_findalldevs() returning BAD after findalldevs\n");                                   // fulko
1070                     return -1;
1071                     }
1072           devlistp->beginning = acn_if_list;
1073           acn_if_list = 0;                                                                                                        /* then forget our list head, because someone will call pcap_freealldevs() to empty the malloc'ed stuff */
1074           //printf("pcap_findalldevs() returning ZERO OK\n");                                       // fulko
1075           return 0;
1076 }
1077 
1078 /*
1079  * Libpcap version string.
1080  */
1081 const char *
pcap_lib_version(void)1082 pcap_lib_version(void)
1083 {
1084           return PCAP_VERSION_STRING " (SITA-only)";
1085 }
1086