网络协议栈设计(六)
int is_accept_ethernet_packet(u_int8_t *packet_content,
int len);
void ethernet_protocol_packet_callback(u_char *argument,
const struct pcap_pkthdr *packet_header,
const u_char *packet_content);
#include "Network_IPV4_recv.h"
#include "Network_ARP_recv.h "
int is_accept_ethernet_packet(u_int8_t *packet_content,
int len)
{
struct ethernet_header *ethernet_hdr = (
struct ethernet_header *)packet_content;
int i;
int flag =
0;
for (i =
0; i <
6; i++)
{
if (ethernet_hdr->destination_mac[i] !=
0xff)
break;
}
if (i ==
6)
{
flag =
1;
printf(
"It's broadcast packet.\n");
}
for (i =
0; i <
6; i++)
{
if (ethernet_hdr->destination_mac[i] != local_mac[i])
break;
}
if (i ==
6)
{
flag =
1;
printf(
"It's sended to my pc.\n");
}
if (!flag)
return 0;
u_int32_t crc = calculate_crc((u_int8_t *)packet_content , len -
4 );
if (crc != *((u_int32_t *)(packet_content + len -
4)))
{
printf(
"The data has changed.\n");
return 0;
}
return 1;
}
void ethernet_protocol_packet_callback(u_char *argument,
const struct pcap_pkthdr *packet_header,
const u_char *packet_content)
{
int len = packet_header->len;
if (!is_accept_ethernet_packet((u_int8_t *)packet_content, len))
{
return;
}
struct ethernet_header *ethernet_hdr = (
struct ethernet_header *)packet_content;
u_int16_t ethernet_type = ntohs(ethernet_hdr->ethernet_type);
u_int8_t *upper_buffer = (u_int8_t *)(packet_content +
sizeof(ethernet_header));
switch (ethernet_type)
{
case 0x0800:
printf(
"Upper layer protocol: IPV4\n");
network_ipv4_recv(upper_buffer);
break;
case 0x0806:
printf(
"Upper layer protocol: ARP\n");
dest_mac=network_arp_recv(upper_buffer);
break;
case 0x8035:
printf(
"Upper layer protocol: RARP\n");
break;
case 0x814c:
printf(
"Upper layer protocol: SNMP\n");
break;
case 0x8137:
printf(
"Upper layer protocol: IPX(Internet Packet Exchange)\n");
break;
case 0x86DD:
printf(
"Upper layer protocol: IPV6\n");
break;
case 0x880B:
printf(
"Upper layer protocol: PPP\n");
break;
default:
break;
}
}
到这里我们就算介绍完了数据链路层以太网的数据包发送和接收的过程及实现,我们先在此简单总结一下: 我们的数据发送,向上层提供的接口函数是: int ethernet_send_packet(u_int8_t *upper_buffer,u_int8_t *destination_mac,u_int16_t ethernet_type) 上层调用此函数时需要提供的参数有: 1、上层的数据包,即链路层数据帧的数据部分 2、数据包长度,这里我们用全局变量ethernet_upper_len来获取 2、目的MAC地址 3、调用此函数的上层协议
数据接收时,根据上层协议不同提交时上层提供给我们的接口有: network_arp_recv(upper_buffer); network_ipv4_recv(upper_buffer); //这两个我们后边会慢慢给大家展示出来
下一篇我们就进入网络层的设计。
转载请注明原文地址: https://ju.6miu.com/read-671145.html