LInux kernel中MAC头,IP头,TCP头结构体定义,内核打印方式。
MAC头:
//内核中MAC头结构体
#defein ETH_ALEN 6
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; //48位目的MAC地址
unsigned char h_source[ETH_ALEN]; //48位源MAC地址
__be16 h_proto; //16位协议类型
} __attribute__((packed));
//有这样两个宏可以方便地打印mac地址:
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
//使用样例如下:
const struct ethhdr* eh = eth_hdr(skb);
printk(KERN_INFO "source mac:" MAC_FMT "\n", MAC_ARG(eh->h_source));
printk(KERN_INFO "dest mac:" MAC_FMT "\n", MAC_ARG(eh->h_dest));
IP头:
//linux kernel中ip地址结构体
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4, //4位版本号
ihl:4; //4位首部长度
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos; //8位服务类型
__be16 tot_len; //16位总长度
__be16 id; //16位标识
__be16 frag_off; //3位标志,13位片偏移
__u8 ttl; //8位生存时间
__u8 protocol; //8位协议
__sum16 check; //16位首部校验和
__be32 saddr; //32位源地址
__be32 daddr; //32位目的地址
/*The options start here. */
};
//打印IP地址
#define NIPQUAD(addr) \
((unsigned char *)&addr)[0], \
((unsigned char *)&addr)[1], \
((unsigned char *)&addr)[2], \
((unsigned char *)&addr)[3]
struct iphdr *nh;
struct sk_buff *skb;
nh = ip_hdr(skb);
printk(KERN_INFO "src: %u.%u.%u.%u, dst: %u.%u.%u.%u\n",
NIPQUAD(nh->saddr), NIPQUAD(nh->daddr));
TCP头定义:
//linux kernel 中tcp结构体
struct tcphdr {
__be16 source; //16位源端口号
__be16 dest; //16位目的端口号
__be32 seq; //32位序号
__be32 ack_seq; //32位确认序号
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
__be16 window;
__sum16 check;
__be16 urg_ptr;
};
//打印tcp端口号
const struct tcphdr* th = tcp_hdr(skb);
printk(KERN_INFO "src_port: %d, dst_port: %d\n",
ntohs(th->source), ntohs(th->dest));
uint32_t htonl(uint32_t hostlong);//32位的主机字节序转换到网络字节序
uint16_t htons(uint16_t hostshort);//16位的主机字节序转换到网络字节序
uint32_t ntohl(uint32_t netlong);//32位的网络字节序转换到主机字节序
uint16_t ntohs(uint16_t netshort);//16位的网络字节序转换到主机字节序