微信公众号:创享日记
发送关键词:协议实现
获取各个协议C语言实现源代码源文件
ARP协议部分代码:
#include#include #include "net.h" #include "arp.h" #include "ethernet.h" static const arp_pkt_t arp_init_pkt = { .hw_type16 = swap16(ARP_HW_ETHER), .pro_type16 = swap16(NET_PROTOCOL_IP), .hw_len = NET_MAC_LEN, .pro_len = NET_IP_LEN, .sender_ip = NET_IF_IP, .sender_mac = NET_IF_MAC, .target_mac = {0}}; map_t arp_table; map_t arp_buf; void arp_entry_print(void *ip, void *mac, time_t *timestamp) { printf("%s | %s | %sn", iptos(ip), mactos(mac), timetos(*timestamp)); } void arp_print() { printf("===ARP TABLE BEGIN===n"); map_foreach(&arp_table, arp_entry_print); printf("===ARP TABLE END ===n"); } void arp_req(uint8_t *target_ip) { buf_init(&txbuf, sizeof(arp_pkt_t)); //对txbuf进行初始化 arp_pkt_t *pkt = (arp_pkt_t *)txbuf.data; pkt->hw_type16 = swap16(1); pkt->pro_type16 = swap16(NET_PROTOCOL_IP); pkt->hw_len = 6; pkt->pro_len = 4; pkt->opcode16 = swap16(ARP_REQUEST); // for (int i = 0; i < 6; i++) // { // pkt->sender_mac[i] = net_if_mac[i]; // pkt->target_mac[i] = 0x00; // } // for (int i = 0; i < 4; i++) // { // pkt->sender_ip[i] = net_if_ip[i]; // pkt->target_ip[i] = *(target_ip + i); // } memcpy(pkt->sender_mac, net_if_mac, NET_MAC_LEN); memcpy(pkt->sender_ip, net_if_ip, NET_IP_LEN); memset(pkt->target_mac, 0, NET_MAC_LEN); memcpy(pkt->target_ip, target_ip, NET_IP_LEN); ethernet_out(&txbuf, ether_broadcast_mac, NET_PROTOCOL_ARP); //发送ARP报文 }
ETH协议全部代码:
#include "ethernet.h"
#include "utils.h"
#include "driver.h"
#include "arp.h"
#include "ip.h"
void ethernet_in(buf_t *buf)
{
if(buf->len < sizeof(ether_hdr_t)) //判断数据长度,小于以太网头部长度的话丢弃不处理
{
return;
}
ether_hdr_t *hdr = (ether_hdr_t *)buf->data;
buf_remove_header(buf,sizeof(ether_hdr_t)); //移除以太网包头
net_in(buf,swap16(hdr->protocol16),hdr->src); //向上层传递数据包
}
void ethernet_out(buf_t *buf, const uint8_t *mac, net_protocol_t protocol)
{
if(buf->len < 46)
{
buf_add_padding(buf,46 - buf->len);
}
buf_add_header(buf,sizeof(ether_hdr_t)); //添加以太网包头
ether_hdr_t *hdr = (ether_hdr_t *)buf->data;
// for(int i = 0; i < 6; i++) //填写目的MAC地址
// {
// hdr->dst[i] = *(mac+i);
// }
// for(int i = 0; i < 6; i++) //填写源MAC地址
// {
// hdr->src[i] = net_if_mac[i]; //net_if_mac 得到本机的mac地址
// }
memcpy(hdr->dst, mac, NET_MAC_LEN);
memcpy(hdr->src, net_if_mac, NET_MAC_LEN);
hdr->protocol16 = swap16(protocol);
driver_send(buf); //将添加了以太网包头的数据帧发送到驱动层
}
void ethernet_init()
{
buf_init(&rxbuf, ETHERNET_MAX_TRANSPORT_UNIT + sizeof(ether_hdr_t));
}
void ethernet_poll()
{
if (driver_recv(&rxbuf) > 0)
ethernet_in(&rxbuf);
}
ICMP协议部分代码:
#include "net.h"
#include "icmp.h"
#include "ip.h"
static void icmp_resp(buf_t *req_buf, uint8_t *src_ip)
{
buf_t *buf = &txbuf;
buf_init(buf, req_buf->len );
memcpy(buf->data,req_buf->data,req_buf->len);
icmp_hdr_t *hdr1 = (icmp_hdr_t *)req_buf->data;
icmp_hdr_t hdr2 = {
.code = hdr1->code,
.checksum16 = 0,
.id16 = hdr1->id16,
.seq16 = hdr1->seq16,
.type = ICMP_TYPE_ECHO_REPLY};
memcpy(buf->data, &hdr2, sizeof(icmp_hdr_t));
hdr2.checksum16 = checksum16((uint16_t *)buf->data, buf->len);
memcpy(buf->data, &hdr2, sizeof(icmp_hdr_t));
ip_out(buf, src_ip, NET_PROTOCOL_ICMP);
}
void icmp_in(buf_t *buf, uint8_t *src_ip)
{
if (buf->len < sizeof(icmp_hdr_t))
{
return;
}
icmp_hdr_t *hdr = (icmp_hdr_t *)buf->data;
if (hdr->type == ICMP_TYPE_ECHO_REQUEST)
{
icmp_resp(buf, src_ip);
}
else
{
return;
}
}
UDP协议部分代码:
#include "udp.h"
#include "ip.h"
#include "icmp.h"
map_t udp_table;
static uint16_t udp_checksum(buf_t *buf, uint8_t *src_ip, uint8_t *dst_ip)
{
uint8_t src[4];
uint8_t dst[4];
memcpy(src, src_ip, 4);
memcpy(dst, dst_ip, 4);
buf_add_header(buf, sizeof(udp_peso_hdr_t));
udp_peso_hdr_t *peso_hdr = (udp_peso_hdr_t *)buf->data;
memcpy(peso_hdr->src_ip, src, 4);
memcpy(peso_hdr->dst_ip, dst, 4);
peso_hdr->protocol = NET_PROTOCOL_UDP;
peso_hdr->total_len16 = swap16(buf->len - sizeof(udp_peso_hdr_t));
peso_hdr->placeholder = 0;
uint16_t *p;
p = (uint16_t *)peso_hdr;
int n = buf->len / 2;
int i = 0;
uint32_t checksum = 0;
while (i < n)
{
checksum += swap16(*p);
p++;
i++;
}
if (buf->len % 2 != 0)
{
checksum += swap16(*p) & 0xFF00;
}
while ((checksum >> 16) != 0)
{
checksum = (checksum >> 16) + (checksum & 0xFFFF);
}
buf_remove_header(buf, sizeof(udp_peso_hdr_t));
memcpy(src_ip, src, 4);
memcpy(dst_ip, dst, 4);
return (uint16_t)(~checksum);
}
void udp_in(buf_t *buf, uint8_t *src_ip)
{
if (buf->len < sizeof(udp_hdr_t))
{
return;
}
udp_hdr_t *hdr = (udp_hdr_t *)buf->data;
if (buf->len < swap16(hdr->total_len16))
{
return;
}
uint16_t temp = swap16(hdr->checksum16);
hdr->checksum16 = 0;
hdr->checksum16 = udp_checksum(buf, src_ip, net_if_ip);
if (temp != hdr->checksum16)
{
return;
}
uint16_t dst_port16 = swap16(hdr->dst_port16);
uint16_t src_port16 = swap16(hdr->src_port16);
if (!(map_get(&udp_table, &dst_port16)))
{
buf_add_header(buf, sizeof(ip_hdr_t));
icmp_unreachable(buf, src_ip, ICMP_CODE_PORT_UNREACH);
}
else
{
udp_handler_t *handler = map_get(&udp_table, &dst_port16);
buf_remove_header(buf, sizeof(udp_hdr_t));
(*handler)(buf->data, buf->len, src_ip, src_port16);
}
}
IP协议部分代码:
#include "net.h"
#include "ip.h"
#include "ethernet.h"
#include "arp.h"
#include "icmp.h"
void ip_in(buf_t *buf, uint8_t *src_mac)
{
if(buf->len < sizeof(ip_hdr_t))
{
return;
}
ip_hdr_t *hdr = (ip_hdr_t *)buf->data;
if(hdr->version != 4 || swap16(hdr->total_len16) > buf->len)
{
return;
}
uint16_t hdr_checksum_temp = hdr->hdr_checksum16;
hdr->hdr_checksum16 = 0;
uint16_t checksum = checksum16((uint16_t *)hdr, sizeof(ip_hdr_t));
hdr->hdr_checksum16 = swap16(checksum);
if(checksum != hdr_checksum_temp)
{
return;
}
else
{
hdr->hdr_checksum16 = hdr_checksum_temp;
}
for (size_t i = 0; i < NET_IP_LEN; i++)
{
if(hdr->dst_ip[i] != net_if_ip[i])
{
return;
}
}
if(buf->len > swap16(hdr->total_len16))
{
buf_remove_padding(buf, buf->len - swap16(hdr->total_len16));
}
if(hdr->protocol != NET_PROTOCOL_ICMP && hdr->protocol != NET_PROTOCOL_UDP)
{
icmp_unreachable(buf, hdr->src_ip, ICMP_CODE_PROTOCOL_UNREACH);
}
else
{
buf_remove_header(buf, sizeof(ip_hdr_t));
net_in(buf, hdr->protocol, hdr->src_ip);
}
}
void ip_fragment_out(buf_t *buf, uint8_t *ip, net_protocol_t protocol, int id, uint16_t offset, int mf)
{
buf_add_header(buf, sizeof(ip_hdr_t));
ip_hdr_t *hdr = (ip_hdr_t *)buf->data;
hdr->hdr_len = 5;
hdr->version = 4;
hdr->tos = 0;
hdr->total_len16 = swap16(buf->len);
hdr->id16 = swap16(id);
hdr->protocol = protocol;
hdr->ttl = 64;
if (mf == 1)
{
hdr->flags_fragment16 = swap16((offset >> 3) + IP_MORE_FRAGMENT);
}
else
{
hdr->flags_fragment16 = swap16(offset >> 3);
}
memcpy(hdr->src_ip, net_if_ip, NET_IP_LEN);
memcpy(hdr->dst_ip, ip, NET_IP_LEN);
hdr->hdr_checksum16 = 0;
hdr->hdr_checksum16 = checksum16((uint16_t *)hdr, sizeof(ip_hdr_t));
arp_out(buf, ip);
}



