thus i use winpcap,these are some code:typedef struct _ETH_HEADER { __u8 h_dest[6]; __u8 h_source[6]; __u16 h_proto; }ETH_HEADER; typedef struct _IP_HEADER { __u8 h_lenver;//4位首部长度+4位IP版本号 __u8 tos;//8位服务类型TOS __u16 tot_len;//16位总长度(字节) __u16 id;//16位标识 __u16 frag_off;//3位标志位 __u8 ttl;//8位生存时间 TTL __u8 protocol;//8位协议 (TCP, UDP 或其他) __u16 check;//16位IP首部校验和 __u32 saddr;//32位源IP地址 __u32 daddr;//32位目的IP地址 }IP_HEADER; typedef struct _TCP_HEADER { __u16 source;//16位源端口 __u16 dest;//16位目的端口 __u32 seq;//32位序列号 __u32 ack_seq;//32位确认号 __u8 th_lenres;//4位首部长度/6位保留字 __u8 th_flag;//6位标志位 __u16 window;//16位窗口大小 __u16 check;//16位校验和 __u16 urg_ptr;//16位紧急数据偏移量 }TCP_HEADER; //for more details you can consult winpcap example "testApp.exe" char *pChar; struct bpf_hdr *hdr; char *buf=(char*)lpPacket->Buffer;//lpPacket point for packet that you receivedUINT off=0;hdr=(struct bpf_hdr *)(buf+off); off+=hdr->bh_hdrlen; pChar =(char*)(buf+off); // pChar中指向的才是报文数据。 ////////////////////////////////////////////////////// ETHER_PACKET *pEthPkt = (ETHER_PACKET *) lpPacket->Buffer; ETH_HEADER *pEthHdr = (ETH_HEADER *) pChar; IP_HEADER *pIpHdr = (IP_HEADER *) (pChar+sizeof(ETH_HEADER)); int i_IPH_Size = 20;//pIpHdr->ihl * 4; TCP_HEADER *pTcpHdr = (TCP_HEADER *) ((char *) pIpHdr + i_IPH_Size); int i_TCPH_Size = 20;//pTcpHdr->doff * 4;
给个结构自己去解析吧 struct ip { #if BYTE_ORDER == LITTLE_ENDIAN u_char ip_hl:4, /* header length */ ip_v:4; /* version */ #else u_char ip_v:4, /* version */ ip_hl:4; /* header length */ #endif u_char ip_tos; /* type of service */ short ip_len; /* total length */ u_short ip_id; /* identification */ short ip_off; /* fragment offset field */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* checksum */ in_addr ip_src,ip_dst; /* source and dest address */ };
int DecodeIPHeader(WSABUF *wsabuf, unsigned int srcip, unsigned short srcport, unsigned int destip, unsigned short destport) { BYTE *hdr = (BYTE *)wsabuf->buf, *nexthdr = NULL; unsigned short shortval; SOCKADDR_IN srcaddr, destaddr;
其实就是一个结构体与共用体的问题
如果 详解上面没有的协议就参看 RFC : http://www.rfc-editor.org/
2 如果懒点的话直接找代码,linux下关于网络的很多OpenSource都有类似
代码,例如: libnet,libnids,snort
{
__u8 h_dest[6];
__u8 h_source[6];
__u16 h_proto;
}ETH_HEADER;
typedef struct _IP_HEADER
{
__u8 h_lenver;//4位首部长度+4位IP版本号
__u8 tos;//8位服务类型TOS
__u16 tot_len;//16位总长度(字节)
__u16 id;//16位标识
__u16 frag_off;//3位标志位
__u8 ttl;//8位生存时间 TTL
__u8 protocol;//8位协议 (TCP, UDP 或其他)
__u16 check;//16位IP首部校验和
__u32 saddr;//32位源IP地址
__u32 daddr;//32位目的IP地址
}IP_HEADER;
typedef struct _TCP_HEADER
{
__u16 source;//16位源端口
__u16 dest;//16位目的端口
__u32 seq;//32位序列号
__u32 ack_seq;//32位确认号
__u8 th_lenres;//4位首部长度/6位保留字
__u8 th_flag;//6位标志位
__u16 window;//16位窗口大小
__u16 check;//16位校验和
__u16 urg_ptr;//16位紧急数据偏移量
}TCP_HEADER;
//for more details you can consult winpcap example "testApp.exe"
char *pChar;
struct bpf_hdr *hdr;
char *buf=(char*)lpPacket->Buffer;//lpPacket point for packet that you receivedUINT off=0;hdr=(struct bpf_hdr *)(buf+off);
off+=hdr->bh_hdrlen;
pChar =(char*)(buf+off); // pChar中指向的才是报文数据。
//////////////////////////////////////////////////////
ETHER_PACKET *pEthPkt = (ETHER_PACKET *) lpPacket->Buffer;
ETH_HEADER *pEthHdr = (ETH_HEADER *) pChar;
IP_HEADER *pIpHdr = (IP_HEADER *) (pChar+sizeof(ETH_HEADER));
int i_IPH_Size = 20;//pIpHdr->ihl * 4;
TCP_HEADER *pTcpHdr = (TCP_HEADER *) ((char *) pIpHdr + i_IPH_Size);
int i_TCPH_Size = 20;//pTcpHdr->doff * 4;
struct ip {
#if BYTE_ORDER == LITTLE_ENDIAN
u_char ip_hl:4, /* header length */
ip_v:4; /* version */
#else
u_char ip_v:4, /* version */
ip_hl:4; /* header length */
#endif
u_char ip_tos; /* type of service */
short ip_len; /* total length */
u_short ip_id; /* identification */
short ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
in_addr ip_src,ip_dst; /* source and dest address */
};
写得比较清楚。
我愿意拿出100分来寻《用TCPIP实现网络互连》和具体解析IP数据包头
unsigned int destip, unsigned short destport)
{
BYTE *hdr = (BYTE *)wsabuf->buf,
*nexthdr = NULL;
unsigned short shortval;
SOCKADDR_IN srcaddr,
destaddr;
unsigned short ip_version,
ip_hdr_len,
ip_tos,
ip_total_len,
ip_id,
ip_flags,
ip_ttl,
ip_frag_offset,
ip_proto,
ip_hdr_chksum,
ip_src_port,
ip_dest_port;
unsigned int ip_src,
ip_dest;
BOOL bPrint = TRUE;
ip_version = HI_WORD(*hdr);
ip_hdr_len = LO_WORD(*hdr) * 4;
nexthdr = (BYTE *)(wsabuf->buf + ip_hdr_len);
hdr++; ip_tos = *hdr;
hdr++; memcpy(&shortval, hdr, 2);
ip_total_len = ntohs(shortval);
hdr += 2; memcpy(&shortval, hdr, 2);
ip_id = ntohs(shortval);
hdr += 2; ip_flags = ((*hdr) >> 5); memcpy(&shortval, hdr, 2);
ip_frag_offset = ((ntohs(shortval)) & 0x1FFF);
hdr+=2; ip_ttl = *hdr;
hdr++; ip_proto = *hdr;
hdr++; memcpy(&shortval, hdr, 2);
ip_hdr_chksum = ntohs(shortval);
hdr += 2; memcpy(&srcaddr.sin_addr.s_addr, hdr, 4);
ip_src = ntohl(srcaddr.sin_addr.s_addr);
hdr += 4; memcpy(&destaddr.sin_addr.s_addr, hdr, 4);
ip_dest = ntohl(destaddr.sin_addr.s_addr);
hdr += 4;
//
// If packet is UDP, TCP, or IGMP read ahead and
// get the port values.
//
if (((ip_proto == 2) ||
(ip_proto == 6) ||
(ip_proto == 17)))
{
memcpy(&ip_src_port, nexthdr, 2);
ip_src_port = ntohs(ip_src_port);
memcpy(&ip_dest_port, nexthdr+2, 2);
ip_dest_port = ntohs(ip_dest_port);// if ((srcip == ip_src) ||
// (srcport == ip_src_port) ||
// (destip == ip_dest) ||
// (destport == ip_dest_port))
// {
// bPrint = TRUE;
// }
// else
// {
// bPrint = FALSE;
// }
}
if (srcip == ip_src || destip == ip_dest || srcip == 0 || destip == 0)
{
bPrint = TRUE;
}
else
{
bPrint = FALSE;
} // Print IP Hdr
//
if (bPrint)
{
printf("IP HEADER\n");
printf(" IP Version: %-10d | IP Header Len: %2d bytes | IP TOS: %X%X (hex)\n",
ip_version, ip_hdr_len, HI_WORD(ip_tos), LO_WORD(ip_tos));
printf(" IP Total Len: %-05d bytes | Identification: 0x%08X | IP Flags: %X (hex)\n",
ip_total_len, ip_id, ip_flags);
printf(" Frag Offset: 0x%08X | TTL: %-10d | Protocol: %-10s \n",
ip_frag_offset, ip_ttl, szProto[ip_proto]);
printf(" Hdr Checksum: 0x%08X\n", ip_hdr_chksum);
printf(" Src Addr: %-15s\n", inet_ntoa(srcaddr.sin_addr));
printf(" Dest Addr: %-15s\n", inet_ntoa(destaddr.sin_addr));
}
else
return ip_hdr_len; if (!bPrint)
return ip_hdr_len; switch (ip_proto)
{
case 2: // IGMP
DecodeIGMPHeader(wsabuf, ip_hdr_len);
break;
case 6: // TCP
DecodeTCPHeader(wsabuf, ip_hdr_len);
break;
case 17: // UDP
DecodeUDPHeader(wsabuf, ip_hdr_len);
break;
default:
printf(" No decoder installed for protocol\n");
break;
}
printf("\n"); return ip_hdr_len;
}