📄 ip.c
字号:
#include <bios/netdev.h>#include <bios/checksum.h>#include <bios/stdio.h>#include <bios/ctype.h>#include <bios/string.h>#undef DEBUG_S3C4_IP#ifdef DEBUG_S3C4_IP #define DEBUG_IP(fmt, args...) printf("%s-%s()[%d]: " fmt, __FILE__, __FUNCTION__, __LINE__, args)#else #define DEBUG_IP(fmt, args...)#endif/* extern functions */extern int arp_lookup(struct netdev *nd, u32 addr, u8 *eth_addr);static u32 ip_pkt_no;/* function proto types */int ip_send(struct netdev *nd, int protocol, u32 from, u32 to, struct buflist *data);int ip_recv(struct netdev *nd, int protocol, u32 from, u32 to, u8 *buffer);char *in_ntoa(u32 addr);unsigned int in_aton(char *s);char *in_ntoa(u32 addr){ static char buffer[16];#ifndef BIG_ENDIAN sprintf(buffer, "%ld.%ld.%ld.%ld", addr & 255, (addr >> 8) & 255, (addr >> 16) & 255, (addr >> 24) & 255);#else /* BIG_ENDIAN */ sprintf(buffer, "%ld.%ld.%ld.%ld", (addr >> 24) & 255, (addr >> 16) & 255, (addr >> 8) & 255, addr & 255) ;#endif /* LITTLE_ENDIAN */ return buffer;}unsigned int in_aton(char *s){ unsigned int n[4] = {0,0,0,0}; char ip[20]; int i = 0, sp = 0; sprintf(ip,"%s",s); while(isspace(ip[sp])) sp++; /* get the next charactor */ for(i = 0; i < 4; i++) { while(ip[sp]) if(isdigit(ip[sp])) n[i]= n[i] * 10 + todecimal(ip[sp++]); else { sp++; break; } if(ip[sp] == CR || ip[sp] == (char)NULL) break; } return htonl(n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3]);}static unsigned short ip_check(struct iphdr *ip){ unsigned int check, length = ip->ip_ihl * 4; check = ~checksum(ip, length, 0); if (check == 0) check = -1; return htons(check);}int ip_send(struct netdev *nd, int protocol, u32 from, u32 to, struct buflist *data){ static u8 hwto[6], *dest; static struct buflist bl, *blp; static struct iphdr ip; int size = 0; for (blp = data; blp; blp = blp->next) size += blp->size; ip.ip_ver = 4; ip.ip_ihl = 5; ip.ip_tos = 0; ip.ip_len = htons(sizeof(ip) + size); ip.ip_id = htons(ip_pkt_no); ip.ip_frag = 0; ip.ip_ttl = 0x40; ip.ip_proto = protocol; ip.ip_check = 0; ip.ip_source = from; ip.ip_dest = to; ip.ip_check = ip_check(&ip); ip_pkt_no += 1; bl.data = &ip; bl.size = sizeof(ip); bl.next = data; if (to == INADDR_ANY) { dest = nd->hw_broadcast; DEBUG_IP("dest(%x)\n",dest); } else if (!arp_lookup(nd, to, hwto)) { dest = hwto; DEBUG_IP("dest(%x)\n",dest); } else return -1; blp = nd->eth_header(nd, dest, ETH_P_IP, &bl); DEBUG_IP("IP buffer(%x)\n",&bl); return blp ? nd->eth_send(nd, blp) : -1;}int ip_recv(struct netdev *nd, int protocol, u32 from, u32 to, u8 *buffer){ static u8 ip_buffer[1584]; static struct iphdr *ip = (struct iphdr *)ip_buffer; int bytes, hdrlen; int check; DEBUG_IP("\n%s", "->"); bytes = nd->eth_recv(nd, ETH_P_IP, ip_buffer); DEBUG_IP("BYTES(%d)\n", bytes); if (bytes == 0) return 0; if (ip->ip_ver != 4 || ip->ip_ihl < 5) { DEBUG_IP("ERROR: IP version(%d)/length(%d)\n",ip->ip_ver, ip->ip_ihl); return 0; } hdrlen = ip->ip_ihl * 4; if ( (check=checksum(ip, hdrlen, 0)) != 0xffff) { DEBUG_IP("ERROR:IP checksum(0x%x)\n",check); return 0; } if (ip->ip_proto != protocol) { DEBUG_IP("ERROR:protocol(%x)\n",ip->ip_proto); return 0; } if (from != INADDR_ANY && from != ip->ip_source) { DEBUG_IP("ERROR:Src addr(%x)\n", from); return 0; } if (to != INADDR_ANY && to != ip->ip_dest) { DEBUG_IP("ERROR:dest addr(%x)\n", to); return 0; } bytes -= hdrlen; memcpy(buffer, ip_buffer + hdrlen, bytes); return bytes;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -