📄 net.c
字号:
/* * Copied from Linux Monitor (LiMon) - Networking. * * Copyright 1994 - 2000 Neil Russell. * (See License) * Copyright 2000 Roland Borde * Copyright 2000 Paolo Scaffardi * Copyright 2000, 2001 Wolfgang Denk * * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Marius Groeger <mgroeger@sysgo.de> *//* * General Desription: * * The user interface supports commands for BOOTP, RARP, and TFTP. * Also, we support ARP internally. Depending on available data, * these interact as follows: * * BOOTP: * * Prerequisites: - own ethernet address * We want: - own IP address * - TFTP server IP address * - name of bootfile * Next step: ARP * * RARP: * * Prerequisites: - own ethernet address * We want: - own IP address * - TFTP server IP address * Next step: ARP * * ARP: * * Prerequisites: - own ethernet address * - own IP address * - TFTP server IP address * We want: - TFTP server ethernet address * Next step: TFTP * * DHCP: * * Prerequisites: - own ethernet address * We want: - IP, Netmask, ServerIP, Gateway IP * - bootfilename, lease time * Next step: - TFTP * * TFTP: * * Prerequisites: - own ethernet address * - own IP address * - TFTP server IP address * - TFTP server ethernet address * - name of bootfile (if unknown, we use a default name * derived from our own IP address) * We want: - load the boot file * Next step: none */#include <stdio.h>#include <string.h>#include "net.h"#include "console.h"char NetOurEther[6]; /* Our ethernet address */IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */char NetBcastAddr[6] = /* Ethernet bcast address */ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };char NetServerEther[6];IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */unsigned short NetServerPort;volatile uchar *NetRxPkt; /* Current receive packet */int NetRxPktLen; /* Current rx packet length */unsigned NetIPID; /* IP packet ID */int NetState; /* Network loop state *///void NetPrintEther(volatile uchar * addr);void NetSendPacket(volatile char * pkt, int len){ eth_send(pkt, len);}void NetReceive(volatile char * pkt, int len){ Ethernet_t *et; IP_t *ip; ARP_t *arp; int x;// NetRxPkt = pkt;// NetRxPktLen = len; et = (Ethernet_t *)pkt; x = SWAP16(et->et_protlen); ip = (IP_t *)(pkt + ETHER_HDR_SIZE); len -= ETHER_HDR_SIZE; if (x == PROT_ARP) { arp = (ARP_t *)ip; if (len < ARP_HDR_SIZE) { printf("bad length %d < %d\n", len, ARP_HDR_SIZE); return; } if (SWAP16(arp->ar_hrd) != ARP_ETHER) { return; } if (SWAP16(arp->ar_pro) != PROT_IP) { return; } if (arp->ar_hln != 6) { return; } if (arp->ar_pln != 4) { return; } if (NetOurIP == 0) { return; } { IPaddr_t ip = NetReadIP((char*)&arp->ar_data[16]); if (ip != NetOurIP) { return; } } switch (SWAP16(arp->ar_op)) { case ARPOP_REQUEST: /* reply with our Ether address */ NetSetEther((char *)et, (char *)(et->et_src), PROT_ARP); arp->ar_op = SWAP16(ARPOP_REPLY); NetCopyEther(NetServerEther, &arp->ar_data[0]); NetServerIP = NetReadIP(&arp->ar_data[6]); NetCopyEther(&arp->ar_data[0], NetOurEther); NetWriteIP( &arp->ar_data[6], NetOurIP); NetCopyEther(&arp->ar_data[10], NetServerEther); NetWriteIP( &arp->ar_data[16], NetServerIP); NetSendPacket((char *)et,((char *)arp-pkt)+ARP_HDR_SIZE); return; case ARPOP_REPLY: /* set TFTP server eth addr */#if 0 /* check if target ether is ours */ if ( memcmp(NetOurEther, &(arp->ar_data[10]), 6) != 0 ) { return; } NetCopyEther(NetServerEther, &arp->ar_data[0]); printf("eth addr: "); NetPrintEther(NetServerEther); (*packetHandler)(0,0,0,0); /* start TFTP */ return;#endif default: return; } } else if (x == PROT_IP){ if ((len < IP_HDR_SIZE)||(len < SWAP16(ip->ip_len))){ return; } len = SWAP16(ip->ip_len); if ((ip->ip_hl_v & 0xf0) != 0x40) { return; } if (ip->ip_off & SWAP16c(0x1fff)) { printf("can't deal with fragments\n"); return; } if (!NetCksumOk((char *)ip, IP_HDR_SIZE_NO_UDP / 2)) { printf("checksum bad\n"); return; } if (NetOurIP) { IPaddr_t ipaddr = NetReadIP((char*)&ip->ip_dst); if (ipaddr != NetOurIP && ipaddr != 0xFFFFFFFF){ return; } } if (ip->ip_p == IPPROTO_ICMP) { icmp_echo_reply(pkt); return; } else if (ip->ip_p == IPPROTO_UDP) { /* Only UDP packets */ unsigned short port = SWAP16(ip->udp_dst); if (port == COMMAND_UDP_PORT){ NetCopyEther(NetServerEther, (char *)(et->et_src)); NetServerIP = NetReadIP((char*)&ip->ip_src); command_input((char *)ip +IP_HDR_SIZE, (int)(SWAP16(ip->udp_len) - 8)); } else if (port == SERVER_TFTP_PORT){ NetCopyEther(NetServerEther, (char *)(et->et_src)); NetServerIP = NetReadIP((char*)&ip->ip_src); NetServerPort = SWAP16(ip->udp_src); tftp_handle((char *)ip +IP_HDR_SIZE, (int)(SWAP16(ip->udp_len) - 8)); } else if (port == LOCAL_TFTP_PORT){ tftp_handle((char *)ip +IP_HDR_SIZE, (int)(SWAP16(ip->udp_len) - 8)); } } }}int NetCksumOk(char * ptr, int len){ return !((NetCksum(ptr, len) + 1) & 0xfffe);}unsigned NetCksum(char * ptr, int len){ unsigned long xsum; unsigned short *p16 = (unsigned short *)ptr; xsum = 0; while (len-- > 0){// xsum += (*((unsigned short *)ptr)++); xsum += (*p16++); } xsum = (xsum & 0xffff) + (xsum >> 16); xsum = (xsum & 0xffff) + (xsum >> 16); return (xsum & 0xffff);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -