Annotation of embedaddon/libnet/src/libnet_link_win32.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *  $Id: libnet_link_win32.c,v 1.16 2004/02/18 18:19:00 mike Exp $
                      3:  *
                      4:  *  libnet
                      5:  *  libnet_link_win32.c - low-level win32 libwpcap routines
                      6:  *
                      7:  *  Copyright (c) 2001 - 2002 Don Bowman <don@sandvine.com>
                      8:  *  Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
                      9:  *  Copyright (c) 2002 Roberto Larcher <roberto.larcher@libero.it>
                     10:  *  All rights reserved.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  *
                     33:  */
                     34: 
                     35: #if (HAVE_CONFIG_H)
                     36: #include "../include/config.h"
                     37: #endif
                     38: #include <winsock2.h>
                     39: #include <iphlpapi.h> // From the Microsoft Platform SDK 
                     40: #include "../include/win32/libnet.h"
                     41: #include <assert.h>
                     42: #include <Packet32.h>
                     43: #include <Ntddndis.h>
                     44: #include "iprtrmib.h"
                     45: 
                     46: int
                     47: libnet_open_link(libnet_t *l)
                     48: {
                     49:     DWORD dwErrorCode;
                     50:     NetType IFType;
                     51: 
                     52:     if (l == NULL)
                     53:     { 
                     54:         return (-1);
                     55:     } 
                     56: 
                     57:     if (l->device == NULL)
                     58:     {
                     59:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                     60:                 "%s(): NULL device\n", __func__);
                     61:         return (-1);
                     62:     }
                     63: 
                     64:     l->lpAdapter = 0;
                     65: 
                     66:     /* open adapter */
                     67:        l->lpAdapter = PacketOpenAdapter(l->device);
                     68:     if (!l->lpAdapter || (l->lpAdapter->hFile == INVALID_HANDLE_VALUE))
                     69:     {
                     70:         dwErrorCode=GetLastError();
                     71:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                     72:                 "%s(): unable to open the driver, error Code : %lx\n",
                     73:                 __func__, dwErrorCode); 
                     74:         return (-1);
                     75:     }
                     76:        
                     77:     /* increase the send buffer */
                     78:     PacketSetBuff(l->lpAdapter, 512000);
                     79: 
                     80:     /*
                     81:      *  Assign link type and offset.
                     82:      */
                     83:     if (PacketGetNetType(l->lpAdapter, &IFType))
                     84:     {
                     85:         switch(IFType.LinkType)
                     86:         {
                     87:             case NdisMedium802_3:
                     88:                                l->link_type = DLT_EN10MB;
                     89:                                l->link_offset = LIBNET_ETH_H;
                     90:                 break;
                     91:                        case NdisMedium802_5:
                     92:                                l->link_type = DLT_IEEE802;
                     93:                                l->link_offset = LIBNET_TOKEN_RING_H;
                     94:                                break;
                     95:                        case NdisMediumFddi:
                     96:                                l->link_type = DLT_FDDI;
                     97:                                l->link_offset = 0x15;
                     98:                                break;
                     99:                        case NdisMediumWan:
                    100:                                snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    101:                  "%s():, WinPcap has disabled support for Network type (%d)\n",
                    102:                  __func__, IFType.LinkType);
                    103:                                return (-1);
                    104:                                break;
                    105:                        case NdisMediumAtm:
                    106:                                l->link_type = DLT_ATM_RFC1483;
                    107:                                break;
                    108:                        case NdisMediumArcnet878_2:
                    109:                                l->link_type = DLT_ARCNET;
                    110:                                break;
                    111:                        default:
                    112:                 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    113:                          "%s(): network type (%d) is not supported\n",
                    114:                          __func__, IFType.LinkType);
                    115:                 return (-1);
                    116:                 break;
                    117:         }
                    118:     }
                    119:     else
                    120:     {
                    121:         dwErrorCode=GetLastError();
                    122:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    123:             "%s(): unable to determine the network type, error Code : %lx\n",
                    124:                 __func__, dwErrorCode);
                    125:         return (-1);
                    126:     }
                    127:     return (1);
                    128: }
                    129: 
                    130: int
                    131: libnet_close_link_interface(libnet_t *l)
                    132: {
                    133:     if (l->lpAdapter)
                    134:     {
                    135:         PacketSetHwFilter(l->lpAdapter, NDIS_PACKET_TYPE_ALL_LOCAL);
                    136:         PacketCloseAdapter(l->lpAdapter);
                    137:     }
                    138:     return (1);
                    139: }
                    140: 
                    141: int
                    142: libnet_write_link(libnet_t *l, u_int8_t *packet, u_int32_t size)
                    143: {
                    144:     LPPACKET   lpPacket;
                    145:     DWORD      BytesTransfered;        
                    146: 
                    147:     BytesTransfered = -1;
                    148: 
                    149:     if ((lpPacket = PacketAllocatePacket()) == NULL)
                    150:     {
                    151:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    152:                 "%s(): failed to allocate the LPPACKET structure\n", __func__);
                    153:                return (-1);
                    154:     }
                    155:     PacketInitPacket(lpPacket, packet, size);
                    156: 
                    157:     /* PacketSendPacket returns a BOOLEAN */
                    158:     if(PacketSendPacket(l->lpAdapter, lpPacket, TRUE))
                    159:     {
                    160:            BytesTransfered = size;
                    161:     }
                    162:        
                    163:     PacketFreePacket(lpPacket);
                    164:     return (BytesTransfered);
                    165:  }
                    166: 
                    167: struct libnet_ether_addr *
                    168: libnet_get_hwaddr(libnet_t *l)
                    169: {
                    170:     /* This implementation is not-reentrant. */
                    171:     static struct libnet_ether_addr *mac;
                    172:     
                    173:     ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA) + sizeof(ULONG) - 1);
                    174:        PPACKET_OID_DATA OidData;
                    175:        
                    176:        int i = 0;
                    177: 
                    178:        if (l == NULL)
                    179:     { 
                    180:         return (NULL);
                    181:     } 
                    182: 
                    183:        if (l->device == NULL)
                    184:     {           
                    185:         if (libnet_select_device(l) == -1)
                    186:         {   
                    187:             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    188:                     "%s(): can't figure out a device to use\n", __func__);
                    189:             return (NULL);
                    190:         }
                    191:     }
                    192: 
                    193:     mac = (struct libnet_ether_addr *)calloc(1,sizeof(struct libnet_ether_addr));
                    194:        if (mac == NULL)
                    195:        {
                    196:                snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    197:                     "%s(): calloc error\n", __func__);
                    198:                return (NULL);
                    199:        }
                    200: 
                    201:     OidData = (struct _PACKET_OID_DATA *) malloc(IoCtlBufferLength);
                    202:        
                    203:        if (OidData == NULL)
                    204:        {
                    205:             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    206:                                 "%s(): OidData is NULL\n", __func__);
                    207:            return(NULL);
                    208:        }
                    209: 
                    210:        if (l->link_type == DLT_IEEE802)
                    211:        {
                    212:                OidData->Oid = OID_802_5_CURRENT_ADDRESS;       
                    213:        }
                    214:        else
                    215:        {
                    216:                OidData->Oid = OID_802_3_CURRENT_ADDRESS;       
                    217:        }
                    218:        
                    219:        OidData->Length = 6;
                    220:        if((PacketRequest(l->lpAdapter, FALSE, OidData)) == FALSE)
                    221:        {
                    222:                memset(mac, 0, 6);
                    223:        }
                    224:        else
                    225:        {
                    226:                for (i = 0; i < 6; i++)
                    227:                {
                    228:                        mac->ether_addr_octet[i] = OidData->Data[i];
                    229:                }
                    230:        }
                    231:         free(OidData);
                    232:        return(mac);
                    233: }
                    234: 
                    235: struct hostent *gethostbyname2(const int8_t *name, int af) 
                    236: {
                    237:    // XXX not implemented
                    238:    return(NULL);
                    239: }
                    240: 
                    241: BYTE *
                    242: libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
                    243: {
                    244:        HRESULT hr;
                    245:     ULONG   pulMac[6];
                    246:     ULONG   ulLen = 6;
                    247:        static PBYTE pbHexMac;
                    248:        PIP_ADAPTER_INFO pinfo = NULL;
                    249:        DWORD dwSize = 0;
                    250:        struct sockaddr_in sin;
                    251:        static BYTE bcastmac[]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
                    252: 
                    253:        BYTE *MAC = libnet_win32_read_arp_table(DestIP);
                    254:        
                    255:        if (MAC==NULL)
                    256:        {
                    257:                memset(pulMac, 0xff, sizeof (pulMac));
                    258:                memset(&sin, 0, sizeof(sin));
                    259:            
                    260:                if((hr = SendARP (DestIP, 0, pulMac, &ulLen)) != NO_ERROR)
                    261:                {
                    262:                        *(int32_t *)&sin.sin_addr = DestIP;
                    263:                        GetAdaptersInfo(NULL, &dwSize);
                    264:                        pinfo = (PIP_ADAPTER_INFO)GlobalAlloc(GPTR, dwSize);
                    265:                        GetAdaptersInfo(pinfo, &dwSize);
                    266:                        if(pinfo != NULL)
                    267:                        {
                    268:                                DestIP = inet_addr(pinfo->GatewayList.IpAddress.String);
                    269:                                memset (pulMac, 0xff, sizeof (pulMac));
                    270:                                ulLen = 6;
                    271:                                if((hr = SendARP (DestIP, 0, pulMac, &ulLen)) != NO_ERROR)
                    272:                                {
                    273:                                        GlobalFree(pinfo);
                    274:                                        return(bcastmac);
                    275:                                }
                    276:                        }
                    277:                        else
                    278:                        {
                    279:                                GlobalFree(pinfo);
                    280:                                return(bcastmac); /* ff:ff:ff:ff:ff:ff */
                    281:                        }
                    282:                }
                    283:                
                    284:                pbHexMac = (PBYTE) pulMac;
                    285: 
                    286:                return (pbHexMac);
                    287:        }
                    288:        else
                    289:        {
                    290:                return (MAC);
                    291:        }
                    292: }
                    293: 
                    294: BYTE * libnet_win32_read_arp_table(DWORD DestIP)
                    295: {
                    296:        static BYTE buffMAC[6];
                    297:     BOOL fOrder=TRUE;
                    298:        BYTE *MAC=NULL;
                    299:        DWORD status, i, ci;
                    300:     
                    301:     PMIB_IPNETTABLE pIpNetTable = NULL;
                    302:        DWORD Size = 0;
                    303:        
                    304:        memset(buffMAC, 0, sizeof(buffMAC));
                    305: 
                    306:     if((status = GetIpNetTable(pIpNetTable, &Size, fOrder)) == ERROR_INSUFFICIENT_BUFFER)
                    307:     {
                    308:         pIpNetTable = (PMIB_IPNETTABLE) malloc(Size);
                    309:         assert(pIpNetTable);        
                    310:         status = GetIpNetTable(pIpNetTable, &Size, fOrder);
                    311:     }
                    312: 
                    313:        if(status == NO_ERROR)
                    314:        {
                    315:                // set current interface
                    316:                ci = pIpNetTable->table[0].dwIndex;
                    317: 
                    318:                for (i = 0; i < pIpNetTable->dwNumEntries; ++i)
                    319:                {
                    320:                        if (pIpNetTable->table[i].dwIndex != ci)
                    321:                            ci = pIpNetTable->table[i].dwIndex;
                    322: 
                    323:                        if(pIpNetTable->table[i].dwAddr == DestIP) // found IP in arp cache
                    324:                        {
                    325:                                memcpy(buffMAC, pIpNetTable->table[i].bPhysAddr, sizeof(buffMAC));
                    326:                                free(pIpNetTable);
                    327:                                return buffMAC;
                    328:                        }        
                    329:                }
                    330:                  
                    331:                if (pIpNetTable)
                    332:             free (pIpNetTable);
                    333:                return(NULL);
                    334:        }
                    335:     else
                    336:     {
                    337:         if (pIpNetTable)
                    338:         {
                    339:             free (pIpNetTable);
                    340:         }
                    341:         MAC=NULL;
                    342:     }
                    343:     return(NULL);
                    344: }
                    345: 
                    346: /* EOF */

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