?? zipv4.c
字號:
#include "include/zipv4.h"#include "include/zicmp.h"#include "include/zudp.h"#include "include/ztcp.h"u16_t ip_id = 0;static u32_t chksum(void *dataptr, u16_t len){ u32_t acc; for(acc = 0; len > 1; len -= 2) { acc += *((u16_t *)dataptr)++; } /* add up any odd byte */ if(len == 1) { acc += (u16_t)((*(u8_t *)dataptr) & 0xff) << 8; } return acc;}u16_t inet_chksum(void *dataptr, u16_t len){ u32_t acc; acc = chksum(dataptr, len); while(acc >> 16) { acc = (acc & 0xffff) + (acc >> 16); } return ~(acc & 0xffff);}u16_t inet_chksum_pseudo(zbuffer_t *pbuf_dat, ipaddr_t *src, ipaddr_t *dest, u8_t proto, u16_t proto_len){ u32_t acc; zbuffer_t *q; u8_t swapped; acc = 0; swapped = 0; for(q = pbuf_dat; q != NULL; q = q->next) { acc += chksum(q->pdata, q->len); while(acc >> 16) { acc = (acc & 0xffff) + (acc >> 16); } if(q->len % 2 != 0) { swapped = 1 - swapped; acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8); } } if(swapped) { acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8); } acc += (*src & 0xffff); acc += ((*src >> 16) & 0xffff); acc += (*dest & 0xffff); acc += ((*dest >> 16) & 0xffff); acc += (u32_t)((u16_t)proto); acc += (u32_t)(proto_len); while(acc >> 16) { acc = (acc & 0xffff) + (acc >> 16); } return ~(acc & 0xffff);} u8_t ip_input(znetif_t *pnetif, zbuffer_t *pbuffer){ ip_header_t *pheader; u8_t hl; pheader = (ip_header_t *)((u8_t *)pbuffer->pdata + ETH_HEAD_LEN); /*step 1. check this is a ipv4 packet*/ if(IPH_V(pheader) != 4) { zbuffer_delete(pbuffer); return -1; } hl = IPH_HL(pheader); /*step 2. the header is too long for our buffer*/ if(hl * 4 > pbuffer->len) { zbuffer_delete(pbuffer); return -1; } /*setp 3. we check IPV4 header checksum*/ if (inet_chksum(pheader, hl * 4) ) { zbuffer_delete(pbuffer); return -1; } /*setup 4. we only check DEST-ip is our ip's packet whithout brocast ip*/#if 0 if ( !((pheader->dest_ipaddr == pnetif->ipaddr) || (ip_addr_isbroadcast(pheader->dest_ipaddr,pnetif->netmask) && ip_addr_maskcmp(pheader->dest_ipaddr,pnetif->ipaddr,pnetif->netmask) )))#else if ( !(pheader->dest_ipaddr == pnetif->ipaddr) )#endif { zbuffer_delete(pbuffer); return -1; } /*step 5. we only check none-fragment ip packet now FIXME*/ if(( IPH_OFFSET(pheader) & (IP_OFFMASK | IP_MF) ) != 0) { zbuffer_delete(pbuffer); return -1; } /*setup 6.we check if length < pbuffer->totlen ) */ if ( pbuffer->tot_len > (IPH_LEN(pheader) + 14) ) { pbuffer = zbuffer_adjust( pbuffer, 0, (-1)*(pbuffer->tot_len - (IPH_LEN(pheader) + 14))); if ( pbuffer == NULL) return -1; } /*step 7. we will check what type packet this is?*/ switch(IPH_PROTO(pheader)) { case IP_PROTO_UDP: udp_input(pnetif, pbuffer); break; case IP_PROTO_TCP: tcp_input(pnetif, pbuffer); break; case IP_PROTO_ICMP: return icmp_input(pnetif, pbuffer); break; default: if ( !ip_addr_isbroadcast((pheader->dest_ipaddr), (pnetif->netmask)) && !ip_addr_ismulticast((pheader->dest_ipaddr))) { icmp_dest_unreach(pnetif,pbuffer, ICMP_DUR_PROTO); } else zbuffer_delete(pbuffer); return -1; break; } return 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -