📄 winip.c
字号:
int l;
printf(" result: physaddr (0x");
for(l = 0; l < len; l++)
{
char blah[3];
printf("%02s", _itoa(OidData->Data[l], blah, 16));
}
printf(") matches %s\n", iftable[i].name);
}
iftable[i].pcapname = a;
break; // Out of the j-loop
}
}
// else ignore the non-Ethernet device
if(i == numifs && wo.trace)
{
int l;
printf(" result: no match (physaddr = 0x");
for(l = 0; l < len; l++)
{
char blah[3];
printf("%02s", _itoa(OidData->Data[l], blah, 16));
}
printf(")\n");
}
}
PacketCloseAdapter(pAdap);
}
static void winip_cleanup(void)
{
free(ipblock);
WSACleanup();
}
// name translation
int name2ifi(const char *name)
{
WINIP_NAME *n = (WINIP_NAME*)bsearch(name, nametable, numifs,
sizeof(WINIP_NAME), strcmp);
if(!n) return -1;
return n->ifi;
}
const char *ifi2name(int ifi)
{
if(ifi < 0 || ifi >= numifs) return 0;
return iftable[ifi].name;
}
int ifi2winif(int ifi)
{
if(ifi < 0 || ifi >= numifs) return -1;
return iftable[ifi].winif;
}
const WINIP_IF* ifi2ifentry(int ifi)
{
if(ifi < 0 || ifi >= numifs) return 0;
return iftable + ifi;
}
static int cmp_uint(const void *e1, const void *e2)
{
return *(DWORD*)e1 - *(DWORD*)e2;
}
int winif2ifi(int winif)
{
WINIP_IF *x = (WINIP_IF*)bsearch(&winif, iftable, numifs,
sizeof(WINIP_IF), cmp_uint);
if(!x) return -1;
return x - iftable;
}
int ifi2ipaddr(int ifi, struct in_addr *addr)
{
if(ifi < 0 || ifi >= numifs) return -1;
if(!iftable[ifi].firstip) return -1;
addr->s_addr = iftable[ifi].firstip->ip;
return 0;
}
int ipaddr2ifi(DWORD ip)
{
// Amusing hack
// Note: this is slow since I see no reason to make it fast
int i;
for(i = 0; i < numips; i++)
{
if(ipblock[i].ip == ip)
return ipblock[i].ifi;
}
return -1;
}
int devname2ipaddr(char *dev, struct in_addr *addr)
{
return ifi2ipaddr(name2ifi(dev), addr);
}
int ipaddr2devname( char *dev, struct in_addr *addr )
{
int ifi = ipaddr2ifi(addr->s_addr);
if(ifi == -1) return -1;
strcpy(dev, iftable[ifi].name);
return 0;
}
static void winip_list_interfaces()
{
int i;
if(inited == 3)
winip_barf(0);
printf("Available interfaces:\n\n");
// 0000000000111111111122222222223333333333
// 0123456789012345678901234567890123456789
printf("Name Raw send Raw recieve IP\n");
for(i = 0; i < numifs; i++)
{
/* char *addr = "(query failed)";
char extra[32];
if(iftable[i].firstip)
addr = inet_ntoa(*(struct in_addr*)&iftable[i].firstip->ip);
if(iftable[i].pcapname)
strcpy(extra, rawsock_avail ? "winpcap, rawsock" : "winpcap");
else strcpy(extra, rawsock_avail ? "rawsock" : "no raw");
printf("%s: %s (%s)\n", iftable[i].name,
addr, extra);
if(o.debugging && iftable[i].pcapname)
printf(iftable[i].pcapname[1] ? " winpcap: %s\n"
: " winpcap: %ls\n", iftable[i].pcapname);*/
IPNODE *ip = iftable[i].firstip;
printf("%-12s%-10s%-13s", iftable[i].name,
(rawsock_avail ? "SOCK_RAW" : (iftable[i].pcapname ? "winpcap" : "none")),
(iftable[i].pcapname ? "winpcap" : (rawsock_avail ? "SOCK_RAW" : "none")));
if(!ip) printf("[none]\n");
else while(ip)
{
if(ip != iftable[i].firstip) printf(" -- ");
printf("%s\n", inet_ntoa(*(struct in_addr*)&ip->ip));
ip = ip->next;
}
if(o.debugging && iftable[i].pcapname)
printf(iftable[i].pcapname[1] ? " winpcap: %s\n"
: " winpcap: %ls\n", iftable[i].pcapname);
}
}
// Find a route to dest. Fill in source, return device
// I will fail this if no raw, so nmap will still work
typedef DWORD (__stdcall *PGBI)(IPAddr, PDWORD);
char *routethrough(struct in_addr *dest, struct in_addr *source)
{
/*
In theory, GetBestInterface is ideal. But we need
the source address. Even though GetBestInterface
is still the fastest way to get the name,
ipaddr2devname is fast enough. So we use
SIO_ROUTING_INTERFACE_QUERY.
*/
// the raw senders tend to iterate this
// so we cache the results
static DWORD last_dest = 0;
static DWORD last_source;
static char dev[128];
struct sockaddr_in sin_dest, sin_source;
winip_test(0);
if(inited == 3)
{
static int warned = 0;
if(!warned)
printf("routethrough: failing due to lack of any raw support\n");
warned = 1;
}
if(last_dest == dest->s_addr)
{
source->s_addr = last_source;
return dev;
}
ZeroMemory(&sin_dest, sizeof(sin_dest));
sin_dest.sin_family = AF_INET;
sin_dest.sin_addr = *dest;
if(wo.nt4route)
{
MIB_IPFORWARDROW ir;
int ifi;
if(0 != get_best_route(sin_dest.sin_addr.s_addr, &ir))
{
if(o.debugging > 1)
printf("get_best_route failed, so routethrough will fail\n");
return NULL;
}
if(-1 == (ifi = winif2ifi(ir.dwForwardIfIndex)))
fatal("routethrough: got unmappable (new?) interface\n");
if(0 != ifi2ipaddr(ifi, &sin_source.sin_addr))
fatal("routethrough: no IP for device %s\n", ifi2name(ifi));
if(!rawsock_avail && !iftable[ifi].pcapname) return NULL;
strcpy(dev, ifi2name(ifi));
}
else
{
SOCKET s;
DWORD br;
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(s == INVALID_SOCKET)
fatal("failed to create socket\n");
if(0 != WSAIoctl(s, SIO_ROUTING_INTERFACE_QUERY,
&sin_dest, sizeof(sin_dest),
&sin_source, sizeof(sin_source), &br, 0, 0))
{
if(o.debugging)
printf("SIO_ROUTING_INTERFACE_QUERY(%s) failed (%d)\n", inet_ntoa(*dest), WSAGetLastError());
closesocket(s);
return NULL;
}
closesocket(s);
}
// localhost scan (fake) support
// this allows localhost, but not 127.0.0.1, scans to seem to work
if(sin_source.sin_addr.s_addr == htonl(INADDR_LOOPBACK))
sin_source.sin_addr.s_addr = dest->s_addr;
if(0 != ipaddr2devname(dev, &sin_source.sin_addr))
{
if(o.debugging)
{
printf("routethrough: %s routes through ", inet_ntoa(*dest));
printf("%s, but inaddr2devname failed\n",
inet_ntoa(sin_source.sin_addr));
}
return 0;
}
if(!rawsock_avail &&
!iftable[ipaddr2ifi(sin_source.sin_addr.s_addr)].pcapname)
return NULL;
last_dest = dest->s_addr;
last_source = sin_source.sin_addr.s_addr;
*source = sin_source.sin_addr;
if(o.debugging > 1)
{
printf("%s will use interface ", inet_ntoa(*(struct in_addr*)&last_dest));
printf("%s\n", inet_ntoa(*(struct in_addr*)&last_source));
}
return dev;
}
// socket and sendto replacements
int win32_sendto(int sd, const char *packet, int len,
unsigned int flags, struct sockaddr *to, int tolen)
{
if(sd == 501)
return pcapsendraw(packet, len, to, tolen);
else return sendto(sd, packet, len, flags, to, tolen);
}
int Sendto(char *functionname, int sd, const unsigned char *packet, int len,
unsigned int flags, struct sockaddr *to, int tolen)
{
return win32_sendto(sd, packet, len, flags, to, tolen);
}
int win32_socket(int af, int type, int proto)
{
SOCKET s;
winip_test(0);
if(type == SOCK_RAW && proto == IPPROTO_RAW && !rawsock_avail)
{
winip_test(1);
pcapsend_init();
return 501;
}
if(o.debugging > 1 && type == SOCK_RAW && proto == IPPROTO_RAW)
printf("Opening a real raw socket\n");
s = socket(af, type, proto);
// Do this here to save a little time
if(type == SOCK_RAW && proto == IPPROTO_RAW) sethdrinclude(s);
return s;
}
void win32_pcap_close(pcap_t *pd)
{
if(-2 != (long)pd) pcap_close(pd);
else rawrecv_close(pd);
}
pcap_t *my_pcap_open_live(char *device, int snaplen, int promisc, int to_ms)
{
int ifi = name2ifi(device);
if(ifi == -1)
fatal("my_pcap_open_live: invalid device %s\n");
winip_test(1);
if(iftable[ifi].pcapname)
return my_real_pcap_open_live(device, snaplen, promisc, to_ms);
else if(rawsock_avail)
{
if(promisc)
fatal("promiscuous capture not available on non-pcap device %s\n", device);
return rawrecv_open(device);
}
else
fatal(winbug ? "%s: rawsock disabled to avoid BSOD\n"
: "%s: no raw access\n", device);
return 0; // to make the compiler happy
}
int winip_corruption_possible()
{
return rawsock_avail; // for now
}
inline void sethdrinclude(int sd)
{
int one = 1;
if(sd != 501)
{
// error("sethdrinclude called -- this probably shouldn't happen\n");
setsockopt(sd, IPPROTO_IP, IP_HDRINCL, (void *) &one, sizeof(one));
}
}
char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec)
{
if(-2 == (long)pd)
return rawrecv_readip(pd, len, to_usec);
else return readip_pcap_real(pd, len, to_usec);
}
void set_pcap_filter(struct hoststruct *target,
pcap_t *pd, PFILTERFN filter, char *bpf, ...)
{
va_list ap;
char buf[512];
struct bpf_program fcode;
unsigned int localnet, netmask;
char err0r[256];
if(-2 == (long)pd)
{
rawrecv_setfilter(pd, filter);
return;
}
if (pcap_lookupnet(target->device, &localnet, &netmask, err0r) == -1)
; /* fatal("Failed to lookup device subnet/netmask: %s", err0r);*/
va_start(ap, bpf);
vsprintf(buf, bpf, ap);
va_end(ap);
if (o.debugging)
log_write(LOG_STDOUT, "Packet capture filter: %s\n", buf);
/* Due to apparent bug in libpcap */
if (islocalhost(&(target->host)))
buf[0] = '\0';
if (pcap_compile(pd, &fcode, buf, 0, netmask) < 0)
fatal("Error compiling our pcap filter: %s\n", pcap_geterr(pd));
if (pcap_setfilter(pd, &fcode) < 0 )
fatal("Failed to set the pcap filter: %s\n", pcap_geterr(pd));
}
#ifdef _MSC_VER
static FARPROC WINAPI winip_dli_fail_hook(unsigned code, PDelayLoadInfo info)
{
if(wo.trace)
{
printf("***WinIP*** delay load error:\n");
switch(code)
{
case dliFailLoadLib:
printf(" failed to load dll: %s\n", info->szDll);
break;
case dliFailGetProc:
printf(" failed to load ");
if(info->dlp.fImportByName)
printf("function %s", info->dlp.szProcName + 2);
else printf("ordinal %d", info->dlp.dwOrdinal);
printf(" in dll %s\n", info->szDll);
break;
default:
printf(" unknown error\n");
break;
}
}
if(dli_done)
{
printf("******* Unexpected delay-load failure *******\n");
switch(code)
{
case dliFailLoadLib:
printf(" failed to load dll: %s\n", info->szDll);
if(!stricmp(info->szDll, "wpcap.dll"))
printf(" this is most likely because you have"
" winpcap 2.0 (2.1 or later is required)\n"
"Get it from http://netgroup-serv.polito.it/winpcap\n");
break;
case dliFailGetProc:
printf(" failed to load ");
if(info->dlp.fImportByName)
printf("function %s", info->dlp.szProcName + 2);
else printf("ordinal %d", info->dlp.dwOrdinal);
printf(" in dll %s\n", info->szDll);
break;
default:
printf(" unknown error\n");
break;
}
}
return 0;
}
#endif // _MSC_VER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -