Diff for /embedaddon/libnet/src/libnet_link_win32.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2013/07/22 11:54:42 version 1.1.1.3, 2023/09/27 11:11:38
Line 1 Line 1
 /*  /*
  *  $Id$  
  *  
  *  libnet   *  libnet
  *  libnet_link_win32.c - low-level win32 libwpcap routines   *  libnet_link_win32.c - low-level win32 libwpcap routines
  *   *
Line 32 Line 30
  *   *
  */   */
   
#if (HAVE_CONFIG_H)/* Libnet's unnamespaced ICMP6_ macros stomp on the enumerated versions of
#include "../include/config.h"   these names in the MS headers, so pre-include this header. */
#endif
 #include <winsock2.h>  #include <winsock2.h>
 #include <iphlpapi.h> /* From the Microsoft Platform SDK */  #include <iphlpapi.h> /* From the Microsoft Platform SDK */
#include "../include/win32/libnet.h"#include <iprtrmib.h>
 #include <assert.h>  #include <assert.h>
 #include <Packet32.h>  
 #include <Ntddndis.h>  
 #include "iprtrmib.h"  
   
   #include "common.h"
   
   /*
    * These are the types that are the same on all platforms, and that
    * have been defined by <net/bpf.h> for ages.
    */
   
   #ifndef DLT_NULL
   #define DLT_NULL        0       /* BSD loopback encapsulation */
   #endif
   
   #ifndef DLT_EN10MB
   #define DLT_EN10MB      1       /* Ethernet (10Mb) */
   #endif
   
   #ifndef DLT_EN3MB
   #define DLT_EN3MB       2       /* Experimental Ethernet (3Mb) */
   #endif
   
   #ifndef DLT_AX25
   #define DLT_AX25        3       /* Amateur Radio AX.25 */
   #endif
   
   #ifndef DLT_PRONET
   #define DLT_PRONET      4       /* Proteon ProNET Token Ring */
   #endif
   
   #ifndef DLT_CHAOS
   #define DLT_CHAOS       5       /* Chaos */
   #endif
   
   #ifndef DLT_IEEE802
   #define DLT_IEEE802     6       /* 802.5 Token Ring */
   #endif
   
   #ifndef DLT_ARCNET
   #define DLT_ARCNET      7       /* ARCNET, with BSD-style header */
   #endif
   
   #ifndef DLT_SLIP
   #define DLT_SLIP        8       /* Serial Line IP */
   #endif
   
   #ifndef DLT_PPP
   #define DLT_PPP         9       /* Point-to-point Protocol */
   #endif
   
   #ifndef DLT_FDDI
   #define DLT_FDDI        10      /* FDDI */
   #endif
   
   /*
    * These are types that are different on some platforms, and that
    * have been defined by <net/bpf.h> for ages.  We use #ifdefs to
    * detect the BSDs that define them differently from the traditional
    * libpcap <net/bpf.h>
    *
    * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS,
    * but I don't know what the right #define is for BSD/OS.
    */
   
   #ifndef DLT_ATM_RFC1483
   #define DLT_ATM_RFC1483 11      /* LLC-encapsulated ATM */
   #endif
   
 int  int
 libnet_open_link(libnet_t *l)  libnet_open_link(libnet_t *l)
 {  {
Line 50  libnet_open_link(libnet_t *l) Line 110  libnet_open_link(libnet_t *l)
     NetType IFType;      NetType IFType;
   
     if (l == NULL)      if (l == NULL)
    {     {
         return (-1);          return (-1);
    }     }
   
     if (l->device == NULL)      if (l->device == NULL)
     {      {
         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): NULL device\n", __func__);                 "%s(): NULL device", __func__);
         return (-1);          return (-1);
     }      }
   
     l->lpAdapter = 0;      l->lpAdapter = 0;
   
     /* open adapter */      /* open adapter */
        l->lpAdapter = PacketOpenAdapter(l->device);    l->lpAdapter = PacketOpenAdapter(l->device);
     if (!l->lpAdapter || (l->lpAdapter->hFile == INVALID_HANDLE_VALUE))      if (!l->lpAdapter || (l->lpAdapter->hFile == INVALID_HANDLE_VALUE))
     {      {
         dwErrorCode=GetLastError();          dwErrorCode=GetLastError();
         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): unable to open the driver, error Code : %lx\n",                 "%s(): unable to open the driver, error Code : %lx",
                __func__, dwErrorCode);                  __func__, dwErrorCode);
         return (-1);          return (-1);
     }      }
        
     /* increase the send buffer */      /* increase the send buffer */
     PacketSetBuff(l->lpAdapter, 512000);      PacketSetBuff(l->lpAdapter, 512000);
   
Line 84  libnet_open_link(libnet_t *l) Line 144  libnet_open_link(libnet_t *l)
     {      {
         switch(IFType.LinkType)          switch(IFType.LinkType)
         {          {
            case NdisMedium802_3:        case NdisMedium802_3:
                                l->link_type = DLT_EN10MB;            l->link_type = DLT_EN10MB;
                                l->link_offset = LIBNET_ETH_H;            l->link_offset = LIBNET_ETH_H;
                break;            break;
                        case NdisMedium802_5:        case NdisMedium802_5:
                                l->link_type = DLT_IEEE802;            l->link_type = DLT_IEEE802;
                                l->link_offset = LIBNET_TOKEN_RING_H;            l->link_offset = LIBNET_TOKEN_RING_H;
                                break;            break;
                        case NdisMediumFddi:        case NdisMediumFddi:
                                l->link_type = DLT_FDDI;            l->link_type = DLT_FDDI;
                                l->link_offset = 0x15;            l->link_offset = 0x15;
                                break;            break;
                        case NdisMediumWan:        case NdisMediumWan:
                                snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,            snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                 "%s():, WinPcap has disabled support for Network type (%d)\n",                     "%s():, WinPcap has disabled support for Network type (%d)",
                 __func__, IFType.LinkType);                     __func__, IFType.LinkType);
                                return (-1);            return (-1);
                                break;            break;
                        case NdisMediumAtm:        case NdisMediumAtm:
                                l->link_type = DLT_ATM_RFC1483;            l->link_type = DLT_ATM_RFC1483;
                                break;            break;
                        case NdisMediumArcnet878_2:        case NdisMediumArcnet878_2:
                                l->link_type = DLT_ARCNET;            l->link_type = DLT_ARCNET;
                                break;            break;
                        default:        default:
                snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,            snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                         "%s(): network type (%d) is not supported\n",                     "%s(): network type (%d) is not supported",
                         __func__, IFType.LinkType);                     __func__, IFType.LinkType);
                return (-1);            return (-1);
                break;            break;
         }          }
     }      }
     else      else
     {      {
         dwErrorCode=GetLastError();          dwErrorCode=GetLastError();
         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
            "%s(): unable to determine the network type, error Code : %lx\n",                 "%s(): unable to determine the network type, error Code : %lx",
                __func__, dwErrorCode);                 __func__, dwErrorCode);
         return (-1);          return (-1);
     }      }
     return (1);      return (1);
Line 139  libnet_close_link_interface(libnet_t *l) Line 199  libnet_close_link_interface(libnet_t *l)
 }  }
   
 int  int
libnet_write_link(libnet_t *l, const uint8_t *packet, uint32_t size)libnet_write_link(libnet_t *l, const uint8_t *data, uint32_t size)
 {  {
    LPPACKET   lpPacket;    PACKET pkt;
    DWORD      BytesTransfered;           DWORD  BytesTransfered = -1;
   
    BytesTransfered = -1;    /* Packet* arguments aren't const, but aren't actually modified.
      */
     PacketInitPacket(&pkt, (PVOID)data, size);
   
    if ((lpPacket = PacketAllocatePacket()) == NULL)    if (PacketSendPacket(l->lpAdapter, &pkt, TRUE))
    {       BytesTransfered = size;
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, 
                "%s(): failed to allocate the LPPACKET structure\n", __func__); 
                return (-1); 
    } 
    PacketInitPacket(lpPacket, packet, size); 
   
     /* PacketSendPacket returns a BOOLEAN */  
     if(PacketSendPacket(l->lpAdapter, lpPacket, TRUE))  
     {  
             BytesTransfered = size;  
     }  
           
     PacketFreePacket(lpPacket);  
     return (BytesTransfered);      return (BytesTransfered);
  }   }
   
 struct libnet_ether_addr *  struct libnet_ether_addr *
 libnet_get_hwaddr(libnet_t *l)  libnet_get_hwaddr(libnet_t *l)
 {  {
    /* This implementation is not-reentrant. */    struct libnet_ether_addr *mac = &l->link_addr;
    static struct libnet_ether_addr *mac; 
     
     ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA) + sizeof(ULONG) - 1);      ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA) + sizeof(ULONG) - 1);
        PPACKET_OID_DATA OidData;    PPACKET_OID_DATA OidData;
         
        int i = 0; 
   
        if (l == NULL)    int i = 0;
    { 
     if (l == NULL)
     {
         return (NULL);          return (NULL);
    }     }
   
        if (l->device == NULL)    if (l->device == NULL)
    {               {
         if (libnet_select_device(l) == -1)          if (libnet_select_device(l) == -1)
        {           {
             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,              snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    "%s(): can't figure out a device to use\n", __func__);                     "%s(): can't figure out a device to use", __func__);
             return (NULL);              return (NULL);
         }          }
     }      }
   
    mac = (struct libnet_ether_addr *)calloc(1,sizeof(struct libnet_ether_addr));    OidData = (struct _PACKET_OID_DATA *)malloc(IoCtlBufferLength);
        if (mac == NULL)    if (OidData == NULL)
        {    {
                snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    "%s(): calloc error\n", __func__);                 "%s(): OidData is NULL", __func__);
                return (NULL);        return(NULL);
        }    }
   
    OidData = (struct _PACKET_OID_DATA *) malloc(IoCtlBufferLength);    if (l->link_type == DLT_IEEE802)
            {
        if (OidData == NULL)        OidData->Oid = OID_802_5_CURRENT_ADDRESS;
        {    }
             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,    else
                                 "%s(): OidData is NULL\n", __func__);    {
            return(NULL);        OidData->Oid = OID_802_3_CURRENT_ADDRESS;
        }    }
   
        if (l->link_type == DLT_IEEE802)    OidData->Length = 6;
        {    if ((PacketRequest(l->lpAdapter, FALSE, OidData)) == FALSE)
                OidData->Oid = OID_802_5_CURRENT_ADDRESS;           {
        }        memset(mac, 0, 6);
        else    }
        {    else
                OidData->Oid = OID_802_3_CURRENT_ADDRESS;           {
        }        for (i = 0; i < 6; i++)
                {
        OidData->Length = 6;            mac->ether_addr_octet[i] = OidData->Data[i];
        if((PacketRequest(l->lpAdapter, FALSE, OidData)) == FALSE)        }
        {    }
                memset(mac, 0, 6);    free(OidData);
        }    return(mac);
        else 
        { 
                for (i = 0; i < 6; i++) 
                { 
                        mac->ether_addr_octet[i] = OidData->Data[i]; 
                } 
        } 
        free(OidData); 
        return(mac); 
 }  }
   
 struct hostent *gethostbyname2(const int8_t *name, int af)   
 {  
    /* XXX not implemented */  
    return(NULL);  
 }  
   
 BYTE *  BYTE *
 libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)  libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
Line 251  libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP) Line 285  libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
         static BYTE bcastmac[]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};          static BYTE bcastmac[]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
   
         BYTE *MAC = libnet_win32_read_arp_table(DestIP);          BYTE *MAC = libnet_win32_read_arp_table(DestIP);
        
         if (MAC==NULL)          if (MAC==NULL)
         {          {
                 memset(pulMac, 0xff, sizeof (pulMac));                  memset(pulMac, 0xff, sizeof (pulMac));
                 memset(&sin, 0, sizeof(sin));                  memset(&sin, 0, sizeof(sin));
            
                 if((hr = SendARP (DestIP, 0, pulMac, &ulLen)) != NO_ERROR)                  if((hr = SendARP (DestIP, 0, pulMac, &ulLen)) != NO_ERROR)
                 {                  {
                         *(int32_t *)&sin.sin_addr = DestIP;                          *(int32_t *)&sin.sin_addr = DestIP;
Line 280  libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP) Line 314  libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
                                 return(bcastmac); /* ff:ff:ff:ff:ff:ff */                                  return(bcastmac); /* ff:ff:ff:ff:ff:ff */
                         }                          }
                 }                  }
                
                 pbHexMac = (PBYTE) pulMac;                  pbHexMac = (PBYTE) pulMac;
   
                 return (pbHexMac);                  return (pbHexMac);
Line 291  libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP) Line 325  libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
         }          }
 }  }
   
BYTE * libnet_win32_read_arp_table(DWORD DestIP)BYTE *libnet_win32_read_arp_table(DWORD DestIP)
 {  {
        static BYTE buffMAC[6];    static BYTE buffMAC[6];
    BOOL fOrder=TRUE;    BOOL fOrder = TRUE;
        BYTE *MAC=NULL;    DWORD status;
        DWORD status, i, ci; 
     
    PMIB_IPNETTABLE pIpNetTable = NULL; 
        DWORD Size = 0; 
         
        memset(buffMAC, 0, sizeof(buffMAC)); 
   
    if((status = GetIpNetTable(pIpNetTable, &Size, fOrder)) == ERROR_INSUFFICIENT_BUFFER)    MIB_IPNETTABLE *pIpNetTable = NULL;
     DWORD Size = 0;
 
     memset(buffMAC, 0, sizeof(buffMAC));
     status = GetIpNetTable(NULL, &Size, fOrder);
     if (status == ERROR_INSUFFICIENT_BUFFER)
     {      {
        pIpNetTable = (PMIB_IPNETTABLE) malloc(Size);        pIpNetTable = alloca(Size);
        assert(pIpNetTable);         
         status = GetIpNetTable(pIpNetTable, &Size, fOrder);          status = GetIpNetTable(pIpNetTable, &Size, fOrder);
     }      }
   
        if(status == NO_ERROR)    if (status == NO_ERROR)
        { 
                /* set current interface */ 
                ci = pIpNetTable->table[0].dwIndex; 
 
                for (i = 0; i < pIpNetTable->dwNumEntries; ++i) 
                { 
                        if (pIpNetTable->table[i].dwIndex != ci) 
                            ci = pIpNetTable->table[i].dwIndex; 
 
                        if(pIpNetTable->table[i].dwAddr == DestIP) /* found IP in arp cache */ 
                        { 
                                memcpy(buffMAC, pIpNetTable->table[i].bPhysAddr, sizeof(buffMAC)); 
                                free(pIpNetTable); 
                                return buffMAC; 
                        }         
                } 
                   
                if (pIpNetTable) 
            free (pIpNetTable); 
                return(NULL); 
        } 
    else 
     {      {
        if (pIpNetTable)        DWORD i, ci = pIpNetTable->table[0].dwIndex;  /* set current interface */
 
         for (i = 0; i < pIpNetTable->dwNumEntries; ++i)
         {          {
            free (pIpNetTable);            if (pIpNetTable->table[i].dwIndex != ci)
                 ci = pIpNetTable->table[i].dwIndex;
 
             if(pIpNetTable->table[i].dwAddr == DestIP) /* found IP in arp cache */
             {
                 memcpy(buffMAC, pIpNetTable->table[i].bPhysAddr, sizeof(buffMAC));
                 return buffMAC;
             }
         }          }
         MAC=NULL;  
     }      }
   
     return(NULL);      return(NULL);
 }  }
   
/* EOF *//**
  * Local Variables:
  *  indent-tabs-mode: nil
  *  c-file-style: "stroustrup"
  * End:
  */

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>