📄 ip.c
字号:
#include "ip.h"#include "mac.h"#include "serial.h"#include "udp.h"#include "icmp.h"#include "mac_low.h"extern IP_SETTINGS ipsettings;IP_TABLE iptable;Uint16 tmpident;Uint16 crc_counter =0;//Table for IP addressesARP_TABLE arptable;IPHEADER *ip_header;extern UDPHEADER *udp_header;extern ICMPHEADER *icmp_header;//Layer2 processingUint8 ip_process(IPHEADER *packet, ETHHEADER *eth_header){ Uint16 datasize,chk; Uint8 *tmpptr; Uint32 word; //Calculate CRC on packet //chk = ip_chksum((Uint16 *) packet,IP_SIZE/2); //dbg(chk); //if (chk != 0x0000) if (ip_chksum((Uint16 *) packet,IP_SIZE/2) > 0) { crc_counter++; //dbg(chk); return 0; } //Check if packet is for us else if ((((packet->destip_h == ipsettings.ip_address_h)) && ((packet->destip_l == ipsettings.ip_address_l))) || ((packet->destip_h == 0xffff) && (packet->destip_l == 0xffff))) { //dbg_char(packet->protocol); //Set datasize datasize = (packet->packetlength-IP_SIZE)/2; //Store ident tmpident = packet->ident; //Handle source ip address //Test if local if ((packet->sourceip_h ^ packet->destip_h)) { //Non-zero mask - not local } else { //Zero mask, local //Test if in arptable if (arptable_match(packet->sourceip_h,packet->sourceip_l) == 0xff) { //Not in table, add arptable_add(packet->sourceip_h, packet->sourceip_l,eth_header->sourcemac); } } word = (Uint32) packet; word += IP_SIZE; //Decode protocol if (packet->protocol == PROTOCOL_UDP) { udp_header = (UDPHEADER *) word; udp_process(udp_header,datasize,packet->sourceip_h,packet->sourceip_l); } else if (packet->protocol == PROTOCOL_ICMP) { icmp_header = (ICMPHEADER *) word; //dbg_string((Uint16 *) &word,2); icmp_process(icmp_header,datasize,packet->sourceip_h,packet->sourceip_l); } } else { //dbg(packet->destip_h); //dbg(packet->destip_l); } return 0;}void ip_init(void){ Uint8 x,*y; y = (Uint8 *) &arptable; for (x=0;x<sizeof(arptable);x++) { *(y++) = 0; } ipsettings.ip_address_h = ipsettings.ip_address_l = 0; //fill in gateway information //IP Address 192.168.1.1 arptable.entry[0].ip_address_h = 0xc0a8; arptable.entry[0].ip_address_l = 0x0101; arptable.entry[0].mac_address[0]=0; arptable.entry[0].mac_address[1]=0x12; arptable.entry[0].mac_address[2]=0x17; arptable.entry[0].mac_address[3]=0xad; arptable.entry[0].mac_address[4]=0x3d; arptable.entry[0].mac_address[5]=0xf1; arptable.index = 1; iptable.index = 0;}void ip_send(Uint16 dest_ip_h,Uint16 dest_ip_l, Uint16 data_len, Uint8 protocol){ IPHEADER *ip_header; Uint16 match; //Set ip_header pointer ip_header = (IPHEADER *) (EMAC_TX_PTR + ETH_SIZE); ip_header->destip_h = dest_ip_h; ip_header->destip_l = dest_ip_l; ip_header->sourceip_h = ipsettings.ip_address_h; ip_header->sourceip_l = ipsettings.ip_address_l; ip_header->protocol = protocol; ip_packet(ip_header,data_len); //Header is filled out and added to buffer, check if IP is in table match = arptable_match(dest_ip_h,dest_ip_l); if (match != 0xff) { //Set length //mac_set_len(((ETH_SIZE+IP_SIZE)/2)+data_len); //Index is in 'match' mac_send(match,IP_TYPE,data_len+(IP_SIZE/2)); } else { //IP needs to be looked up }}//Returns index of arp_table if IP is foundUint16 arptable_match(Uint16 ip_address_h, Uint16 ip_address_l){ Uint16 x; //Check if broadcast msg if ((ip_address_h == 0xffff) && (ip_address_l == 0xffff)) { return 0xfe; } for (x=0;x<ENTRY_SIZE;x++) { if ((arptable.entry[x].ip_address_h == ip_address_h) && (arptable.entry[x].ip_address_l == ip_address_l)) { //Match found return x; } } //See if ip is external if (ip_address_h ^ ipsettings.ip_address_h) { //External ip, return gateway return 0; } //No match found return 0xff;}//Adds ip and mac to arptablevoid arptable_add(Uint16 ip_address_h, Uint16 ip_address_l, Uint8 *mac_address){ Uint8 x; arptable.entry[arptable.index].ip_address_h = ip_address_h; arptable.entry[arptable.index].ip_address_l = ip_address_l; for (x=0;x<6;x++) { arptable.entry[arptable.index].mac_address[x] = mac_address[x]; } //Rollover index if (++arptable.index == ENTRY_SIZE) arptable.index = 1;}/////////////////////////////////////////////////Expect length, source/dest ip, protocol to be filled outUint16 ip_packet(IPHEADER *packet, Uint16 data_len){ //Fill out fields of structure packet->version = 0x45; packet->service = 0x00; //If len != 0, change length if (data_len != 0) packet->packetlength = 20+(data_len*2); packet->ident = tmpident; packet->offset = 0x0000; packet->timetolive = 0x80; packet->checksum = 0x0000; //All fields of struct have now been filled out, calculate checksum packet->checksum = ip_chksum((Uint16 *) packet,10); //Return length in words return (packet->packetlength)/2;}//Returns checksum on string starting at 'buf' for 'len' wordsUint16 ip_chksum(Uint16 *buf,Uint16 len){ Uint16 i; Uint32 tmp=0,tmp2; Uint16 tmpint; for (i=0;i<len;i++) { tmp += (Uint32) (buf[i] & 0xFFFF); } //Add the carry to tmp tmp2 = (tmp >> 16) & 0xFFFF; tmp += tmp2; tmpint = 0xFFFF - ((Uint16) (tmp & 0xFFFF)); return tmpint;}//Calc checksum over 2 stringsUint16 ip_chksum2(Uint16 *buf,Uint16 len,Uint16 *buf2,Uint16 len2){ Uint16 i; Uint32 tmp=0,tmp2; Uint16 tmpint; for (i=0;i<len;i++) { tmp += (Uint32) (buf[i] & 0xFFFF); } for (i=0;i<len2;i++) tmp += (Uint32) (buf2[i] & 0xFFFF); //Add the carry to tmp tmp2 = (tmp >> 16) & 0xFFFF; tmp += tmp2; tmpint = 0xFFFF - ((Uint16) (tmp & 0xFFFF)); return tmpint;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -