📄 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 <armboot.h>#include <command.h>#include "net.h"#include "bootp.h"#include "tftp.h"#include "rarp.h"#include "arp.h"#if (CONFIG_COMMANDS & CFG_CMD_NET)#if 0#define ET_DEBUG#endif/** BOOTP EXTENTIONS **/IPaddr_t NetOurSubnetMask=0; /* Our subnet mask (0=unknown) */IPaddr_t NetOurGatewayIP=0; /* Our gateways IP address */IPaddr_t NetOurDNSIP=0; /* Our DNS IP address */char NetOurNISDomain[32]={0,}; /* Our NIS domain */char NetOurHostName[32]={0,}; /* Our hostname */char NetOurRootPath[64]={0,}; /* Our bootpath */ushort NetBootFileSize=0; /* Our bootfile size in blocks *//** END OF BOOTP EXTENTIONS **/ulong NetBootFileXferSize; /* The actual transferred size of the bootfile (in bytes) */uchar NetOurEther[6]; /* Our ethernet address */uchar NetServerEther[6] = /* Boot server enet address */ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */volatile uchar *NetRxPkt; /* Current receive packet */int NetRxPktLen; /* Current rx packet length */unsigned NetIPID; /* IP packet ID */uchar NetBcastAddr[6] = /* Ethernet bcast address */ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };int NetState; /* Network loop state */char BootFile[128]; /* Boot File name */volatile uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];volatile uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */static rxhand_f *packetHandler; /* Current RX packet handler */static thand_f *timeHandler; /* Current timeout handler */static ulong timeValue; /* Current timeout value */volatile uchar *NetTxPacket = 0; /* THE transmit packet */bd_t *Net_bd;static int net_check_prereq (proto_t protocol);#ifdef ET_DEBUGvoid hexdump(uchar * data, unsigned long size);#endifvoid NetPrintEther(volatile uchar * addr);/**********************************************************************//* * Main network processing loop. */intNetLoop(bd_t *bis, proto_t protocol){ char *s, *e; ulong reg; Net_bd = bis; if (!NetTxPacket) { int i; /* * Setup packet buffers, aligned correctly. */ NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); NetTxPacket -= (ulong)NetTxPacket % PKTALIGN; for (i = 0; i < PKTBUFSRX; i++) { NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN; } } eth_halt(); eth_init(bis); NetCopyEther(NetOurEther, bis->bi_enetaddr);restart: NetState = NETLOOP_CONTINUE; /* * Start the ball rolling with the given start function. From * here on, this code is a state machine driven by received * packets and timer events. */ if (protocol == TFTP) { /* TFTP */ NetOurIP = bis->bi_ip_addr; NetServerIP = 0; s = getenv (bis, "serverip"); for (reg=0; reg<4; ++reg) { ulong val = s ? simple_strtoul(s, &e, 10) : 0; NetServerIP <<= 8; NetServerIP |= (val & 0xFF); if (s) s = (*e) ? e+1 : e; } if (net_check_prereq (protocol) != 0) { return 0; } /* always use ARP to get server ethernet address */ ArpTry = 0; ArpRequest ();#if (CONFIG_COMMANDS & CFG_CMD_DHCP) } else if (protocol == DHCP) { if (net_check_prereq (protocol) != 0) { return 0; } /* Start with a clean slate... */ NetOurIP = 0; NetServerIP = 0; DhcpRequest(); /* Basically same as BOOTP */#endif /* CFG_CMD_DHCP */ } else { /* BOOTP or RARP */ /* * initialize our IP addr to 0 in order to accept ANY * IP addr assigned to us by the BOOTP / RARP server */ NetOurIP = 0; NetServerIP = 0; if (net_check_prereq (protocol) != 0) { return 0; } if (protocol == BOOTP) { BootpTry = 0; BootpRequest (); } else { RarpTry = 0; RarpRequest (); } } NetBootFileXferSize = 0; /* * Main packet reception loop. Loop receiving packets until * someone sets `NetQuit'. */ for (;;) { /* * Check the ethernet for a new packet. The ethernet * receive routine will process it. */ eth_rx(); /* * Abort if ctrl-c was pressed. */ if (ctrlc()) { eth_halt(); printf("\nAbort\n"); return 0; } /* * Check for a timeout, and run the timeout handler * if we have one. */ if (timeHandler && (get_timer(0) > timeValue)) { thand_f *x; x = timeHandler; timeHandler = (thand_f *)0; (*x)(); } switch (NetState) { case NETLOOP_RESTART: goto restart; case NETLOOP_SUCCESS: if (NetBootFileXferSize > 0) { char buf[10]; printf("Bytes transferred = %ld (%lx hex)\n", NetBootFileXferSize, NetBootFileXferSize); sprintf(buf, "%lx", NetBootFileXferSize); setenv(bis, "filesize", buf); } eth_halt(); return 1; case NETLOOP_FAIL: return 0; } }}/**********************************************************************/static voidstartAgainTimeout(void){ NetState = NETLOOP_RESTART;}static voidstartAgainHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len){ /* Totally ignore the packet */}voidNetStartAgain(void){ NetSetTimeout(10 * CFG_HZ, startAgainTimeout); NetSetHandler(startAgainHandler);}/**********************************************************************//* * Miscelaneous bits. */voidNetSetHandler(rxhand_f * f){ packetHandler = f;}voidNetSetTimeout(int iv, thand_f * f){ if (iv == 0) { timeHandler = (thand_f *)0; } else { timeHandler = f; timeValue = get_timer(0) + iv; }}voidNetSendPacket(volatile uchar * pkt, int len){ (void) eth_send(pkt, len);}voidNetReceive(volatile uchar * 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); if (x < 1514) { /* * Got a 802 packet. Check the other protocol field. */ x = SWAP16(et->et_prot); ip = (IP_t *)(pkt + E802_HDR_SIZE); len -= E802_HDR_SIZE;#ifdef ET_DEBUG printf("Receive 802 type ET, protocol 0x%x\n", x);#endif } else { ip = (IP_t *)(pkt + ETHER_HDR_SIZE); len -= ETHER_HDR_SIZE;#ifdef ET_DEBUG printf("Receive non-802 type ET\n");#endif } switch (x) { case PROT_ARP: /* * We have to deal with two types of ARP packets: * - REQUEST packets will be answered by sending our * IP address - if we know it. * - REPLY packates are expected only after we asked * for the TFTP server's or the gateway's ethernet * address; so if we receive such a packet, we set * the server ethernet address */#ifdef ET_DEBUG printf("Got ARP\n");#endif 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -