首页 > 代码库 > struct ethhdr结构体详解
struct ethhdr结构体详解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #define ETH_ALEN 6 //定义了以太网接口的MAC地址的长度为6个字节 #define ETH_HLAN 14 //定义了以太网帧的头长度为14个字节 #define ETH_ZLEN 60 //定义了以太网帧的最小长度为 ETH_ZLEN + ETH_FCS_LEN = 64个字节 #define ETH_DATA_LEN 1500 //定义了以太网帧的最大负载为1500个字节 #define ETH_FRAME_LEN 1514 //定义了以太网正的最大长度为ETH_DATA_LEN + ETH_FCS_LEN = 1518个字节 #define ETH_FCS_LEN 4 //定义了以太网帧的CRC值占4个字节 struct ethhdr { unsigned char h_dest[ETH_ALEN]; //目的MAC地址 unsigned char h_source[ETH_ALEN]; //源MAC地址 __u16 h_proto ; //网络层所使用的协议类型 }__attribute__((packed)) //用于告诉编译器不要对这个结构体中的缝隙部分进行填充操作; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | int eth_header( struct sk_buff *skb, struct net_device *dev, u16 type, void *daddr, void *saddr, int len) { //将skb->data = skb->data + ETH_ALEN; struct ethhdr *eth = ( struct ethhdr*)skb_push(skb, ETH_ALEN); if (type != ETH_P_802_3) eth->proto = htons(type); // htons()将本地类型转换为网络类型 else eth->proto = htons(len); //如果 saddr = NULL的话,以太网帧头中的源MAC地址为dev的MAC地址 if (!saddr) saddr = dev->dev_addr; memcpy (eth->saddr, saddr, ETH_ALEN); if (daddr) { memcpy (eth->daddr, daddr, ETH_ALEN); return ETH_HLEN ; //返回值为14 } return -ETH_HLEN; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | __be16 eth_type_trans( struct sk_buff *skb, struct net_device *dev) { struct ethhdr *eth; skb->dev = dev; eth = eth_hdr(skb); if (netdev_uses_dsa_tags(dev)) return htons(ETH_P_DSA); if (netdev_uses_trailer_tags(dev)) return htons(ETH_P_TRAILER); if ( ntohs(eth->h_proto) >= 1536 ) return eth->h_proto; } |
1 2 3 4 5 6 | int eth_header_parse( struct sk_buff *skb, u8 *haddr) { struct ethhdr *eth = eth_hdr(skb); memcpy (haddr, eth->h_source, ETH_ALEN); //可知haddr中存放的是源MAC地址; return ETH_ALEN; } |
1 2 3 4 5 6 7 8 | char *print_mac( char *buffer, const unsigned char *addr) { // MAC_BUF_SIZE = 18 // ETH_ALEN = 6 _format_mac_addr(buffer, MAC_BUF_SIZE, addr, ETH_ALEN); return buffer; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | int eth_mac_addr( struct net_device *dev, void *p) { struct sockaddr *addr = p; //用于判断网络设备是否正在运行 if (netif_running(dev)) return -EBUSY; if ( !is_valid_ether_addr(addr->sa_data) ) return -ETHADDRNOTAVAIL; memcpy (dev->dev_addr, addr->sa_data, ETH_ALEN); return 0; } |
1 2 3 4 5 6 7 8 | struct net_device *alloc_etherdev_mq( int sizeof_priv, unsigned int queue_count) { // ether_setup为对分配的struct net_device进行初始化的函数; //这个ether_setup是内核的导出函数,可以直接使用; return alloc_netdev_mq(sizeof_priv, "eth%d" , ether_setup, queue_count); } #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) |
1 2 3 4 | static inline int is_zero_ether_addr( const u8 *addr) { return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); } |
1 2 3 4 5 | static inline int is_multicast_ether_addr( const u8 *addr) { //组播MAC地址的判断方法:如果一个MAC地址的最低一位是1的话,则这个MAC地址为组播MAC地址; return (0x01 & addr[0]); } |
1 2 3 4 | static inline int is_broadcast_ether_addr( const u8 *addr) { return ( addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5] ) == 0xff; } |
1 2 3 4 5 | static inline int is_valid_ether_addr( const u8 *addr) { //既不是组播地址,也不为0的MAC地址为有效的MAC地址; return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr); } |
1 2 3 4 5 6 | static inline void random_ether_addr(u8 *addr) { get_random_bytes(addr, ETH_ALEN); addr[0] & = 0xfe; addr[0] |= 0x02; // IEEE802本地MAC地址 } |
1 2 3 4 | static inline int is_local_ether_addr( const u8 *addr) { return (0x02 & addr[0]); } |
1 2 3 4 5 6 7 | static inline unsigned compare_ether_addr( const u8 *addr1, const u8 *addr2) { const u16 *a = ( const u16*)addr1; const u16 *b = ( const u16*)addr2; return ( (a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) ) != 0; } |
struct ethhdr结构体详解
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。