|
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;} |
更多关于
android开发 的文章原文地址:http://blog.csdn.net/androidmylove/article/details/41774883