"Fossies" - the Fresh Open Source Software Archive

Member "libpcap-1.10.1/./pcap-npf.c" (7 Jun 2021, 64619 Bytes) of package /linux/misc/libpcap-1.10.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pcap-npf.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.10.0_vs_1.10.1.

    1 /*
    2  * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
    3  * Copyright (c) 2005 - 2010 CACE Technologies, Davis (California)
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  *
   10  * 1. Redistributions of source code must retain the above copyright
   11  * notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  * notice, this list of conditions and the following disclaimer in the
   14  * documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the Politecnico di Torino, CACE Technologies
   16  * nor the names of its contributors may be used to endorse or promote
   17  * products derived from this software without specific prior written
   18  * permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  *
   32  */
   33 
   34 #ifdef HAVE_CONFIG_H
   35 #include <config.h>
   36 #endif
   37 
   38 #include <errno.h>
   39 #define PCAP_DONT_INCLUDE_PCAP_BPF_H
   40 #include <Packet32.h>
   41 #include <pcap-int.h>
   42 #include <pcap/dlt.h>
   43 
   44 /*
   45  * XXX - Packet32.h defines bpf_program, so we can't include
   46  * <pcap/bpf.h>, which also defines it; that's why we define
   47  * PCAP_DONT_INCLUDE_PCAP_BPF_H,
   48  *
   49  * However, no header in the WinPcap or Npcap SDKs defines the
   50  * macros for BPF code, so we have to define them ourselves.
   51  */
   52 #define     BPF_RET     0x06
   53 #define     BPF_K       0x00
   54 
   55 /* Old-school MinGW have these headers in a different place.
   56  */
   57 #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
   58   #include <ddk/ntddndis.h>
   59   #include <ddk/ndis.h>
   60 #else
   61   #include <ntddndis.h>  /* MSVC/TDM-MinGW/MinGW64 */
   62 #endif
   63 
   64 #ifdef HAVE_DAG_API
   65   #include <dagnew.h>
   66   #include <dagapi.h>
   67 #endif /* HAVE_DAG_API */
   68 
   69 #include "diag-control.h"
   70 
   71 #include "pcap-airpcap.h"
   72 
   73 static int pcap_setfilter_npf(pcap_t *, struct bpf_program *);
   74 static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
   75 static int pcap_getnonblock_npf(pcap_t *);
   76 static int pcap_setnonblock_npf(pcap_t *, int);
   77 
   78 /*dimension of the buffer in the pcap_t structure*/
   79 #define WIN32_DEFAULT_USER_BUFFER_SIZE 256000
   80 
   81 /*dimension of the buffer in the kernel driver NPF */
   82 #define WIN32_DEFAULT_KERNEL_BUFFER_SIZE 1000000
   83 
   84 /* Equivalent to ntohs(), but a lot faster under Windows */
   85 #define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
   86 
   87 /*
   88  * Private data for capturing on WinPcap/Npcap devices.
   89  */
   90 struct pcap_win {
   91     ADAPTER *adapter;       /* the packet32 ADAPTER for the device */
   92     int nonblock;
   93     int rfmon_selfstart;        /* a flag tells whether the monitor mode is set by itself */
   94     int filtering_in_kernel;    /* using kernel filter */
   95 
   96 #ifdef HAVE_DAG_API
   97     int dag_fcs_bits;       /* Number of checksum bits from link layer */
   98 #endif
   99 
  100 #ifdef ENABLE_REMOTE
  101     int samp_npkt;          /* parameter needed for sampling, with '1 out of N' method has been requested */
  102     struct timeval samp_time;   /* parameter needed for sampling, with '1 every N ms' method has been requested */
  103 #endif
  104 };
  105 
  106 /*
  107  * Define stub versions of the monitor-mode support routines if this
  108  * isn't Npcap. HAVE_NPCAP_PACKET_API is defined by Npcap but not
  109  * WinPcap.
  110  */
  111 #ifndef HAVE_NPCAP_PACKET_API
  112 static int
  113 PacketIsMonitorModeSupported(PCHAR AdapterName _U_)
  114 {
  115     /*
  116      * We don't support monitor mode.
  117      */
  118     return (0);
  119 }
  120 
  121 static int
  122 PacketSetMonitorMode(PCHAR AdapterName _U_, int mode _U_)
  123 {
  124     /*
  125      * This should never be called, as PacketIsMonitorModeSupported()
  126      * will return 0, meaning "we don't support monitor mode, so
  127      * don't try to turn it on or off".
  128      */
  129     return (0);
  130 }
  131 
  132 static int
  133 PacketGetMonitorMode(PCHAR AdapterName _U_)
  134 {
  135     /*
  136      * This should fail, so that pcap_activate_npf() returns
  137      * PCAP_ERROR_RFMON_NOTSUP if our caller requested monitor
  138      * mode.
  139      */
  140     return (-1);
  141 }
  142 #endif
  143 
  144 /*
  145  * Sigh.  PacketRequest() will have made a DeviceIoControl()
  146  * call to the NPF driver to perform the OID request, with a
  147  * BIOCQUERYOID ioctl.  The kernel code should get back one
  148  * of NDIS_STATUS_INVALID_OID, NDIS_STATUS_NOT_SUPPORTED,
  149  * or NDIS_STATUS_NOT_RECOGNIZED if the OID request isn't
  150  * supported by the OS or the driver, but that doesn't seem
  151  * to make it to the caller of PacketRequest() in a
  152  * reliable fashion.
  153  */
  154 #define NDIS_STATUS_INVALID_OID     0xc0010017
  155 #define NDIS_STATUS_NOT_SUPPORTED   0xc00000bb  /* STATUS_NOT_SUPPORTED */
  156 #define NDIS_STATUS_NOT_RECOGNIZED  0x00010001
  157 
  158 static int
  159 oid_get_request(ADAPTER *adapter, bpf_u_int32 oid, void *data, size_t *lenp,
  160     char *errbuf)
  161 {
  162     PACKET_OID_DATA *oid_data_arg;
  163 
  164     /*
  165      * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
  166      * It should be big enough to hold "*lenp" bytes of data; it
  167      * will actually be slightly larger, as PACKET_OID_DATA has a
  168      * 1-byte data array at the end, standing in for the variable-length
  169      * data that's actually there.
  170      */
  171     oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
  172     if (oid_data_arg == NULL) {
  173         snprintf(errbuf, PCAP_ERRBUF_SIZE,
  174             "Couldn't allocate argument buffer for PacketRequest");
  175         return (PCAP_ERROR);
  176     }
  177 
  178     /*
  179      * No need to copy the data - we're doing a fetch.
  180      */
  181     oid_data_arg->Oid = oid;
  182     oid_data_arg->Length = (ULONG)(*lenp);  /* XXX - check for ridiculously large value? */
  183     if (!PacketRequest(adapter, FALSE, oid_data_arg)) {
  184         pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
  185             GetLastError(), "Error calling PacketRequest");
  186         free(oid_data_arg);
  187         return (-1);
  188     }
  189 
  190     /*
  191      * Get the length actually supplied.
  192      */
  193     *lenp = oid_data_arg->Length;
  194 
  195     /*
  196      * Copy back the data we fetched.
  197      */
  198     memcpy(data, oid_data_arg->Data, *lenp);
  199     free(oid_data_arg);
  200     return (0);
  201 }
  202 
  203 static int
  204 pcap_stats_npf(pcap_t *p, struct pcap_stat *ps)
  205 {
  206     struct pcap_win *pw = p->priv;
  207     struct bpf_stat bstats;
  208 
  209     /*
  210      * Try to get statistics.
  211      *
  212      * (Please note - "struct pcap_stat" is *not* the same as
  213      * WinPcap's "struct bpf_stat". It might currently have the
  214      * same layout, but let's not cheat.
  215      *
  216      * Note also that we don't fill in ps_capt, as we might have
  217      * been called by code compiled against an earlier version of
  218      * WinPcap that didn't have ps_capt, in which case filling it
  219      * in would stomp on whatever comes after the structure passed
  220      * to us.
  221      */
  222     if (!PacketGetStats(pw->adapter, &bstats)) {
  223         pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
  224             GetLastError(), "PacketGetStats error");
  225         return (-1);
  226     }
  227     ps->ps_recv = bstats.bs_recv;
  228     ps->ps_drop = bstats.bs_drop;
  229 
  230     /*
  231      * XXX - PacketGetStats() doesn't fill this in, so we just
  232      * return 0.
  233      */
  234 #if 0
  235     ps->ps_ifdrop = bstats.ps_ifdrop;
  236 #else
  237     ps->ps_ifdrop = 0;
  238 #endif
  239 
  240     return (0);
  241 }
  242 
  243 /*
  244  * Win32-only routine for getting statistics.
  245  *
  246  * This way is definitely safer than passing the pcap_stat * from the userland.
  247  * In fact, there could happen than the user allocates a variable which is not
  248  * big enough for the new structure, and the library will write in a zone
  249  * which is not allocated to this variable.
  250  *
  251  * In this way, we're pretty sure we are writing on memory allocated to this
  252  * variable.
  253  *
  254  * XXX - but this is the wrong way to handle statistics.  Instead, we should
  255  * have an API that returns data in a form like the Options section of a
  256  * pcapng Interface Statistics Block:
  257  *
  258  *    https://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.6
  259  *
  260  * which would let us add new statistics straightforwardly and indicate which
  261  * statistics we are and are *not* providing, rather than having to provide
  262  * possibly-bogus values for statistics we can't provide.
  263  */
  264 static struct pcap_stat *
  265 pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size)
  266 {
  267     struct pcap_win *pw = p->priv;
  268     struct bpf_stat bstats;
  269 
  270     *pcap_stat_size = sizeof (p->stat);
  271 
  272     /*
  273      * Try to get statistics.
  274      *
  275      * (Please note - "struct pcap_stat" is *not* the same as
  276      * WinPcap's "struct bpf_stat". It might currently have the
  277      * same layout, but let's not cheat.)
  278      */
  279     if (!PacketGetStatsEx(pw->adapter, &bstats)) {
  280         pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
  281             GetLastError(), "PacketGetStatsEx error");
  282         return (NULL);
  283     }
  284     p->stat.ps_recv = bstats.bs_recv;
  285     p->stat.ps_drop = bstats.bs_drop;
  286     p->stat.ps_ifdrop = bstats.ps_ifdrop;
  287     /*
  288      * Just in case this is ever compiled for a target other than
  289      * Windows, which is somewhere between extremely unlikely and
  290      * impossible.
  291      */
  292 #ifdef _WIN32
  293     p->stat.ps_capt = bstats.bs_capt;
  294 #endif
  295     return (&p->stat);
  296 }
  297 
  298 /* Set the dimension of the kernel-level capture buffer */
  299 static int
  300 pcap_setbuff_npf(pcap_t *p, int dim)
  301 {
  302     struct pcap_win *pw = p->priv;
  303 
  304     if(PacketSetBuff(pw->adapter,dim)==FALSE)
  305     {
  306         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
  307         return (-1);
  308     }
  309     return (0);
  310 }
  311 
  312 /* Set the driver working mode */
  313 static int
  314 pcap_setmode_npf(pcap_t *p, int mode)
  315 {
  316     struct pcap_win *pw = p->priv;
  317 
  318     if(PacketSetMode(pw->adapter,mode)==FALSE)
  319     {
  320         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
  321         return (-1);
  322     }
  323 
  324     return (0);
  325 }
  326 
  327 /*set the minimum amount of data that will release a read call*/
  328 static int
  329 pcap_setmintocopy_npf(pcap_t *p, int size)
  330 {
  331     struct pcap_win *pw = p->priv;
  332 
  333     if(PacketSetMinToCopy(pw->adapter, size)==FALSE)
  334     {
  335         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
  336         return (-1);
  337     }
  338     return (0);
  339 }
  340 
  341 static HANDLE
  342 pcap_getevent_npf(pcap_t *p)
  343 {
  344     struct pcap_win *pw = p->priv;
  345 
  346     return (PacketGetReadEvent(pw->adapter));
  347 }
  348 
  349 static int
  350 pcap_oid_get_request_npf(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp)
  351 {
  352     struct pcap_win *pw = p->priv;
  353 
  354     return (oid_get_request(pw->adapter, oid, data, lenp, p->errbuf));
  355 }
  356 
  357 static int
  358 pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data,
  359     size_t *lenp)
  360 {
  361     struct pcap_win *pw = p->priv;
  362     PACKET_OID_DATA *oid_data_arg;
  363 
  364     /*
  365      * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
  366      * It should be big enough to hold "*lenp" bytes of data; it
  367      * will actually be slightly larger, as PACKET_OID_DATA has a
  368      * 1-byte data array at the end, standing in for the variable-length
  369      * data that's actually there.
  370      */
  371     oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
  372     if (oid_data_arg == NULL) {
  373         snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
  374             "Couldn't allocate argument buffer for PacketRequest");
  375         return (PCAP_ERROR);
  376     }
  377 
  378     oid_data_arg->Oid = oid;
  379     oid_data_arg->Length = (ULONG)(*lenp);  /* XXX - check for ridiculously large value? */
  380     memcpy(oid_data_arg->Data, data, *lenp);
  381     if (!PacketRequest(pw->adapter, TRUE, oid_data_arg)) {
  382         pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
  383             GetLastError(), "Error calling PacketRequest");
  384         free(oid_data_arg);
  385         return (PCAP_ERROR);
  386     }
  387 
  388     /*
  389      * Get the length actually copied.
  390      */
  391     *lenp = oid_data_arg->Length;
  392 
  393     /*
  394      * No need to copy the data - we're doing a set.
  395      */
  396     free(oid_data_arg);
  397     return (0);
  398 }
  399 
  400 static u_int
  401 pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync)
  402 {
  403     struct pcap_win *pw = p->priv;
  404     u_int res;
  405 
  406     res = PacketSendPackets(pw->adapter,
  407         queue->buffer,
  408         queue->len,
  409         (BOOLEAN)sync);
  410 
  411     if(res != queue->len){
  412         pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
  413             GetLastError(), "Error queueing packets");
  414     }
  415 
  416     return (res);
  417 }
  418 
  419 static int
  420 pcap_setuserbuffer_npf(pcap_t *p, int size)
  421 {
  422     unsigned char *new_buff;
  423 
  424     if (size<=0) {
  425         /* Bogus parameter */
  426         snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
  427             "Error: invalid size %d",size);
  428         return (-1);
  429     }
  430 
  431     /* Allocate the buffer */
  432     new_buff=(unsigned char*)malloc(sizeof(char)*size);
  433 
  434     if (!new_buff) {
  435         snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
  436             "Error: not enough memory");
  437         return (-1);
  438     }
  439 
  440     free(p->buffer);
  441 
  442     p->buffer=new_buff;
  443     p->bufsize=size;
  444 
  445     return (0);
  446 }
  447 
  448 static int
  449 pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks)
  450 {
  451     struct pcap_win *pw = p->priv;
  452     BOOLEAN res;
  453 
  454     /* Set the packet driver in dump mode */
  455     res = PacketSetMode(pw->adapter, PACKET_MODE_DUMP);
  456     if(res == FALSE){
  457         snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
  458             "Error setting dump mode");
  459         return (-1);
  460     }
  461 
  462     /* Set the name of the dump file */
  463     res = PacketSetDumpName(pw->adapter, filename, (int)strlen(filename));
  464     if(res == FALSE){
  465         snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
  466             "Error setting kernel dump file name");
  467         return (-1);
  468     }
  469 
  470     /* Set the limits of the dump file */
  471     res = PacketSetDumpLimits(pw->adapter, maxsize, maxpacks);
  472     if(res == FALSE) {
  473         snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
  474                 "Error setting dump limit");
  475         return (-1);
  476     }
  477 
  478     return (0);
  479 }
  480 
  481 static int
  482 pcap_live_dump_ended_npf(pcap_t *p, int sync)
  483 {
  484     struct pcap_win *pw = p->priv;
  485 
  486     return (PacketIsDumpEnded(pw->adapter, (BOOLEAN)sync));
  487 }
  488 
  489 #ifdef HAVE_AIRPCAP_API
  490 static PAirpcapHandle
  491 pcap_get_airpcap_handle_npf(pcap_t *p)
  492 {
  493     struct pcap_win *pw = p->priv;
  494 
  495     return (PacketGetAirPcapHandle(pw->adapter));
  496 }
  497 #else /* HAVE_AIRPCAP_API */
  498 static PAirpcapHandle
  499 pcap_get_airpcap_handle_npf(pcap_t *p _U_)
  500 {
  501     return (NULL);
  502 }
  503 #endif /* HAVE_AIRPCAP_API */
  504 
  505 static int
  506 pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
  507 {
  508     PACKET Packet;
  509     int cc;
  510     int n;
  511     register u_char *bp, *ep;
  512     u_char *datap;
  513     struct pcap_win *pw = p->priv;
  514 
  515     cc = p->cc;
  516     if (cc == 0) {
  517         /*
  518          * Has "pcap_breakloop()" been called?
  519          */
  520         if (p->break_loop) {
  521             /*
  522              * Yes - clear the flag that indicates that it
  523              * has, and return PCAP_ERROR_BREAK to indicate
  524              * that we were told to break out of the loop.
  525              */
  526             p->break_loop = 0;
  527             return (PCAP_ERROR_BREAK);
  528         }
  529 
  530         /*
  531          * Capture the packets.
  532          *
  533          * The PACKET structure had a bunch of extra stuff for
  534          * Windows 9x/Me, but the only interesting data in it
  535          * in the versions of Windows that we support is just
  536          * a copy of p->buffer, a copy of p->buflen, and the
  537          * actual number of bytes read returned from
  538          * PacketReceivePacket(), none of which has to be
  539          * retained from call to call, so we just keep one on
  540          * the stack.
  541          */
  542         PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
  543         if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
  544             /*
  545              * Did the device go away?
  546              * If so, the error we get can either be
  547              * ERROR_GEN_FAILURE or ERROR_DEVICE_REMOVED.
  548              */
  549             DWORD errcode = GetLastError();
  550 
  551             if (errcode == ERROR_GEN_FAILURE ||
  552                 errcode == ERROR_DEVICE_REMOVED) {
  553                 /*
  554                  * The device on which we're capturing
  555                  * went away, or it became unusable
  556                  * by NPF due to a suspend/resume.
  557                  *
  558                  * ERROR_GEN_FAILURE comes from
  559                  * STATUS_UNSUCCESSFUL, as well as some
  560                  * other NT status codes that the Npcap
  561                  * driver is unlikely to return.
  562                  * XXX - hopefully no other error
  563                  * conditions are indicated by this.
  564                  *
  565                  * ERROR_DEVICE_REMOVED comes from
  566                  * STATUS_DEVICE_REMOVED.
  567                  *
  568                  * We report the Windows status code
  569                  * name and the corresponding NT status
  570                  * code name, for the benefit of attempts
  571                  * to debug cases where this error is
  572                  * reported when the device *wasn't*
  573                  * removed, either because it's not
  574                  * removable, it's removable but wasn't
  575                  * removed, or it's a device that doesn't
  576                  * correspond to a physical device.
  577                  *
  578                  * XXX - we really should return an
  579                  * appropriate error for that, but
  580                  * pcap_dispatch() etc. aren't
  581                  * documented as having error returns
  582                  * other than PCAP_ERROR or PCAP_ERROR_BREAK.
  583                  */
  584                 const char *errcode_msg;
  585 
  586                 if (errcode == ERROR_GEN_FAILURE)
  587                     errcode_msg = "ERROR_GEN_FAILURE/STATUS_UNSUCCESSFUL";
  588                 else
  589                     errcode_msg = "ERROR_DEVICE_REMOVED/STATUS_DEVICE_REMOVED";
  590                 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
  591                     "The interface disappeared (error code %s)",
  592                     errcode_msg);
  593             } else {
  594                 pcap_fmt_errmsg_for_win32_err(p->errbuf,
  595                     PCAP_ERRBUF_SIZE, errcode,
  596                     "PacketReceivePacket error");
  597             }
  598             return (PCAP_ERROR);
  599         }
  600 
  601         cc = Packet.ulBytesReceived;
  602 
  603         bp = p->buffer;
  604     }
  605     else
  606         bp = p->bp;
  607 
  608     /*
  609      * Loop through each packet.
  610      */
  611 #define bhp ((struct bpf_hdr *)bp)
  612     n = 0;
  613     ep = bp + cc;
  614     for (;;) {
  615         register u_int caplen, hdrlen;
  616 
  617         /*
  618          * Has "pcap_breakloop()" been called?
  619          * If so, return immediately - if we haven't read any
  620          * packets, clear the flag and return PCAP_ERROR_BREAK
  621          * to indicate that we were told to break out of the loop,
  622          * otherwise leave the flag set, so that the *next* call
  623          * will break out of the loop without having read any
  624          * packets, and return the number of packets we've
  625          * processed so far.
  626          */
  627         if (p->break_loop) {
  628             if (n == 0) {
  629                 p->break_loop = 0;
  630                 return (PCAP_ERROR_BREAK);
  631             } else {
  632                 p->bp = bp;
  633                 p->cc = (int) (ep - bp);
  634                 return (n);
  635             }
  636         }
  637         if (bp >= ep)
  638             break;
  639 
  640         caplen = bhp->bh_caplen;
  641         hdrlen = bhp->bh_hdrlen;
  642         datap = bp + hdrlen;
  643 
  644         /*
  645          * Short-circuit evaluation: if using BPF filter
  646          * in kernel, no need to do it now - we already know
  647          * the packet passed the filter.
  648          *
  649          * XXX - pcap_filter() should always return TRUE if
  650          * handed a null pointer for the program, but it might
  651          * just try to "run" the filter, so we check here.
  652          */
  653         if (pw->filtering_in_kernel ||
  654             p->fcode.bf_insns == NULL ||
  655             pcap_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
  656 #ifdef ENABLE_REMOTE
  657             switch (p->rmt_samp.method) {
  658 
  659             case PCAP_SAMP_1_EVERY_N:
  660                 pw->samp_npkt = (pw->samp_npkt + 1) % p->rmt_samp.value;
  661 
  662                 /* Discard all packets that are not '1 out of N' */
  663                 if (pw->samp_npkt != 0) {
  664                     bp += Packet_WORDALIGN(caplen + hdrlen);
  665                     continue;
  666                 }
  667                 break;
  668 
  669             case PCAP_SAMP_FIRST_AFTER_N_MS:
  670                 {
  671                 struct pcap_pkthdr *pkt_header = (struct pcap_pkthdr*) bp;
  672 
  673                 /*
  674                  * Check if the timestamp of the arrived
  675                  * packet is smaller than our target time.
  676                  */
  677                 if (pkt_header->ts.tv_sec < pw->samp_time.tv_sec ||
  678                    (pkt_header->ts.tv_sec == pw->samp_time.tv_sec && pkt_header->ts.tv_usec < pw->samp_time.tv_usec)) {
  679                     bp += Packet_WORDALIGN(caplen + hdrlen);
  680                     continue;
  681                 }
  682 
  683                 /*
  684                  * The arrived packet is suitable for being
  685                  * delivered to our caller, so let's update
  686                  * the target time.
  687                  */
  688                 pw->samp_time.tv_usec = pkt_header->ts.tv_usec + p->rmt_samp.value * 1000;
  689                 if (pw->samp_time.tv_usec > 1000000) {
  690                     pw->samp_time.tv_sec = pkt_header->ts.tv_sec + pw->samp_time.tv_usec / 1000000;
  691                     pw->samp_time.tv_usec = pw->samp_time.tv_usec % 1000000;
  692                 }
  693                 }
  694             }
  695 #endif  /* ENABLE_REMOTE */
  696 
  697             /*
  698              * XXX A bpf_hdr matches a pcap_pkthdr.
  699              */
  700             (*callback)(user, (struct pcap_pkthdr*)bp, datap);
  701             bp += Packet_WORDALIGN(caplen + hdrlen);
  702             if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) {
  703                 p->bp = bp;
  704                 p->cc = (int) (ep - bp);
  705                 return (n);
  706             }
  707         } else {
  708             /*
  709              * Skip this packet.
  710              */
  711             bp += Packet_WORDALIGN(caplen + hdrlen);
  712         }
  713     }
  714 #undef bhp
  715     p->cc = 0;
  716     return (n);
  717 }
  718 
  719 #ifdef HAVE_DAG_API
  720 static int
  721 pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
  722 {
  723     struct pcap_win *pw = p->priv;
  724     PACKET Packet;
  725     u_char *dp = NULL;
  726     int packet_len = 0, caplen = 0;
  727     struct pcap_pkthdr  pcap_header;
  728     u_char *endofbuf;
  729     int n = 0;
  730     dag_record_t *header;
  731     unsigned erf_record_len;
  732     ULONGLONG ts;
  733     int cc;
  734     unsigned swt;
  735     unsigned dfp = pw->adapter->DagFastProcess;
  736 
  737     cc = p->cc;
  738     if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
  739     {
  740         /*
  741          * Get new packets from the network.
  742          *
  743          * The PACKET structure had a bunch of extra stuff for
  744          * Windows 9x/Me, but the only interesting data in it
  745          * in the versions of Windows that we support is just
  746          * a copy of p->buffer, a copy of p->buflen, and the
  747          * actual number of bytes read returned from
  748          * PacketReceivePacket(), none of which has to be
  749          * retained from call to call, so we just keep one on
  750          * the stack.
  751          */
  752         PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
  753         if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
  754             snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
  755             return (-1);
  756         }
  757 
  758         cc = Packet.ulBytesReceived;
  759         if(cc == 0)
  760             /* The timeout has expired but we no packets arrived */
  761             return (0);
  762         header = (dag_record_t*)pw->adapter->DagBuffer;
  763     }
  764     else
  765         header = (dag_record_t*)p->bp;
  766 
  767     endofbuf = (char*)header + cc;
  768 
  769     /*
  770      * Cycle through the packets
  771      */
  772     do
  773     {
  774         erf_record_len = SWAPS(header->rlen);
  775         if((char*)header + erf_record_len > endofbuf)
  776             break;
  777 
  778         /* Increase the number of captured packets */
  779         p->stat.ps_recv++;
  780 
  781         /* Find the beginning of the packet */
  782         dp = ((u_char *)header) + dag_record_size;
  783 
  784         /* Determine actual packet len */
  785         switch(header->type)
  786         {
  787         case TYPE_ATM:
  788             packet_len = ATM_SNAPLEN;
  789             caplen = ATM_SNAPLEN;
  790             dp += 4;
  791 
  792             break;
  793 
  794         case TYPE_ETH:
  795             swt = SWAPS(header->wlen);
  796             packet_len = swt - (pw->dag_fcs_bits);
  797             caplen = erf_record_len - dag_record_size - 2;
  798             if (caplen > packet_len)
  799             {
  800                 caplen = packet_len;
  801             }
  802             dp += 2;
  803 
  804             break;
  805 
  806         case TYPE_HDLC_POS:
  807             swt = SWAPS(header->wlen);
  808             packet_len = swt - (pw->dag_fcs_bits);
  809             caplen = erf_record_len - dag_record_size;
  810             if (caplen > packet_len)
  811             {
  812                 caplen = packet_len;
  813             }
  814 
  815             break;
  816         }
  817 
  818         if(caplen > p->snapshot)
  819             caplen = p->snapshot;
  820 
  821         /*
  822          * Has "pcap_breakloop()" been called?
  823          * If so, return immediately - if we haven't read any
  824          * packets, clear the flag and return -2 to indicate
  825          * that we were told to break out of the loop, otherwise
  826          * leave the flag set, so that the *next* call will break
  827          * out of the loop without having read any packets, and
  828          * return the number of packets we've processed so far.
  829          */
  830         if (p->break_loop)
  831         {
  832             if (n == 0)
  833             {
  834                 p->break_loop = 0;
  835                 return (-2);
  836             }
  837             else
  838             {
  839                 p->bp = (char*)header;
  840                 p->cc = endofbuf - (char*)header;
  841                 return (n);
  842             }
  843         }
  844 
  845         if(!dfp)
  846         {
  847             /* convert between timestamp formats */
  848             ts = header->ts;
  849             pcap_header.ts.tv_sec = (int)(ts >> 32);
  850             ts = (ts & 0xffffffffi64) * 1000000;
  851             ts += 0x80000000; /* rounding */
  852             pcap_header.ts.tv_usec = (int)(ts >> 32);
  853             if (pcap_header.ts.tv_usec >= 1000000) {
  854                 pcap_header.ts.tv_usec -= 1000000;
  855                 pcap_header.ts.tv_sec++;
  856             }
  857         }
  858 
  859         /* No underlaying filtering system. We need to filter on our own */
  860         if (p->fcode.bf_insns)
  861         {
  862             if (pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0)
  863             {
  864                 /* Move to next packet */
  865                 header = (dag_record_t*)((char*)header + erf_record_len);
  866                 continue;
  867             }
  868         }
  869 
  870         /* Fill the header for the user suppplied callback function */
  871         pcap_header.caplen = caplen;
  872         pcap_header.len = packet_len;
  873 
  874         /* Call the callback function */
  875         (*callback)(user, &pcap_header, dp);
  876 
  877         /* Move to next packet */
  878         header = (dag_record_t*)((char*)header + erf_record_len);
  879 
  880         /* Stop if the number of packets requested by user has been reached*/
  881         if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
  882         {
  883             p->bp = (char*)header;
  884             p->cc = endofbuf - (char*)header;
  885             return (n);
  886         }
  887     }
  888     while((u_char*)header < endofbuf);
  889 
  890     return (1);
  891 }
  892 #endif /* HAVE_DAG_API */
  893 
  894 /* Send a packet to the network */
  895 static int
  896 pcap_inject_npf(pcap_t *p, const void *buf, int size)
  897 {
  898     struct pcap_win *pw = p->priv;
  899     PACKET pkt;
  900 
  901     PacketInitPacket(&pkt, (PVOID)buf, size);
  902     if(PacketSendPacket(pw->adapter,&pkt,TRUE) == FALSE) {
  903         pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
  904             GetLastError(), "send error: PacketSendPacket failed");
  905         return (-1);
  906     }
  907 
  908     /*
  909      * We assume it all got sent if "PacketSendPacket()" succeeded.
  910      * "pcap_inject()" is expected to return the number of bytes
  911      * sent.
  912      */
  913     return (size);
  914 }
  915 
  916 static void
  917 pcap_cleanup_npf(pcap_t *p)
  918 {
  919     struct pcap_win *pw = p->priv;
  920 
  921     if (pw->adapter != NULL) {
  922         PacketCloseAdapter(pw->adapter);
  923         pw->adapter = NULL;
  924     }
  925     if (pw->rfmon_selfstart)
  926     {
  927         PacketSetMonitorMode(p->opt.device, 0);
  928     }
  929     pcap_cleanup_live_common(p);
  930 }
  931 
  932 static void
  933 pcap_breakloop_npf(pcap_t *p)
  934 {
  935     pcap_breakloop_common(p);
  936     struct pcap_win *pw = p->priv;
  937 
  938     /* XXX - what if this fails? */
  939     SetEvent(PacketGetReadEvent(pw->adapter));
  940 }
  941 
  942 /*
  943  * Vendor-specific error codes.
  944  *
  945  * These are NTSTATUS values:
  946  *
  947  *    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/87fba13e-bf06-450e-83b1-9241dc81e781
  948  *
  949  * with the "Customer" bit set.  If a driver returns them, they are not
  950  * mapped to Windows error values in userland; they're returned by
  951  * GetLastError().
  952  *
  953  * Attempting to set non-promiscuous mode on a Microsoft Surface Pro's
  954  * Mobile Broadband Adapter returns an error; that error can safely be
  955  * ignored, as it's always in non-promiscuous mode.
  956  *
  957  * It is likely that there are other devices which throw spurious errors,
  958  * at which point this will need refactoring to efficiently check against
  959  * a list, but for now we can just check this one value.
  960  */
  961 #define NPF_SURFACE_MOBILE_NONPROMISC   0xe00000bb
  962 
  963 static int
  964 pcap_activate_npf(pcap_t *p)
  965 {
  966     struct pcap_win *pw = p->priv;
  967     NetType type;
  968     int res;
  969     int status = 0;
  970     struct bpf_insn total_insn;
  971     struct bpf_program total_prog;
  972 
  973     if (p->opt.rfmon) {
  974         /*
  975          * Monitor mode is supported on Windows Vista and later.
  976          */
  977         if (PacketGetMonitorMode(p->opt.device) == 1)
  978         {
  979             pw->rfmon_selfstart = 0;
  980         }
  981         else
  982         {
  983             if ((res = PacketSetMonitorMode(p->opt.device, 1)) != 1)
  984             {
  985                 pw->rfmon_selfstart = 0;
  986                 // Monitor mode is not supported.
  987                 if (res == 0)
  988                 {
  989                     return PCAP_ERROR_RFMON_NOTSUP;
  990                 }
  991                 else
  992                 {
  993                     return PCAP_ERROR;
  994                 }
  995             }
  996             else
  997             {
  998                 pw->rfmon_selfstart = 1;
  999             }
 1000         }
 1001     }
 1002 
 1003     /* Init Winsock if it hasn't already been initialized */
 1004     pcap_wsockinit();
 1005 
 1006     pw->adapter = PacketOpenAdapter(p->opt.device);
 1007 
 1008     if (pw->adapter == NULL)
 1009     {
 1010         DWORD errcode = GetLastError();
 1011 
 1012         /*
 1013          * What error did we get when trying to open the adapter?
 1014          */
 1015         switch (errcode) {
 1016 
 1017         case ERROR_BAD_UNIT:
 1018             /*
 1019              * There's no such device.
 1020              */
 1021             return (PCAP_ERROR_NO_SUCH_DEVICE);
 1022 
 1023         case ERROR_ACCESS_DENIED:
 1024             /*
 1025              * There is, but we don't have permission to
 1026              * use it.
 1027              */
 1028             return (PCAP_ERROR_PERM_DENIED);
 1029 
 1030         default:
 1031             /*
 1032              * Unknown - report details.
 1033              */
 1034             pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
 1035                 errcode, "Error opening adapter");
 1036             if (pw->rfmon_selfstart)
 1037             {
 1038                 PacketSetMonitorMode(p->opt.device, 0);
 1039             }
 1040             return (PCAP_ERROR);
 1041         }
 1042     }
 1043 
 1044     /*get network type*/
 1045     if(PacketGetNetType (pw->adapter,&type) == FALSE)
 1046     {
 1047         pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
 1048             GetLastError(), "Cannot determine the network type");
 1049         goto bad;
 1050     }
 1051 
 1052     /*Set the linktype*/
 1053     switch (type.LinkType)
 1054     {
 1055     case NdisMediumWan:
 1056         p->linktype = DLT_EN10MB;
 1057         break;
 1058 
 1059     case NdisMedium802_3:
 1060         p->linktype = DLT_EN10MB;
 1061         /*
 1062          * This is (presumably) a real Ethernet capture; give it a
 1063          * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
 1064          * that an application can let you choose it, in case you're
 1065          * capturing DOCSIS traffic that a Cisco Cable Modem
 1066          * Termination System is putting out onto an Ethernet (it
 1067          * doesn't put an Ethernet header onto the wire, it puts raw
 1068          * DOCSIS frames out on the wire inside the low-level
 1069          * Ethernet framing).
 1070          */
 1071         p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
 1072         /*
 1073          * If that fails, just leave the list empty.
 1074          */
 1075         if (p->dlt_list != NULL) {
 1076             p->dlt_list[0] = DLT_EN10MB;
 1077             p->dlt_list[1] = DLT_DOCSIS;
 1078             p->dlt_count = 2;
 1079         }
 1080         break;
 1081 
 1082     case NdisMediumFddi:
 1083         p->linktype = DLT_FDDI;
 1084         break;
 1085 
 1086     case NdisMedium802_5:
 1087         p->linktype = DLT_IEEE802;
 1088         break;
 1089 
 1090     case NdisMediumArcnetRaw:
 1091         p->linktype = DLT_ARCNET;
 1092         break;
 1093 
 1094     case NdisMediumArcnet878_2:
 1095         p->linktype = DLT_ARCNET;
 1096         break;
 1097 
 1098     case NdisMediumAtm:
 1099         p->linktype = DLT_ATM_RFC1483;
 1100         break;
 1101 
 1102     case NdisMediumCHDLC:
 1103         p->linktype = DLT_CHDLC;
 1104         break;
 1105 
 1106     case NdisMediumPPPSerial:
 1107         p->linktype = DLT_PPP_SERIAL;
 1108         break;
 1109 
 1110     case NdisMediumNull:
 1111         p->linktype = DLT_NULL;
 1112         break;
 1113 
 1114     case NdisMediumBare80211:
 1115         p->linktype = DLT_IEEE802_11;
 1116         break;
 1117 
 1118     case NdisMediumRadio80211:
 1119         p->linktype = DLT_IEEE802_11_RADIO;
 1120         break;
 1121 
 1122     case NdisMediumPpi:
 1123         p->linktype = DLT_PPI;
 1124         break;
 1125 
 1126     case NdisMediumWirelessWan:
 1127         p->linktype = DLT_RAW;
 1128         break;
 1129 
 1130     default:
 1131         /*
 1132          * An unknown medium type is assumed to supply Ethernet
 1133          * headers; if not, the user will have to report it,
 1134          * so that the medium type and link-layer header type
 1135          * can be determined.  If we were to fail here, we
 1136          * might get the link-layer type in the error, but
 1137          * the user wouldn't get a capture, so we wouldn't
 1138          * be able to determine the link-layer type; we report
 1139          * a warning with the link-layer type, so at least
 1140          * some programs will report the warning.
 1141          */
 1142         p->linktype = DLT_EN10MB;
 1143         snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
 1144             "Unknown NdisMedium value %d, defaulting to DLT_EN10MB",
 1145             type.LinkType);
 1146         status = PCAP_WARNING;
 1147         break;
 1148     }
 1149 
 1150 #ifdef HAVE_PACKET_GET_TIMESTAMP_MODES
 1151     /*
 1152      * Set the timestamp type.
 1153      * (Yes, we require PacketGetTimestampModes(), not just
 1154      * PacketSetTimestampMode().  If we have the former, we
 1155      * have the latter, unless somebody's using a version
 1156      * of Npcap that they've hacked to provide the former
 1157      * but not the latter; if they've done that, either
 1158      * they're confused or they're trolling us.)
 1159      */
 1160     switch (p->opt.tstamp_type) {
 1161 
 1162     case PCAP_TSTAMP_HOST_HIPREC_UNSYNCED:
 1163         /*
 1164          * Better than low-res, but *not* synchronized with
 1165          * the OS clock.
 1166          */
 1167         if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_SINGLE_SYNCHRONIZATION))
 1168         {
 1169             pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
 1170                 GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_SINGLE_SYNCHRONIZATION");
 1171             goto bad;
 1172         }
 1173         break;
 1174 
 1175     case PCAP_TSTAMP_HOST_LOWPREC:
 1176         /*
 1177          * Low-res, but synchronized with the OS clock.
 1178          */
 1179         if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_QUERYSYSTEMTIME))
 1180         {
 1181             pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
 1182                 GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_QUERYSYSTEMTIME");
 1183             goto bad;
 1184         }
 1185         break;
 1186 
 1187     case PCAP_TSTAMP_HOST_HIPREC:
 1188         /*
 1189          * High-res, and synchronized with the OS clock.
 1190          */
 1191         if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE))
 1192         {
 1193             pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
 1194                 GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE");
 1195             goto bad;
 1196         }
 1197         break;
 1198 
 1199     case PCAP_TSTAMP_HOST:
 1200         /*
 1201          * XXX - do whatever the default is, for now.
 1202          * Set to the highest resolution that's synchronized
 1203          * with the system clock?
 1204          */
 1205         break;
 1206     }
 1207 #endif /* HAVE_PACKET_GET_TIMESTAMP_MODES */
 1208 
 1209     /*
 1210      * Turn a negative snapshot value (invalid), a snapshot value of
 1211      * 0 (unspecified), or a value bigger than the normal maximum
 1212      * value, into the maximum allowed value.
 1213      *
 1214      * If some application really *needs* a bigger snapshot
 1215      * length, we should just increase MAXIMUM_SNAPLEN.
 1216      */
 1217     if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
 1218         p->snapshot = MAXIMUM_SNAPLEN;
 1219 
 1220     /* Set promiscuous mode */
 1221     if (p->opt.promisc)
 1222     {
 1223 
 1224         if (PacketSetHwFilter(pw->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
 1225         {
 1226             DWORD errcode = GetLastError();
 1227 
 1228             /*
 1229              * Suppress spurious error generated by non-compiant
 1230              * MS Surface mobile adapters.
 1231              *
 1232              * If we knew that this meant "promiscuous mode
 1233              * isn't supported", we could add a "promiscuous
 1234              * mode isn't supported" error code and return
 1235              * that, but:
 1236              *
 1237              *    1) we don't know that it means that
 1238              *    rather than meaning "we reject attempts
 1239              *    to set the filter, even though the NDIS
 1240              *    specifications say you shouldn't do that"
 1241              *
 1242              * and
 1243              *
 1244              *    2) other interface types that don't
 1245              *    support promiscuous mode, at least
 1246              *    on UN*Xes, just silently ignore
 1247              *    attempts to set promiscuous mode
 1248              *
 1249              * and rejecting it with an error could disrupt
 1250              * attempts to capture, as many programs (tcpdump,
 1251              * *shark) default to promiscuous mode.
 1252              */
 1253             if (errcode != NPF_SURFACE_MOBILE_NONPROMISC)
 1254             {
 1255                 pcap_fmt_errmsg_for_win32_err(p->errbuf,
 1256                     PCAP_ERRBUF_SIZE, errcode,
 1257                     "failed to set hardware filter to promiscuous mode");
 1258                 goto bad;
 1259             }
 1260         }
 1261     }
 1262     else
 1263     {
 1264         /*
 1265          * NDIS_PACKET_TYPE_ALL_LOCAL selects "All packets sent by
 1266          * installed protocols and all packets indicated by the NIC",
 1267          * but if no protocol drivers (like TCP/IP) are installed,
 1268          * NDIS_PACKET_TYPE_DIRECTED, NDIS_PACKET_TYPE_BROADCAST,
 1269          * and NDIS_PACKET_TYPE_MULTICAST are needed to capture
 1270          * incoming frames.
 1271          */
 1272         if (PacketSetHwFilter(pw->adapter,
 1273             NDIS_PACKET_TYPE_ALL_LOCAL |
 1274             NDIS_PACKET_TYPE_DIRECTED |
 1275             NDIS_PACKET_TYPE_BROADCAST |
 1276             NDIS_PACKET_TYPE_MULTICAST) == FALSE)
 1277         {
 1278             DWORD errcode = GetLastError();
 1279 
 1280             /*
 1281              * Suppress spurious error generated by non-compiant
 1282              * MS Surface mobile adapters.
 1283              */
 1284             if (errcode != NPF_SURFACE_MOBILE_NONPROMISC)
 1285             {
 1286                 pcap_fmt_errmsg_for_win32_err(p->errbuf,
 1287                     PCAP_ERRBUF_SIZE, errcode,
 1288                     "failed to set hardware filter to non-promiscuous mode");
 1289                 goto bad;
 1290             }
 1291         }
 1292     }
 1293 
 1294     /* Set the buffer size */
 1295     p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
 1296 
 1297     if(!(pw->adapter->Flags & INFO_FLAG_DAG_CARD))
 1298     {
 1299     /*
 1300      * Traditional Adapter
 1301      */
 1302         /*
 1303          * If the buffer size wasn't explicitly set, default to
 1304          * WIN32_DEFAULT_KERNEL_BUFFER_SIZE.
 1305          */
 1306         if (p->opt.buffer_size == 0)
 1307             p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;
 1308 
 1309         if(PacketSetBuff(pw->adapter,p->opt.buffer_size)==FALSE)
 1310         {
 1311             snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
 1312             goto bad;
 1313         }
 1314 
 1315         p->buffer = malloc(p->bufsize);
 1316         if (p->buffer == NULL)
 1317         {
 1318             pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
 1319                 errno, "malloc");
 1320             goto bad;
 1321         }
 1322 
 1323         if (p->opt.immediate)
 1324         {
 1325             /* tell the driver to copy the buffer as soon as data arrives */
 1326             if(PacketSetMinToCopy(pw->adapter,0)==FALSE)
 1327             {
 1328                 pcap_fmt_errmsg_for_win32_err(p->errbuf,
 1329                     PCAP_ERRBUF_SIZE, GetLastError(),
 1330                     "Error calling PacketSetMinToCopy");
 1331                 goto bad;
 1332             }
 1333         }
 1334         else
 1335         {
 1336             /* tell the driver to copy the buffer only if it contains at least 16K */
 1337             if(PacketSetMinToCopy(pw->adapter,16000)==FALSE)
 1338             {
 1339                 pcap_fmt_errmsg_for_win32_err(p->errbuf,
 1340                     PCAP_ERRBUF_SIZE, GetLastError(),
 1341                     "Error calling PacketSetMinToCopy");
 1342                 goto bad;
 1343             }
 1344         }
 1345     } else {
 1346         /*
 1347          * Dag Card
 1348          */
 1349 #ifdef HAVE_DAG_API
 1350         /*
 1351          * We have DAG support.
 1352          */
 1353         LONG    status;
 1354         HKEY    dagkey;
 1355         DWORD   lptype;
 1356         DWORD   lpcbdata;
 1357         int     postype = 0;
 1358         char    keyname[512];
 1359 
 1360         snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
 1361             "SYSTEM\\CurrentControlSet\\Services\\DAG",
 1362             strstr(_strlwr(p->opt.device), "dag"));
 1363         do
 1364         {
 1365             status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
 1366             if(status != ERROR_SUCCESS)
 1367                 break;
 1368 
 1369             status = RegQueryValueEx(dagkey,
 1370                 "PosType",
 1371                 NULL,
 1372                 &lptype,
 1373                 (char*)&postype,
 1374                 &lpcbdata);
 1375 
 1376             if(status != ERROR_SUCCESS)
 1377             {
 1378                 postype = 0;
 1379             }
 1380 
 1381             RegCloseKey(dagkey);
 1382         }
 1383         while(FALSE);
 1384 
 1385 
 1386         p->snapshot = PacketSetSnapLen(pw->adapter, p->snapshot);
 1387 
 1388         /* Set the length of the FCS associated to any packet. This value
 1389          * will be subtracted to the packet length */
 1390         pw->dag_fcs_bits = pw->adapter->DagFcsLen;
 1391 #else /* HAVE_DAG_API */
 1392         /*
 1393          * No DAG support.
 1394          */
 1395         goto bad;
 1396 #endif /* HAVE_DAG_API */
 1397     }
 1398 
 1399     /*
 1400      * If there's no filter program installed, there's
 1401      * no indication to the kernel of what the snapshot
 1402      * length should be, so no snapshotting is done.
 1403      *
 1404      * Therefore, when we open the device, we install
 1405      * an "accept everything" filter with the specified
 1406      * snapshot length.
 1407      */
 1408     total_insn.code = (u_short)(BPF_RET | BPF_K);
 1409     total_insn.jt = 0;
 1410     total_insn.jf = 0;
 1411     total_insn.k = p->snapshot;
 1412 
 1413     total_prog.bf_len = 1;
 1414     total_prog.bf_insns = &total_insn;
 1415     if (!PacketSetBpf(pw->adapter, &total_prog)) {
 1416         pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
 1417             GetLastError(), "PacketSetBpf");
 1418         status = PCAP_ERROR;
 1419         goto bad;
 1420     }
 1421 
 1422     PacketSetReadTimeout(pw->adapter, p->opt.timeout);
 1423 
 1424     /* disable loopback capture if requested */
 1425     if (p->opt.nocapture_local)
 1426     {
 1427         if (!PacketSetLoopbackBehavior(pw->adapter, NPF_DISABLE_LOOPBACK))
 1428         {
 1429             snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
 1430                 "Unable to disable the capture of loopback packets.");
 1431             goto bad;
 1432         }
 1433     }
 1434 
 1435 #ifdef HAVE_DAG_API
 1436     if(pw->adapter->Flags & INFO_FLAG_DAG_CARD)
 1437     {
 1438         /* install dag specific handlers for read and setfilter */
 1439         p->read_op = pcap_read_win32_dag;
 1440         p->setfilter_op = pcap_setfilter_win32_dag;
 1441     }
 1442     else
 1443     {
 1444 #endif /* HAVE_DAG_API */
 1445         /* install traditional npf handlers for read and setfilter */
 1446         p->read_op = pcap_read_npf;
 1447         p->setfilter_op = pcap_setfilter_npf;
 1448 #ifdef HAVE_DAG_API
 1449     }
 1450 #endif /* HAVE_DAG_API */
 1451     p->setdirection_op = NULL;  /* Not implemented. */
 1452         /* XXX - can this be implemented on some versions of Windows? */
 1453     p->inject_op = pcap_inject_npf;
 1454     p->set_datalink_op = NULL;  /* can't change data link type */
 1455     p->getnonblock_op = pcap_getnonblock_npf;
 1456     p->setnonblock_op = pcap_setnonblock_npf;
 1457     p->stats_op = pcap_stats_npf;
 1458     p->breakloop_op = pcap_breakloop_npf;
 1459     p->stats_ex_op = pcap_stats_ex_npf;
 1460     p->setbuff_op = pcap_setbuff_npf;
 1461     p->setmode_op = pcap_setmode_npf;
 1462     p->setmintocopy_op = pcap_setmintocopy_npf;
 1463     p->getevent_op = pcap_getevent_npf;
 1464     p->oid_get_request_op = pcap_oid_get_request_npf;
 1465     p->oid_set_request_op = pcap_oid_set_request_npf;
 1466     p->sendqueue_transmit_op = pcap_sendqueue_transmit_npf;
 1467     p->setuserbuffer_op = pcap_setuserbuffer_npf;
 1468     p->live_dump_op = pcap_live_dump_npf;
 1469     p->live_dump_ended_op = pcap_live_dump_ended_npf;
 1470     p->get_airpcap_handle_op = pcap_get_airpcap_handle_npf;
 1471     p->cleanup_op = pcap_cleanup_npf;
 1472 
 1473     /*
 1474      * XXX - this is only done because WinPcap supported
 1475      * pcap_fileno() returning the hFile HANDLE from the
 1476      * ADAPTER structure.  We make no general guarantees
 1477      * that the caller can do anything useful with it.
 1478      *
 1479      * (Not that we make any general guarantee of that
 1480      * sort on UN*X, either, any more, given that not
 1481      * all capture devices are regular OS network
 1482      * interfaces.)
 1483      */
 1484     p->handle = pw->adapter->hFile;
 1485 
 1486     return (status);
 1487 bad:
 1488     pcap_cleanup_npf(p);
 1489     return (PCAP_ERROR);
 1490 }
 1491 
 1492 /*
 1493 * Check if rfmon mode is supported on the pcap_t for Windows systems.
 1494 */
 1495 static int
 1496 pcap_can_set_rfmon_npf(pcap_t *p)
 1497 {
 1498     return (PacketIsMonitorModeSupported(p->opt.device) == 1);
 1499 }
 1500 
 1501 pcap_t *
 1502 pcap_create_interface(const char *device _U_, char *ebuf)
 1503 {
 1504     pcap_t *p;
 1505 #ifdef HAVE_PACKET_GET_TIMESTAMP_MODES
 1506     char *device_copy;
 1507     ADAPTER *adapter;
 1508     ULONG num_ts_modes;
 1509     BOOL ret;
 1510     DWORD error;
 1511     ULONG *modes;
 1512 #endif
 1513 
 1514     p = PCAP_CREATE_COMMON(ebuf, struct pcap_win);
 1515     if (p == NULL)
 1516         return (NULL);
 1517 
 1518     p->activate_op = pcap_activate_npf;
 1519     p->can_set_rfmon_op = pcap_can_set_rfmon_npf;
 1520 
 1521 #ifdef HAVE_PACKET_GET_TIMESTAMP_MODES
 1522     /*
 1523      * First, find out how many time stamp modes we have.
 1524      * To do that, we have to open the adapter.
 1525      *
 1526      * XXX - PacketOpenAdapter() takes a non-const pointer
 1527      * as an argument, so we make a copy of the argument and
 1528      * pass that to it.
 1529      */
 1530     device_copy = strdup(device);
 1531     adapter = PacketOpenAdapter(device_copy);
 1532     free(device_copy);
 1533     if (adapter != NULL)
 1534     {
 1535         /*
 1536          * Get the total number of time stamp modes.
 1537          *
 1538          * The buffer for PacketGetTimestampModes() is
 1539          * a sequence of 1 or more ULONGs.  What's
 1540          * passed to PacketGetTimestampModes() should have
 1541          * the total number of ULONGs in the first ULONG;
 1542          * what's returned *from* PacketGetTimestampModes()
 1543          * has the total number of time stamp modes in
 1544          * the first ULONG.
 1545          *
 1546          * Yes, that means if there are N time stamp
 1547          * modes, the first ULONG should be set to N+1
 1548          * on input, and will be set to N on output.
 1549          *
 1550          * We first make a call to PacketGetTimestampModes()
 1551          * with a pointer to a single ULONG set to 1; the
 1552          * call should fail with ERROR_MORE_DATA (unless
 1553          * there are *no* modes, but that should never
 1554          * happen), and that ULONG should be set to the
 1555          * number of modes.
 1556          */
 1557         num_ts_modes = 1;
 1558         ret = PacketGetTimestampModes(adapter, &num_ts_modes);
 1559         if (!ret) {
 1560             /*
 1561              * OK, it failed.  Did it fail with
 1562              * ERROR_MORE_DATA?
 1563              */
 1564             error = GetLastError();
 1565             if (error != ERROR_MORE_DATA) {
 1566                 /*
 1567                  * No, some other error.  Fail.
 1568                  */
 1569                 pcap_fmt_errmsg_for_win32_err(ebuf,
 1570                     PCAP_ERRBUF_SIZE, GetLastError(),
 1571                     "Error calling PacketGetTimestampModes");
 1572                 pcap_close(p);
 1573                 return (NULL);
 1574             }
 1575 
 1576             /*
 1577              * Yes, so we now know how many types to fetch.
 1578              *
 1579                  * The buffer needs to have one ULONG for the
 1580                  * count and num_ts_modes ULONGs for the
 1581                  * num_ts_modes time stamp types.
 1582                  */
 1583             modes = (ULONG *)malloc((1 + num_ts_modes) * sizeof(ULONG));
 1584             if (modes == NULL) {
 1585                 /* Out of memory. */
 1586                 /* XXX SET ebuf */
 1587                 pcap_close(p);
 1588                 return (NULL);
 1589             }
 1590             modes[0] = 1 + num_ts_modes;
 1591             if (!PacketGetTimestampModes(adapter, modes)) {
 1592                 pcap_fmt_errmsg_for_win32_err(ebuf,
 1593                     PCAP_ERRBUF_SIZE, GetLastError(),
 1594                     "Error calling PacketGetTimestampModes");
 1595                 free(modes);
 1596                 pcap_close(p);
 1597                 return (NULL);
 1598             }
 1599             if (modes[0] != num_ts_modes) {
 1600                 snprintf(ebuf, PCAP_ERRBUF_SIZE,
 1601                     "First PacketGetTimestampModes() call gives %lu modes, second call gives %lu modes",
 1602                     num_ts_modes, modes[0]);
 1603                 free(modes);
 1604                 pcap_close(p);
 1605                 return (NULL);
 1606             }
 1607             if (num_ts_modes != 0) {
 1608                 u_int num_ts_types;
 1609 
 1610                 /*
 1611                  * Allocate a buffer big enough for
 1612                  * PCAP_TSTAMP_HOST (default) plus
 1613                  * the explicitly specified modes.
 1614                  */
 1615                 p->tstamp_type_list = malloc((1 + modes[0]) * sizeof(u_int));
 1616                 if (p->tstamp_type_list == NULL) {
 1617                     /* XXX SET ebuf */
 1618                     free(modes);
 1619                     pcap_close(p);
 1620                     return (NULL);
 1621                 }
 1622                 num_ts_types = 0;
 1623                 p->tstamp_type_list[num_ts_types] =
 1624                     PCAP_TSTAMP_HOST;
 1625                 num_ts_types++;
 1626                 for (ULONG i = 0; i < modes[0]; i++) {
 1627                     switch (modes[i + 1]) {
 1628 
 1629                     case TIMESTAMPMODE_SINGLE_SYNCHRONIZATION:
 1630                         /*
 1631                          * Better than low-res,
 1632                          * but *not* synchronized
 1633                          * with the OS clock.
 1634                          */
 1635                         p->tstamp_type_list[num_ts_types] =
 1636                             PCAP_TSTAMP_HOST_HIPREC_UNSYNCED;
 1637                         num_ts_types++;
 1638                         break;
 1639 
 1640                     case TIMESTAMPMODE_QUERYSYSTEMTIME:
 1641                         /*
 1642                          * Low-res, but synchronized
 1643                          * with the OS clock.
 1644                          */
 1645                         p->tstamp_type_list[num_ts_types] =
 1646                             PCAP_TSTAMP_HOST_LOWPREC;
 1647                         num_ts_types++;
 1648                         break;
 1649 
 1650                     case TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE:
 1651                         /*
 1652                          * High-res, and synchronized
 1653                          * with the OS clock.
 1654                          */
 1655                         p->tstamp_type_list[num_ts_types] =
 1656                             PCAP_TSTAMP_HOST_HIPREC;
 1657                         num_ts_types++;
 1658                         break;
 1659 
 1660                     default:
 1661                         /*
 1662                          * Unknown, so we can't
 1663                          * report it.
 1664                          */
 1665                         break;
 1666                     }
 1667                 }
 1668                 p->tstamp_type_count = num_ts_types;
 1669                 free(modes);
 1670             }
 1671         }
 1672         PacketCloseAdapter(adapter);
 1673     }
 1674 #endif /* HAVE_PACKET_GET_TIMESTAMP_MODES */
 1675 
 1676     return (p);
 1677 }
 1678 
 1679 static int
 1680 pcap_setfilter_npf(pcap_t *p, struct bpf_program *fp)
 1681 {
 1682     struct pcap_win *pw = p->priv;
 1683 
 1684     if(PacketSetBpf(pw->adapter,fp)==FALSE){
 1685         /*
 1686          * Kernel filter not installed.
 1687          *
 1688          * XXX - we don't know whether this failed because:
 1689          *
 1690          *  the kernel rejected the filter program as invalid,
 1691          *  in which case we should fall back on userland
 1692          *  filtering;
 1693          *
 1694          *  the kernel rejected the filter program as too big,
 1695          *  in which case we should again fall back on
 1696          *  userland filtering;
 1697          *
 1698          *  there was some other problem, in which case we
 1699          *  should probably report an error.
 1700          *
 1701          * For NPF devices, the Win32 status will be
 1702          * STATUS_INVALID_DEVICE_REQUEST for invalid
 1703          * filters, but I don't know what it'd be for
 1704          * other problems, and for some other devices
 1705          * it might not be set at all.
 1706          *
 1707          * So we just fall back on userland filtering in
 1708          * all cases.
 1709          */
 1710 
 1711         /*
 1712          * install_bpf_program() validates the program.
 1713          *
 1714          * XXX - what if we already have a filter in the kernel?
 1715          */
 1716         if (install_bpf_program(p, fp) < 0)
 1717             return (-1);
 1718         pw->filtering_in_kernel = 0;    /* filtering in userland */
 1719         return (0);
 1720     }
 1721 
 1722     /*
 1723      * It worked.
 1724      */
 1725     pw->filtering_in_kernel = 1;    /* filtering in the kernel */
 1726 
 1727     /*
 1728      * Discard any previously-received packets, as they might have
 1729      * passed whatever filter was formerly in effect, but might
 1730      * not pass this filter (BIOCSETF discards packets buffered
 1731      * in the kernel, so you can lose packets in any case).
 1732      */
 1733     p->cc = 0;
 1734     return (0);
 1735 }
 1736 
 1737 /*
 1738  * We filter at user level, since the kernel driver doesn't process the packets
 1739  */
 1740 static int
 1741 pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
 1742 
 1743     if(!fp)
 1744     {
 1745         pcap_strlcpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
 1746         return (-1);
 1747     }
 1748 
 1749     /* Install a user level filter */
 1750     if (install_bpf_program(p, fp) < 0)
 1751         return (-1);
 1752 
 1753     return (0);
 1754 }
 1755 
 1756 static int
 1757 pcap_getnonblock_npf(pcap_t *p)
 1758 {
 1759     struct pcap_win *pw = p->priv;
 1760 
 1761     /*
 1762      * XXX - if there were a PacketGetReadTimeout() call, we
 1763      * would use it, and return 1 if the timeout is -1
 1764      * and 0 otherwise.
 1765      */
 1766     return (pw->nonblock);
 1767 }
 1768 
 1769 static int
 1770 pcap_setnonblock_npf(pcap_t *p, int nonblock)
 1771 {
 1772     struct pcap_win *pw = p->priv;
 1773     int newtimeout;
 1774 
 1775     if (nonblock) {
 1776         /*
 1777          * Set the packet buffer timeout to -1 for non-blocking
 1778          * mode.
 1779          */
 1780         newtimeout = -1;
 1781     } else {
 1782         /*
 1783          * Restore the timeout set when the device was opened.
 1784          * (Note that this may be -1, in which case we're not
 1785          * really leaving non-blocking mode.  However, although
 1786          * the timeout argument to pcap_set_timeout() and
 1787          * pcap_open_live() is an int, you're not supposed to
 1788          * supply a negative value, so that "shouldn't happen".)
 1789          */
 1790         newtimeout = p->opt.timeout;
 1791     }
 1792     if (!PacketSetReadTimeout(pw->adapter, newtimeout)) {
 1793         pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
 1794             GetLastError(), "PacketSetReadTimeout");
 1795         return (-1);
 1796     }
 1797     pw->nonblock = (newtimeout == -1);
 1798     return (0);
 1799 }
 1800 
 1801 static int
 1802 pcap_add_if_npf(pcap_if_list_t *devlistp, char *name, bpf_u_int32 flags,
 1803     const char *description, char *errbuf)
 1804 {
 1805     pcap_if_t *curdev;
 1806     npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
 1807     LONG if_addr_size;
 1808     int res = 0;
 1809 
 1810     if_addr_size = MAX_NETWORK_ADDRESSES;
 1811 
 1812     /*
 1813      * Add an entry for this interface, with no addresses.
 1814      */
 1815     curdev = add_dev(devlistp, name, flags, description, errbuf);
 1816     if (curdev == NULL) {
 1817         /*
 1818          * Failure.
 1819          */
 1820         return (-1);
 1821     }
 1822 
 1823     /*
 1824      * Get the list of addresses for the interface.
 1825      */
 1826     if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) {
 1827         /*
 1828          * Failure.
 1829          *
 1830          * We don't return an error, because this can happen with
 1831          * NdisWan interfaces, and we want to supply them even
 1832          * if we can't supply their addresses.
 1833          *
 1834          * We return an entry with an empty address list.
 1835          */
 1836         return (0);
 1837     }
 1838 
 1839     /*
 1840      * Now add the addresses.
 1841      */
 1842     while (if_addr_size-- > 0) {
 1843         /*
 1844          * "curdev" is an entry for this interface; add an entry for
 1845          * this address to its list of addresses.
 1846          */
 1847         res = add_addr_to_dev(curdev,
 1848             (struct sockaddr *)&if_addrs[if_addr_size].IPAddress,
 1849             sizeof (struct sockaddr_storage),
 1850             (struct sockaddr *)&if_addrs[if_addr_size].SubnetMask,
 1851             sizeof (struct sockaddr_storage),
 1852             (struct sockaddr *)&if_addrs[if_addr_size].Broadcast,
 1853             sizeof (struct sockaddr_storage),
 1854             NULL,
 1855             0,
 1856             errbuf);
 1857         if (res == -1) {
 1858             /*
 1859              * Failure.
 1860              */
 1861             break;
 1862         }
 1863     }
 1864 
 1865     return (res);
 1866 }
 1867 
 1868 static int
 1869 get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
 1870 {
 1871     char *name_copy;
 1872     ADAPTER *adapter;
 1873     int status;
 1874     size_t len;
 1875     NDIS_HARDWARE_STATUS hardware_status;
 1876 #ifdef OID_GEN_PHYSICAL_MEDIUM
 1877     NDIS_PHYSICAL_MEDIUM phys_medium;
 1878     bpf_u_int32 gen_physical_medium_oids[] = {
 1879   #ifdef OID_GEN_PHYSICAL_MEDIUM_EX
 1880         OID_GEN_PHYSICAL_MEDIUM_EX,
 1881   #endif
 1882         OID_GEN_PHYSICAL_MEDIUM
 1883     };
 1884 #define N_GEN_PHYSICAL_MEDIUM_OIDS  (sizeof gen_physical_medium_oids / sizeof gen_physical_medium_oids[0])
 1885     size_t i;
 1886 #endif /* OID_GEN_PHYSICAL_MEDIUM */
 1887 #ifdef OID_GEN_LINK_STATE
 1888     NDIS_LINK_STATE link_state;
 1889 #endif
 1890     int connect_status;
 1891 
 1892     if (*flags & PCAP_IF_LOOPBACK) {
 1893         /*
 1894          * Loopback interface, so the connection status doesn't
 1895          * apply. and it's not wireless (or wired, for that
 1896          * matter...).  We presume it's up and running.
 1897          */
 1898         *flags |= PCAP_IF_UP | PCAP_IF_RUNNING | PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
 1899         return (0);
 1900     }
 1901 
 1902     /*
 1903      * We need to open the adapter to get this information.
 1904      *
 1905      * XXX - PacketOpenAdapter() takes a non-const pointer
 1906      * as an argument, so we make a copy of the argument and
 1907      * pass that to it.
 1908      */
 1909     name_copy = strdup(name);
 1910     adapter = PacketOpenAdapter(name_copy);
 1911     free(name_copy);
 1912     if (adapter == NULL) {
 1913         /*
 1914          * Give up; if they try to open this device, it'll fail.
 1915          */
 1916         return (0);
 1917     }
 1918 
 1919 #ifdef HAVE_AIRPCAP_API
 1920     /*
 1921      * Airpcap.sys do not support the below 'OID_GEN_x' values.
 1922      * Just set these flags (and none of the '*flags' entered with).
 1923      */
 1924     if (PacketGetAirPcapHandle(adapter)) {
 1925         /*
 1926          * Must be "up" and "running" if the above if succeeded.
 1927          */
 1928         *flags = PCAP_IF_UP | PCAP_IF_RUNNING;
 1929 
 1930         /*
 1931          * An airpcap device is a wireless device (duh!)
 1932          */
 1933         *flags |= PCAP_IF_WIRELESS;
 1934 
 1935         /*
 1936          * A "network assosiation state" makes no sense for airpcap.
 1937          */
 1938         *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
 1939         PacketCloseAdapter(adapter);
 1940         return (0);
 1941     }
 1942 #endif
 1943 
 1944     /*
 1945      * Get the hardware status, and derive "up" and "running" from
 1946      * that.
 1947      */
 1948     len = sizeof (hardware_status);
 1949     status = oid_get_request(adapter, OID_GEN_HARDWARE_STATUS,
 1950         &hardware_status, &len, errbuf);
 1951     if (status == 0) {
 1952         switch (hardware_status) {
 1953 
 1954         case NdisHardwareStatusReady:
 1955             /*
 1956              * "Available and capable of sending and receiving
 1957              * data over the wire", so up and running.
 1958              */
 1959             *flags |= PCAP_IF_UP | PCAP_IF_RUNNING;
 1960             break;
 1961 
 1962         case NdisHardwareStatusInitializing:
 1963         case NdisHardwareStatusReset:
 1964             /*
 1965              * "Initializing" or "Resetting", so up, but
 1966              * not running.
 1967              */
 1968             *flags |= PCAP_IF_UP;
 1969             break;
 1970 
 1971         case NdisHardwareStatusClosing:
 1972         case NdisHardwareStatusNotReady:
 1973             /*
 1974              * "Closing" or "Not ready", so neither up nor
 1975              * running.
 1976              */
 1977             break;
 1978 
 1979         default:
 1980             /*
 1981              * Unknown.
 1982              */
 1983             break;
 1984         }
 1985     } else {
 1986         /*
 1987          * Can't get the hardware status, so assume both up and
 1988          * running.
 1989          */
 1990         *flags |= PCAP_IF_UP | PCAP_IF_RUNNING;
 1991     }
 1992 
 1993     /*
 1994      * Get the network type.
 1995      */
 1996 #ifdef OID_GEN_PHYSICAL_MEDIUM
 1997     /*
 1998      * Try the OIDs we have for this, in order.
 1999      */
 2000     for (i = 0; i < N_GEN_PHYSICAL_MEDIUM_OIDS; i++) {
 2001         len = sizeof (phys_medium);
 2002         status = oid_get_request(adapter, gen_physical_medium_oids[i],
 2003             &phys_medium, &len, errbuf);
 2004         if (status == 0) {
 2005             /*
 2006              * Success.
 2007              */
 2008             break;
 2009         }
 2010         /*
 2011          * Failed.  We can't determine whether it failed
 2012          * because that particular OID isn't supported
 2013          * or because some other problem occurred, so we
 2014          * just drive on and try the next OID.
 2015          */
 2016     }
 2017     if (status == 0) {
 2018         /*
 2019          * We got the physical medium.
 2020          *
 2021          * XXX - we might want to check for NdisPhysicalMediumWiMax
 2022          * and NdisPhysicalMediumNative802_15_4 being
 2023          * part of the enum, and check for those in the "wireless"
 2024          * case.
 2025          */
 2026 DIAG_OFF_ENUM_SWITCH
 2027         switch (phys_medium) {
 2028 
 2029         case NdisPhysicalMediumWirelessLan:
 2030         case NdisPhysicalMediumWirelessWan:
 2031         case NdisPhysicalMediumNative802_11:
 2032         case NdisPhysicalMediumBluetooth:
 2033         case NdisPhysicalMediumUWB:
 2034         case NdisPhysicalMediumIrda:
 2035             /*
 2036              * Wireless.
 2037              */
 2038             *flags |= PCAP_IF_WIRELESS;
 2039             break;
 2040 
 2041         default:
 2042             /*
 2043              * Not wireless or unknown
 2044              */
 2045             break;
 2046         }
 2047 DIAG_ON_ENUM_SWITCH
 2048     }
 2049 #endif
 2050 
 2051     /*
 2052      * Get the connection status.
 2053      */
 2054 #ifdef OID_GEN_LINK_STATE
 2055     len = sizeof(link_state);
 2056     status = oid_get_request(adapter, OID_GEN_LINK_STATE, &link_state,
 2057         &len, errbuf);
 2058     if (status == 0) {
 2059         /*
 2060          * NOTE: this also gives us the receive and transmit
 2061          * link state.
 2062          */
 2063         switch (link_state.MediaConnectState) {
 2064 
 2065         case MediaConnectStateConnected:
 2066             /*
 2067              * It's connected.
 2068              */
 2069             *flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
 2070             break;
 2071 
 2072         case MediaConnectStateDisconnected:
 2073             /*
 2074              * It's disconnected.
 2075              */
 2076             *flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
 2077             break;
 2078 
 2079         case MediaConnectStateUnknown:
 2080         default:
 2081             /*
 2082              * It's unknown whether it's connected or not.
 2083              */
 2084             break;
 2085         }
 2086     }
 2087 #else
 2088     /*
 2089      * OID_GEN_LINK_STATE isn't supported because it's not in our SDK.
 2090      */
 2091     status = -1;
 2092 #endif
 2093     if (status == -1) {
 2094         /*
 2095          * OK, OID_GEN_LINK_STATE didn't work, try
 2096          * OID_GEN_MEDIA_CONNECT_STATUS.
 2097          */
 2098         status = oid_get_request(adapter, OID_GEN_MEDIA_CONNECT_STATUS,
 2099             &connect_status, &len, errbuf);
 2100         if (status == 0) {
 2101             switch (connect_status) {
 2102 
 2103             case NdisMediaStateConnected:
 2104                 /*
 2105                  * It's connected.
 2106                  */
 2107                 *flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
 2108                 break;
 2109 
 2110             case NdisMediaStateDisconnected:
 2111                 /*
 2112                  * It's disconnected.
 2113                  */
 2114                 *flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
 2115                 break;
 2116             }
 2117         }
 2118     }
 2119     PacketCloseAdapter(adapter);
 2120     return (0);
 2121 }
 2122 
 2123 int
 2124 pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
 2125 {
 2126     int ret = 0;
 2127     const char *desc;
 2128     char *AdaptersName;
 2129     ULONG NameLength;
 2130     char *name;
 2131 
 2132     /*
 2133      * Find out how big a buffer we need.
 2134      *
 2135      * This call should always return FALSE; if the error is
 2136      * ERROR_INSUFFICIENT_BUFFER, NameLength will be set to
 2137      * the size of the buffer we need, otherwise there's a
 2138      * problem, and NameLength should be set to 0.
 2139      *
 2140      * It shouldn't require NameLength to be set, but,
 2141      * at least as of WinPcap 4.1.3, it checks whether
 2142      * NameLength is big enough before it checks for a
 2143      * NULL buffer argument, so, while it'll still do
 2144      * the right thing if NameLength is uninitialized and
 2145      * whatever junk happens to be there is big enough
 2146      * (because the pointer argument will be null), it's
 2147      * still reading an uninitialized variable.
 2148      */
 2149     NameLength = 0;
 2150     if (!PacketGetAdapterNames(NULL, &NameLength))
 2151     {
 2152         DWORD last_error = GetLastError();
 2153 
 2154         if (last_error != ERROR_INSUFFICIENT_BUFFER)
 2155         {
 2156             pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
 2157                 last_error, "PacketGetAdapterNames");
 2158             return (-1);
 2159         }
 2160     }
 2161 
 2162     if (NameLength <= 0)
 2163         return 0;
 2164     AdaptersName = (char*) malloc(NameLength);
 2165     if (AdaptersName == NULL)
 2166     {
 2167         snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
 2168         return (-1);
 2169     }
 2170 
 2171     if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
 2172         pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
 2173             GetLastError(), "PacketGetAdapterNames");
 2174         free(AdaptersName);
 2175         return (-1);
 2176     }
 2177 
 2178     /*
 2179      * "PacketGetAdapterNames()" returned a list of
 2180      * null-terminated ASCII interface name strings,
 2181      * terminated by a null string, followed by a list
 2182      * of null-terminated ASCII interface description
 2183      * strings, terminated by a null string.
 2184      * This means there are two ASCII nulls at the end
 2185      * of the first list.
 2186      *
 2187      * Find the end of the first list; that's the
 2188      * beginning of the second list.
 2189      */
 2190     desc = &AdaptersName[0];
 2191     while (*desc != '\0' || *(desc + 1) != '\0')
 2192         desc++;
 2193 
 2194     /*
 2195      * Found it - "desc" points to the first of the two
 2196      * nulls at the end of the list of names, so the
 2197      * first byte of the list of descriptions is two bytes
 2198      * after it.
 2199      */
 2200     desc += 2;
 2201 
 2202     /*
 2203      * Loop over the elements in the first list.
 2204      */
 2205     name = &AdaptersName[0];
 2206     while (*name != '\0') {
 2207         bpf_u_int32 flags = 0;
 2208 
 2209 #ifdef HAVE_AIRPCAP_API
 2210         /*
 2211          * Is this an AirPcap device?
 2212          * If so, ignore it; it'll get added later, by the
 2213          * AirPcap code.
 2214          */
 2215         if (device_is_airpcap(name, errbuf) == 1) {
 2216             name += strlen(name) + 1;
 2217             desc += strlen(desc) + 1;
 2218             continue;
 2219         }
 2220 #endif
 2221 
 2222 #ifdef HAVE_PACKET_IS_LOOPBACK_ADAPTER
 2223         /*
 2224          * Is this a loopback interface?
 2225          */
 2226         if (PacketIsLoopbackAdapter(name)) {
 2227             /* Yes */
 2228             flags |= PCAP_IF_LOOPBACK;
 2229         }
 2230 #endif
 2231         /*
 2232          * Get additional flags.
 2233          */
 2234         if (get_if_flags(name, &flags, errbuf) == -1) {
 2235             /*
 2236              * Failure.
 2237              */
 2238             ret = -1;
 2239             break;
 2240         }
 2241 
 2242         /*
 2243          * Add an entry for this interface.
 2244          */
 2245         if (pcap_add_if_npf(devlistp, name, flags, desc,
 2246             errbuf) == -1) {
 2247             /*
 2248              * Failure.
 2249              */
 2250             ret = -1;
 2251             break;
 2252         }
 2253         name += strlen(name) + 1;
 2254         desc += strlen(desc) + 1;
 2255     }
 2256 
 2257     free(AdaptersName);
 2258     return (ret);
 2259 }
 2260 
 2261 /*
 2262  * Return the name of a network interface attached to the system, or NULL
 2263  * if none can be found.  The interface must be configured up; the
 2264  * lowest unit number is preferred; loopback is ignored.
 2265  *
 2266  * In the best of all possible worlds, this would be the same as on
 2267  * UN*X, but there may be software that expects this to return a
 2268  * full list of devices after the first device.
 2269  */
 2270 #define ADAPTERSNAME_LEN    8192
 2271 char *
 2272 pcap_lookupdev(char *errbuf)
 2273 {
 2274     DWORD dwVersion;
 2275     DWORD dwWindowsMajorVersion;
 2276 
 2277     /*
 2278      * We disable this in "new API" mode, because 1) in WinPcap/Npcap,
 2279      * it may return UTF-16 strings, for backwards-compatibility
 2280      * reasons, and we're also disabling the hack to make that work,
 2281      * for not-going-past-the-end-of-a-string reasons, and 2) we
 2282      * want its behavior to be consistent.
 2283      *
 2284      * In addition, it's not thread-safe, so we've marked it as
 2285      * deprecated.
 2286      */
 2287     if (pcap_new_api) {
 2288         snprintf(errbuf, PCAP_ERRBUF_SIZE,
 2289             "pcap_lookupdev() is deprecated and is not supported in programs calling pcap_init()");
 2290         return (NULL);
 2291     }
 2292 
 2293 /* disable MSVC's GetVersion() deprecated warning here */
 2294 DIAG_OFF_DEPRECATION
 2295     dwVersion = GetVersion();   /* get the OS version */
 2296 DIAG_ON_DEPRECATION
 2297     dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
 2298 
 2299     if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
 2300         /*
 2301          * Windows 95, 98, ME.
 2302          */
 2303         ULONG NameLength = ADAPTERSNAME_LEN;
 2304         static char AdaptersName[ADAPTERSNAME_LEN];
 2305 
 2306         if (PacketGetAdapterNames(AdaptersName,&NameLength) )
 2307             return (AdaptersName);
 2308         else
 2309             return NULL;
 2310     } else {
 2311         /*
 2312          * Windows NT (NT 4.0 and later).
 2313          * Convert the names to Unicode for backward compatibility.
 2314          */
 2315         ULONG NameLength = ADAPTERSNAME_LEN;
 2316         static WCHAR AdaptersName[ADAPTERSNAME_LEN];
 2317         size_t BufferSpaceLeft;
 2318         char *tAstr;
 2319         WCHAR *Unameptr;
 2320         char *Adescptr;
 2321         size_t namelen, i;
 2322         WCHAR *TAdaptersName = (WCHAR*)malloc(ADAPTERSNAME_LEN * sizeof(WCHAR));
 2323         int NAdapts = 0;
 2324 
 2325         if(TAdaptersName == NULL)
 2326         {
 2327             (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
 2328             return NULL;
 2329         }
 2330 
 2331         if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
 2332         {
 2333             pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
 2334                 GetLastError(), "PacketGetAdapterNames");
 2335             free(TAdaptersName);
 2336             return NULL;
 2337         }
 2338 
 2339 
 2340         BufferSpaceLeft = ADAPTERSNAME_LEN * sizeof(WCHAR);
 2341         tAstr = (char*)TAdaptersName;
 2342         Unameptr = AdaptersName;
 2343 
 2344         /*
 2345          * Convert the device names to Unicode into AdapterName.
 2346          */
 2347         do {
 2348             /*
 2349              * Length of the name, including the terminating
 2350              * NUL.
 2351              */
 2352             namelen = strlen(tAstr) + 1;
 2353 
 2354             /*
 2355              * Do we have room for the name in the Unicode
 2356              * buffer?
 2357              */
 2358             if (BufferSpaceLeft < namelen * sizeof(WCHAR)) {
 2359                 /*
 2360                  * No.
 2361                  */
 2362                 goto quit;
 2363             }
 2364             BufferSpaceLeft -= namelen * sizeof(WCHAR);
 2365 
 2366             /*
 2367              * Copy the name, converting ASCII to Unicode.
 2368              * namelen includes the NUL, so we copy it as
 2369              * well.
 2370              */
 2371             for (i = 0; i < namelen; i++)
 2372                 *Unameptr++ = *tAstr++;
 2373 
 2374             /*
 2375              * Count this adapter.
 2376              */
 2377             NAdapts++;
 2378         } while (namelen != 1);
 2379 
 2380         /*
 2381          * Copy the descriptions, but don't convert them from
 2382          * ASCII to Unicode.
 2383          */
 2384         Adescptr = (char *)Unameptr;
 2385         while(NAdapts--)
 2386         {
 2387             size_t desclen;
 2388 
 2389             desclen = strlen(tAstr) + 1;
 2390 
 2391             /*
 2392              * Do we have room for the name in the Unicode
 2393              * buffer?
 2394              */
 2395             if (BufferSpaceLeft < desclen) {
 2396                 /*
 2397                  * No.
 2398                  */
 2399                 goto quit;
 2400             }
 2401 
 2402             /*
 2403              * Just copy the ASCII string.
 2404              * namelen includes the NUL, so we copy it as
 2405              * well.
 2406              */
 2407             memcpy(Adescptr, tAstr, desclen);
 2408             Adescptr += desclen;
 2409             tAstr += desclen;
 2410             BufferSpaceLeft -= desclen;
 2411         }
 2412 
 2413     quit:
 2414         free(TAdaptersName);
 2415         return (char *)(AdaptersName);
 2416     }
 2417 }
 2418 
 2419 /*
 2420  * We can't use the same code that we use on UN*X, as that's doing
 2421  * UN*X-specific calls.
 2422  *
 2423  * We don't just fetch the entire list of devices, search for the
 2424  * particular device, and use its first IPv4 address, as that's too
 2425  * much work to get just one device's netmask.
 2426  */
 2427 int
 2428 pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
 2429     char *errbuf)
 2430 {
 2431     /*
 2432      * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
 2433      * in order to skip non IPv4 (i.e. IPv6 addresses)
 2434      */
 2435     npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
 2436     LONG if_addr_size = MAX_NETWORK_ADDRESSES;
 2437     struct sockaddr_in *t_addr;
 2438     LONG i;
 2439 
 2440     if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
 2441         *netp = *maskp = 0;
 2442         return (0);
 2443     }
 2444 
 2445     for(i = 0; i < if_addr_size; i++)
 2446     {
 2447         if(if_addrs[i].IPAddress.ss_family == AF_INET)
 2448         {
 2449             t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
 2450             *netp = t_addr->sin_addr.S_un.S_addr;
 2451             t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
 2452             *maskp = t_addr->sin_addr.S_un.S_addr;
 2453 
 2454             *netp &= *maskp;
 2455             return (0);
 2456         }
 2457 
 2458     }
 2459 
 2460     *netp = *maskp = 0;
 2461     return (0);
 2462 }
 2463 
 2464 static const char *pcap_lib_version_string;
 2465 
 2466 #ifdef HAVE_VERSION_H
 2467 /*
 2468  * libpcap being built for Windows, as part of a WinPcap/Npcap source
 2469  * tree.  Include version.h from that source tree to get the WinPcap/Npcap
 2470  * version.
 2471  *
 2472  * XXX - it'd be nice if we could somehow generate the WinPcap/Npcap version
 2473  * number when building as part of WinPcap/Npcap.  (It'd be nice to do so
 2474  * for the packet.dll version number as well.)
 2475  */
 2476 #include "../../version.h"
 2477 
 2478 static const char pcap_version_string[] =
 2479     WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING ", based on " PCAP_VERSION_STRING;
 2480 
 2481 const char *
 2482 pcap_lib_version(void)
 2483 {
 2484     if (pcap_lib_version_string == NULL) {
 2485         /*
 2486          * Generate the version string.
 2487          */
 2488         const char *packet_version_string = PacketGetVersion();
 2489 
 2490         if (strcmp(WINPCAP_VER_STRING, packet_version_string) == 0) {
 2491             /*
 2492              * WinPcap/Npcap version string and packet.dll version
 2493              * string are the same; just report the WinPcap/Npcap
 2494              * version.
 2495              */
 2496             pcap_lib_version_string = pcap_version_string;
 2497         } else {
 2498             /*
 2499              * WinPcap/Npcap version string and packet.dll version
 2500              * string are different; that shouldn't be the
 2501              * case (the two libraries should come from the
 2502              * same version of WinPcap/Npcap), so we report both
 2503              * versions.
 2504              */
 2505             char *full_pcap_version_string;
 2506 
 2507             if (pcap_asprintf(&full_pcap_version_string,
 2508                 WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING " (packet.dll version %s), based on " PCAP_VERSION_STRING,
 2509                 packet_version_string) != -1) {
 2510                 /* Success */
 2511                 pcap_lib_version_string = full_pcap_version_string;
 2512             }
 2513         }
 2514     }
 2515     return (pcap_lib_version_string);
 2516 }
 2517 
 2518 #else /* HAVE_VERSION_H */
 2519 
 2520 /*
 2521  * libpcap being built for Windows, not as part of a WinPcap/Npcap source
 2522  * tree.
 2523  */
 2524 const char *
 2525 pcap_lib_version(void)
 2526 {
 2527     if (pcap_lib_version_string == NULL) {
 2528         /*
 2529          * Generate the version string.  Report the packet.dll
 2530          * version.
 2531          */
 2532         char *full_pcap_version_string;
 2533 
 2534         if (pcap_asprintf(&full_pcap_version_string,
 2535             PCAP_VERSION_STRING " (packet.dll version %s)",
 2536             PacketGetVersion()) != -1) {
 2537             /* Success */
 2538             pcap_lib_version_string = full_pcap_version_string;
 2539         }
 2540     }
 2541     return (pcap_lib_version_string);
 2542 }
 2543 #endif /* HAVE_VERSION_H */