基于Linux C的socket抓包程序和Package分析(2)

u_char  ip_tos;
    u_short ip_total_len;
    u_short ip_id;
    u_short ip_flags;
    u_char  ip_ttl;
    u_char  ip_protocol;
    u_short ip_chksum;
    u_int32 ip_src;
    u_int32 ip_dest;
}__attribute__((packed)) IP_HDR;

为保证各属性长度与IP报文头中一致,我们应该在定义该结构体前作如下声明。

typedef int int32;
typedef unsigned int u_int32;
typedef unsigned char u_char;
typedef unsigned short u_short;

注意事项参考定义以太网帧结构体。

(3)为了提取UDP/TCP报文头,可根据UDP/TCP报文头格式,定义相应结构体,这里不作赘述。

下面是对以太网帧进行解析的具体代码。

MAC_FRM_HDR *mac_hdr; //define a Ethernet frame header
IP_HDR *ip_hdr;      //define a IP header
char *tmp1, *tmp2;
int AND_LOGIC = 0xFF;

mac_hdr = buf; //buf is what we got from the socket program
ip_hdr = buf + sizeof(MAC_FRM_HDR);
//udp_hdr = buf + sizeof(MAC_FRM_HDR) + sizeof(IP_HDR); //if we want to analyses the UDP/TCP

tmp1 = mac_hdr->src_addr;
tmp2 = mac_hdr->dest_addr;
/* print the MAC addresses of source and receiving host */
printf("MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X==>" "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
            tmp1[0]&AND_LOGIC, tmp1[1]&AND_LOGIC, tmp1[2]&AND_LOGIC,tmp1[3]&AND_LOGIC,
            tmp1[4]&AND_LOGIC, tmp1[5]&AND_LOGIC,
            tmp2[0]&AND_LOGIC, tmp2[1]&AND_LOGIC, tmp2[2]&AND_LOGIC,tmp2[3]&AND_LOGIC,
            tmp2[4]&AND_LOGIC, tmp2[5]&AND_LOGIC);

tmp1 = (char*)&ip_hdr->ip_src;
tmp2 = (char*)&ip_hdr->ip_dest;
/* print the IP addresses of source and receiving host */
printf("IP: %d.%d.%d.%d => %d.%d.%d.%d",
            tmp1[0]&AND_LOGIC, tmp1[1]&AND_LOGIC, tmp1[2]&AND_LOGIC,tmp1[3]&AND_LOGIC,
            tmp2[0]&AND_LOGIC, tmp2[1]&AND_LOGIC, tmp2[2]&AND_LOGIC,tmp2[3]&AND_LOGIC);
/* print the IP protocol which was used by the socket communication */
switch(ip_hdr->ip_protocol) {
        case IPPROTO_ICMP: LOGI("ICMP"); break;
        case IPPROTO_IGMP: LOGI("IGMP"); break;
        case IPPROTO_IPIP: LOGI("IPIP"); break;
        case IPPROTO_TCP:
  case IPPROTO_UDP:
                            LOGI("Protocol: %s", ip_hdr->ip_protocol == IPPROTO_TCP ? "TCP" : "UDP");
                            LOGI("Source port: %u, destination port: %u", udp_hdr->s_port, udp_hdr->d_port);
                            break;
        case IPPROTO_RAW: LOGI("RAW"); break;
        default: printf("Unknown, please query in inclued/linux/in.h\n"); break;
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9174d52e37fb59c0a70169d7a044dcef.html