struct ethhdr结构体详解
来源:互联网 发布:顾比均线源码带买卖点 编辑:程序博客网 时间:2024/04/30 03:44
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;
}
3 0
- struct ethhdr结构体详解
- struct ethhdr结构体详解
- struct ethhdr、ether_header、iphdr、tcphdr、udphdr结构体定义
- ethhdr、iphdr、tcphdr、udphdr等结构体
- struct addrinfo结构体详解
- struct inode 结构体详解
- struct socket结构体详解
- struct termios结构体详解
- C 结构体 struct 详解
- struct sk_buff结构体详解
- 结构体定义 typedef struct 用法详解
- 结构体定义 typedef struct 用法详解
- struct linger结构体作用详解
- struct module结构体 和 THIS_MODULE详解
- Objective-C--- NSValue 详解 struct 结构体
- 关于c#结构体(struct)定义详解
- struct module结构体 和 THIS_MODULE详解
- struct dirent 和 DIR结构体 详解
- Search in Rotated Sorted Array II
- 《JSP实用教程(第2版)/耿祥义》错误之tomcat虚拟服务目录
- Java TCP/IP字节流在本地进行数据传输测试
- JQ插件第四十九:图片滑动轮播
- NYOJ85 有趣的数
- struct ethhdr结构体详解
- jboss-eap-6.3集成OracleDS和MySqlDS配置
- 第十五周项目三 在OJ上玩指针(2)
- linux SIGBUS 总线错误
- memcached内存管理机制详解
- iOS中的屏幕旋转
- 数据保存(Rom,SdCard)
- 利用LocationManager获取经度,纬度等地理信息完整示例
- WinPcap学习(六)过滤数据包