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;
}
|