实现
main.cpp
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include "base.h"
WSADATA wsa_data;
SOCKET sniffer_socket = INVALID_SOCKET;
IP_PACKET packet;
char hostname[512];
hostent* local;
in_addr addr;
sockaddr_in src,dst;
DWORD optbuf[10];
DWORD optret;
DWORD optval = 1;
int addrlen = sizeof(sockaddr_in);
int ret;
int main(int argc,char* argv[])
{
ret = WSAStartup(MAKEWORD(2,2),&wsa_data);
if(ret != 0)
{
printf("初始化Windows Socket2失败\n");
return 1;
}
sniffer_socket = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
if(sniffer_socket == INVALID_SOCKET)
{
printf("创建套接字失败\n");
WSACleanup();
return 1;
}
ret = gethostname(hostname,sizeof(hostname));
if(ret != 0)
{
printf("获取主机名失败\n");
WSACleanup();
return 1;
}
local = gethostbyname(hostname);
if(local == NULL)
{
printf("获取本机IP地址失败\n");
WSACleanup();
return 1;
}
printf("IP地址列表:\n");
int i = 0;
while(local->h_addr_list[i] != 0)
{
addr.S_un.S_addr = *(unsigned long*)local->h_addr_list[i];
printf("\t%d:\t%s\n",i+1,inet_ntoa(addr));
i++;
}
printf("请输入IP地址序号:\n");
scanf("%d",&i);
memset(&dst,0,sizeof(dst));
memcpy(&dst.sin_addr.S_un.S_addr,local->h_addr_list[i-1],sizeof(dst.sin_addr.S_un.S_addr));
dst.sin_family = AF_INET;
dst.sin_port = 0;
ret = bind(sniffer_socket,(sockaddr*)&dst,sizeof(dst));
if(ret == SOCKET_ERROR)
{
printf("绑定本地IP地址失败\n");
WSACleanup();
return 1;
}
ret = WSAIoctl(sniffer_socket,0x98000001,&optval,sizeof(optval),&optbuf,sizeof(optbuf),&optret,NULL,NULL);
if(ret == SOCKET_ERROR)
{
printf("设置网卡为混杂模式失败\n");
WSACleanup();
return 1;
}
do
{
ret = recvfrom(sniffer_socket,(char*)&packet,sizeof(packet),0,(sockaddr*)&src,&addrlen);
if(ret >0)
{
printf("\n");
printf("获取到IP数据包\n");
printf("源IP地址:%s\n",inet_ntoa(packet.IPHeader.Src));
printf("目的IP地址:%s\n",inet_ntoa(packet.IPHeader.Dst));
printf("IP头长度:%d\n",packet.IPHeader.Len);
printf("数据包长度:%d\n",packet.IPHeader.TotLen);
printf("协议:%s\n",GetProtocol(&packet.IPHeader));
}
else
{
printf("接收数据包失败\n");
WSACleanup();
return 1;
}
}while(true);
WSACleanup();
return 0;
}
base.h
#ifndef _BASE_H
#define _BASE_H
typedef struct tagIP_HEADER
{
unsigned char Len:4;
unsigned char Ver:4;
unsigned char TOS;
unsigned short TotLen;
unsigned short ID;
unsigned short FlagOff;
unsigned char TTL;
unsigned char Protocol;
unsigned short Checksum;
in_addr Src;
in_addr Dst;
}IP_HEADER, *LPIP_HEADER;
#pragma pack(push)
#pragma pack(1)
typedef struct tagIP_PACKET
{
IP_HEADER IPHeader;
char data[65515];
}IP_PACKET, *LPIP_PACKET;
#pragma pack(pop)
const char* strTCP = "TCP协议";
const char* strUDP = "UDP协议";
const char* strICMP = "ICMP协议";
const char* strUnknown = "未知协议";
const char* GetProtocol(LPIP_HEADER iphdr)
{
switch(iphdr->Protocol)
{
case 1:
return strICMP;
break;
case 6:
return strTCP;
break;
case 17:
return strUDP;
break;
default:
return strUnknown;
break;
}
}
#endif