用C实现网卡侦听.doc

上传人:数据九部 文档编号:10246944 上传时间:2021-05-02 格式:DOC 页数:9 大小:965.50KB
返回 下载 相关 举报
用C实现网卡侦听.doc_第1页
第1页 / 共9页
用C实现网卡侦听.doc_第2页
第2页 / 共9页
用C实现网卡侦听.doc_第3页
第3页 / 共9页
用C实现网卡侦听.doc_第4页
第4页 / 共9页
用C实现网卡侦听.doc_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《用C实现网卡侦听.doc》由会员分享,可在线阅读,更多相关《用C实现网卡侦听.doc(9页珍藏版)》请在三一文库上搜索。

1、物联网工程学院实验报告课程名称 计算机网络 实验名称 网卡侦听 实验日期 2012- 5 - 1 班级 计科 姓名 学号 0304实验报告要求 1实验名称 2实验要求 3实验环境 4实验步骤(写明实验结果) 5实验体会 实验2 编程实现网卡侦听程序代码:#include#include#include#include mstcpip.h#pragma comment(lib,ws2_32.lib)#define STATUS_FAILED 0xFFFF /定义异常出错代码#define MAX_PACK_LEN 65535 /接收的最大IP报文#define MAX_ADDR_LEN 16/点

2、分十进制地址的最大长度#define MAX_PROTO_TEXT_LEN 16/子协议名称(如TCP)最大长度#define MAX_PROTO_NUM 12/子协议数量#define MAX_HOSTNAME_LAN 255/最大主机名长度#define CMD_PARAM_HELP truetypedef struct _iphdr/定义IP头部unsigned char h_lenver;/4位首部长度+4位IP版本号unsigned char tos;/8位服务类型TOSunsigned short total_len;/16位总长度(字节)unsigned short ident;

3、/16位标识unsigned short frag_and_flags;/3位标志位unsigned char ttl;/8位生存时间TTLunsigned char proto;/8位协议(TCP,UDP或其他)unsigned short checksum;/16位IP首部校验和unsigned int sourceIP;/32位源IP地址unsigned int destIP;/32位目的IP地址IP_HEADER;typedef struct _tcphdr/定义TCP首部USHORT th_sport;/16位源端口USHORT th_dport;/16位目的端口unsigned i

4、nt th_seq;/32位序列号unsigned int th_ack;/32位确认号unsigned char th_lenres;/4位首部长度/6位保留字unsigned char th_flag;/6位标志位USHORT th_win;/16位窗口大小USHORT th_sum;/16位校验和USHORT th_urp;/16位紧急数据偏移量TCP_HEADER;typedef struct _udphdr/定义UDP首部unsigned short uh_sport;/16位源端口unsigned short uh_dport;/16位目的端口unsigned short uh_l

5、en;/16位长度unsigned short un_sum;/16位校验和UDP_HEADER;typedef struct _icmphdr/定义ICMP首部BYTE i_type;/8位类型BYTE i_code;/8位代码USHORT i_cksum;/16位校验和USHORT i_id;/识别号(一般用进程号作为识别号)USHORT i_seq;/报文序列号ULONG timestamp;/时间戳ICMP_HEADER;typedef struct _protomap/定义子协议映射表int ProtoNum;char ProtoTextMAX_PROTO_TEXT_LEN;PROT

6、OMAP;PROTOMAP ProtoMapMAX_PROTO_NUM=/为子协议映射表赋值IPPROTO_IP,IP,IPPROTO_ICMP,ICMP,IPPROTO_IGMP,IGMP,IPPROTO_GGP,GGP,IPPROTO_TCP,TCP,IPPROTO_PUP,PUP,IPPROTO_UDP,UDP,IPPROTO_IDP,IDP,IPPROTO_ND,NP,IPPROTO_RAW,RAW,IPPROTO_MAX,MAX,NULL,;SOCKET SockRaw;char TcpFlag6=F,S,R,P,A,U; /定义TCP标志位bool ParamTcp=false;

7、/关注TCP报文bool ParamUdp=false;/关注UDP报文bool ParamIcmp=false;/关注ICMP报文bool ParamDecode=true;/对协议进行解码char *strFromIpFilter=NULL; /源IP地址过滤char *strDestIpFilter=NULL; /目的地址过滤int DecodeIpPack(char*,int);/IP解码函数int DecodeTcpPack(char*);/TCP解码函数int DecodeUdpPack(char*);/UDP解码函数int DecodeIcmpPack(char*);/ICMP解

8、码函数void GetFtp(char *);void CheckSockError(int,char*);/错误检测函数char *CheckProtocol(int);/协议检测函数void usage(void);/帮助函数bool GetCmdLine(int,char*);/获取命令行函数void main(int argc,char* argv)int iErrorCode;char RecvBufMAX_PACK_LEN=0;/接收缓冲区usage();/调用使用说明if(GetCmdLine(argc,argv)=CMD_PARAM_HELP) exit(0);/初始化SOCK

9、ET,判断命令行接收函数WSADATA wsaData; iErrorCode=WSAStartup(MAKEWORD(2,1),&wsaData);CheckSockError(iErrorCode,WSAStartup);/建立Socket。属性必须是AF_INET(Ipv4协议)、/SOCK_RAW(原始套接字,即底层IP)、IPPROTO_IP(自己构造IP头),/否则不能设子SIP_RCVALL(混杂模式)属性SockRaw=socket(AF_INET,SOCK_RAW,IPPROTO_IP);CheckSockError(SockRaw,socket);/获取本机IP地址,并判断

10、socket版本,建立原始套接字char FAR nameMAX_HOSTNAME_LAN;iErrorCode=gethostname(name,MAX_HOSTNAME_LAN);/得到本地主机名CheckSockError(iErrorCode,gethostname);struct hostent FAR *pHostent;pHostent=(struct hostent*)malloc(sizeof(struct hostent);pHostent=gethostbyname(name);/获得给定主机名信息SOCKADDR_INsa;sa.sin_family=AF_INET;/

11、设置协议族sa.sin_port=htons(6000);/设置端口memcpy(&sa.sin_addr.S_un.S_addr,pHostent-h_addr_list0,pHostent-h_length);/绑定本机IP地址。首先获得本机主机名,在根据本地名获得本地IP地址。 /注意不能使用参数INADDR_ANY,而是PSOCKADDR。iErrorCode=bind(SockRaw,(PSOCKADDR)&sa,sizeof(sa); /绑定CheckSockError(iErrorCode,bind); /设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包DWORD

12、 dwBufferLen10;DWORD dwBufferInLen=1;DWORD dwBytesReturned=0;/设置混杂模式。下面使用WSAIcotl函数给一个SOCK_RAW类型的socket设置/SIO_RCVALL混杂模式,这样该socket就可以收到所以经过本机的数据iErrorCode=WSAIoctl(SockRaw,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL); CheckSockError(iEr

13、rorCode,Ioctl);/侦听IP报文while(1)/1永远为真,不断循环抓包memset(RecvBuf,0,sizeof(RecvBuf);/强制RecvBuf缓冲区数据为0/获取数据包,开始接收缓冲区数据iErrorCode=recv(SockRaw,RecvBuf,sizeof(RecvBuf),0);CheckSockError(iErrorCode,recv);iErrorCode=DecodeIpPack(RecvBuf,iErrorCode);/开始从缓冲区解码CheckSockError(iErrorCode,Decode);/IP解包程序int DecodeIpPa

14、ck(char *buf,int iBufSize)IP_HEADER *pIpheader;int iProtocol,iTTL;/定义协议,生存时间char szProtocolMAX_PROTO_TEXT_LEN;char szSourceIPMAX_ADDR_LEN,szDestIPMAX_ADDR_LEN;SOCKADDR_IN saSource,saDest;/定义原目标和目的结构pIpheader=(IP_HEADER*)buf;/检测协议是哪种协议/如果命令行指定了IP协议,则校验协议,否则跳出iProtocol=pIpheader-proto;strncpy(szProtoc

15、ol,CheckProtocol(iProtocol),MAX_PROTO_TEXT_LEN);if(iProtocol=IPPROTO_TCP)&(!ParamTcp) return true;if(iProtocol=IPPROTO_UDP)&(!ParamUdp) return true;if(iProtocol=IPPROTO_ICMP)&(!ParamIcmp) return true; /判断协议类型,返回true/检测源IP,不是命令行所给的IP,则跳出 saSource.sin_addr.s_addr=pIpheader-sourceIP;strncpy(szSourceIP,

16、inet_ntoa(saSource.sin_addr),MAX_ADDR_LEN);if(strFromIpFilter)if(strcmp(strFromIpFilter,szSourceIP) return true;/检测目标IP,不是命令行所给的IP,则跳出saDest.sin_addr.s_addr=pIpheader-destIP;strncpy(szDestIP,inet_ntoa(saDest.sin_addr),MAX_ADDR_LEN);if(strDestIpFilter)if(strcmp(strDestIpFilter,szDestIP) return true;i

17、TTL=pIpheader-ttl;/输出包信息printf(%s ,szProtocol);printf( %s-%s ,szSourceIP,szDestIP);printf( bytes=%d TTL=%d ,iBufSize,iTTL);/计算IP头长度int iIphLen=sizeof(unsigned long)*(pIpheader-h_lenver&0xf);/解码信息协议:TCP,UDP,ICMP,etcswitch(iProtocol)case IPPROTO_TCP:DecodeTcpPack(buf+iIphLen);break;case IPPROTO_UDP:De

18、codeUdpPack(buf+iIphLen);break;case IPPROTO_ICMP:DecodeIcmpPack(buf+iIphLen);break;default:break;/通过判断协议。然后用于不同的解码return true;/SOCK错误处理程序void CheckSockError(int iErrorCode,char *pErrorMsg)if(iErrorCode)=SOCKET_ERROR) printf(%s Error:%dn,pErrorMsg,GetLastError();closesocket(SockRaw);exit(0);/协议识别程序ch

19、ar *CheckProtocol(int iProtocol)for(int i=0;i%dn,ntohs(pTcpHeader-th_sport),ntohs(pTcpHeader-th_dport);if (ntohs(pTcpHeader-th_dport)=21)GetFtp(char*)pTcpHeader+sizeof(TCP_HEADER); /打印源端口和目标端口unsigned char FlagMask=1;for(i=0;ith_flag)&FlagMask) printf(%c,TcpFlagi);else printf(-);FlagMask=FlagMask%dn

20、,ntohs(pUdpHeader-uh_sport),ntohs(pUdpHeader-uh_dport);/打印源端口和目标端口printf(Len=%dn,ntohs(pUdpHeader-uh_len);/显示包长度return true;/ICMP解包程序int DecodeIcmpPack(char *IcmpBuf)ICMP_HEADER *pIcmpHeader;pIcmpHeader=(ICMP_HEADER*)IcmpBuf;/指针指向ICMP数据包缓冲printf( Type:%d ,pIcmpHeader-i_type,pIcmpHeader-i_code);print

21、f( ID=%d SEQ=%dnn,pIcmpHeader-i_id,pIcmpHeader-i_seq);return true;/命令行参数处理bool GetCmdLine(int argc,char* argv)if(argc2) return CMD_PARAM_HELP;for(int i=1;iargc;i+)if(argvi0!=/) return CMD_PARAM_HELP;else switch(argvi1)case t:case T:ParamTcp=true;break;case u:case U:ParamUdp=true;break;case i:case I:

22、ParamIcmp=true;break;case p:case P:ParamDecode=true;break;case f:case F:strFromIpFilter=(char*)malloc(16*sizeof(char);memset(strFromIpFilter,0,16*sizeof(char);strcpy(strFromIpFilter,argvi+3);break;case d:case D:strDestIpFilter=(char*)malloc(16*sizeof(char);memset(strDestIpFilter,0,16*sizeof(char);st

23、rcpy(strDestIpFilter,argvi+3);break;printf(n Will Sniffer);if(ParamTcp) printf(TCP);if(ParamUdp) printf(UDP);if(ParamIcmp) printf(ICMP);if(strFromIpFilter) printf(FromIp:%s,strFromIpFilter);if(strDestIpFilter) printf(DestIp:%s,strDestIpFilter);printf(ntCTRL+C to quitnStart:n);return(!CMD_PARAM_HELP);/使用说明void usage(void)printf(sniffer 程序n);printf(使用说明:n); printf(t/t输出TCP包n);printf(t/u输出UDP包n);printf(t/i输出ICMP包n);printf(t/p解包(默认为OFF)n);printf(t/f:fromIP源IP,默认为所有的n);printf(t/d:destIP目标IP,默认为所有);教师评价 优良 中及格不及格教师签名日期

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 科普知识


经营许可证编号:宁ICP备18001539号-1