⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootp.c

📁 嵌入式试验箱S3C2410的bootloader源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	Based on LiMon - BOOTP. * *	Copyright 1994, 1995, 2000 Neil Russell. *	(See License) *	Copyright 2000 Roland Borde *	Copyright 2000 Paolo Scaffardi *	Copyright 2000-2004 Wolfgang Denk, wd@denx.de */#if 0#define DEBUG		1	/* general debug */#define DEBUG_BOOTP_EXT 1	/* Debug received vendor fields */#endif#ifdef DEBUG_BOOTP_EXT#define debug_ext(fmt,args...)	printf (fmt ,##args)#else#define debug_ext(fmt,args...)#endif#include <common.h>#include <command.h>#include <net.h>#include "bootp.h"#include "tftp.h"#include "nfs.h"#ifdef CONFIG_STATUS_LED#include <status_led.h>#endif#define BOOTP_VENDOR_MAGIC	0x63825363	/* RFC1048 Magic Cookie		*/#if (CONFIG_COMMANDS & CFG_CMD_NET)#define TIMEOUT		5		/* Seconds before trying BOOTP again	*/#ifndef CONFIG_NET_RETRY_COUNT# define TIMEOUT_COUNT	5		/* # of timeouts before giving up  */#else# define TIMEOUT_COUNT	(CONFIG_NET_RETRY_COUNT)#endif#define PORT_BOOTPS	67		/* BOOTP server UDP port		*/#define PORT_BOOTPC	68		/* BOOTP client UDP port		*/#ifndef CONFIG_DHCP_MIN_EXT_LEN		/* minimal length of extension list	*/#define CONFIG_DHCP_MIN_EXT_LEN 64#endifulong		BootpID;int		BootpTry;#ifdef CONFIG_BOOTP_RANDOM_DELAYulong		seed1, seed2;#endif#if (CONFIG_COMMANDS & CFG_CMD_DHCP)dhcp_state_t dhcp_state = INIT;unsigned long dhcp_leasetime = 0;IPaddr_t NetDHCPServerIP = 0;static void DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len);/* For Debug */#if 0static char *dhcpmsg2str(int type){	switch (type) {	case 1:	 return "DHCPDISCOVER"; break;	case 2:	 return "DHCPOFFER";	break;	case 3:	 return "DHCPREQUEST";	break;	case 4:	 return "DHCPDECLINE";	break;	case 5:	 return "DHCPACK";	break;	case 6:	 return "DHCPNACK";	break;	case 7:	 return "DHCPRELEASE";	break;	default: return "UNKNOWN/INVALID MSG TYPE"; break;	}}#endif#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX)extern u8 *dhcp_vendorex_prep (u8 *e); /*rtn new e after add own opts. */extern u8 *dhcp_vendorex_proc (u8 *e); /*rtn next e if mine,else NULL  */#endif#endif	/* CFG_CMD_DHCP */static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len){	Bootp_t *bp = (Bootp_t *) pkt;	int retval = 0;	if (dest != PORT_BOOTPC || src != PORT_BOOTPS)		retval = -1;	else if (len < sizeof (Bootp_t) - OPT_SIZE)		retval = -2;	else if (bp->bp_op != OP_BOOTREQUEST &&	    bp->bp_op != OP_BOOTREPLY &&	    bp->bp_op != DHCP_OFFER &&	    bp->bp_op != DHCP_ACK &&	    bp->bp_op != DHCP_NAK ) {		retval = -3;	}	else if (bp->bp_htype != HWT_ETHER)		retval = -4;	else if (bp->bp_hlen != HWL_ETHER)		retval = -5;	else if (NetReadLong((ulong*)&bp->bp_id) != BootpID) {		retval = -6;	}	debug ("Filtering pkt = %d\n", retval);	return retval;}/* * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet */static void BootpCopyNetParams(Bootp_t *bp){	IPaddr_t tmp_ip;	NetCopyIP(&NetOurIP, &bp->bp_yiaddr);	NetCopyIP(&tmp_ip, &bp->bp_siaddr);	if (tmp_ip != 0)		NetCopyIP(&NetServerIP, &bp->bp_siaddr);	memcpy (NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src, 6);	if (strlen(bp->bp_file) > 0)		copy_filename (BootFile, bp->bp_file, sizeof(BootFile));	debug ("Bootfile: %s\n", BootFile);	/* Propagate to environment:	 * don't delete exising entry when BOOTP / DHCP reply does	 * not contain a new value	 */	if (*BootFile) {		setenv ("bootfile", BootFile);	}}static int truncate_sz (const char *name, int maxlen, int curlen){	if (curlen >= maxlen) {		printf("*** WARNING: %s is too long (%d - max: %d) - truncated\n",			name, curlen, maxlen);		curlen = maxlen - 1;	}	return (curlen);}#if !(CONFIG_COMMANDS & CFG_CMD_DHCP)static void BootpVendorFieldProcess (u8 * ext){	int size = *(ext + 1);	debug_ext ("[BOOTP] Processing extension %d... (%d bytes)\n", *ext,		   *(ext + 1));	NetBootFileSize = 0;	switch (*ext) {		/* Fixed length fields */	case 1:			/* Subnet mask                                  */		if (NetOurSubnetMask == 0)			NetCopyIP (&NetOurSubnetMask, (IPaddr_t *) (ext + 2));		break;	case 2:			/* Time offset - Not yet supported              */		break;		/* Variable length fields */	case 3:			/* Gateways list                                */		if (NetOurGatewayIP == 0) {			NetCopyIP (&NetOurGatewayIP, (IPaddr_t *) (ext + 2));		}		break;	case 4:			/* Time server - Not yet supported              */		break;	case 5:			/* IEN-116 name server - Not yet supported      */		break;	case 6:		if (NetOurDNSIP == 0) {			NetCopyIP (&NetOurDNSIP, (IPaddr_t *) (ext + 2));		}#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS2)		if ((NetOurDNS2IP == 0) && (size > 4)) {			NetCopyIP (&NetOurDNS2IP, (IPaddr_t *) (ext + 2 + 4));		}#endif		break;	case 7:			/* Log server - Not yet supported               */		break;	case 8:			/* Cookie/Quote server - Not yet supported      */		break;	case 9:			/* LPR server - Not yet supported               */		break;	case 10:		/* Impress server - Not yet supported           */		break;	case 11:		/* RPL server - Not yet supported               */		break;	case 12:		/* Host name                                    */		if (NetOurHostName[0] == 0) {			size = truncate_sz ("Host Name", sizeof (NetOurHostName), size);			memcpy (&NetOurHostName, ext + 2, size);			NetOurHostName[size] = 0;		}		break;	case 13:		/* Boot file size                               */		if (size == 2)			NetBootFileSize = ntohs (*(ushort *) (ext + 2));		else if (size == 4)			NetBootFileSize = ntohl (*(ulong *) (ext + 2));		break;	case 14:		/* Merit dump file - Not yet supported          */		break;	case 15:		/* Domain name - Not yet supported              */		break;	case 16:		/* Swap server - Not yet supported              */		break;	case 17:		/* Root path                                    */		if (NetOurRootPath[0] == 0) {			size = truncate_sz ("Root Path", sizeof (NetOurRootPath), size);			memcpy (&NetOurRootPath, ext + 2, size);			NetOurRootPath[size] = 0;		}		break;	case 18:		/* Extension path - Not yet supported           */		/*		 * This can be used to send the information of the		 * vendor area in another file that the client can		 * access via TFTP.		 */		break;		/* IP host layer fields */	case 40:		/* NIS Domain name                              */		if (NetOurNISDomain[0] == 0) {			size = truncate_sz ("NIS Domain Name", sizeof (NetOurNISDomain), size);			memcpy (&NetOurNISDomain, ext + 2, size);			NetOurNISDomain[size] = 0;		}		break;		/* Application layer fields */	case 43:		/* Vendor specific info - Not yet supported     */		/*		 * Binary information to exchange specific		 * product information.		 */		break;		/* Reserved (custom) fields (128..254) */	}}static void BootpVendorProcess (u8 * ext, int size){	u8 *end = ext + size;	debug_ext ("[BOOTP] Checking extension (%d bytes)...\n", size);	while ((ext < end) && (*ext != 0xff)) {		if (*ext == 0) {			ext++;		} else {			u8 *opt = ext;			ext += ext[1] + 2;			if (ext <= end)				BootpVendorFieldProcess (opt);		}	}#ifdef DEBUG_BOOTP_EXT	puts ("[BOOTP] Received fields: \n");	if (NetOurSubnetMask) {		puts ("NetOurSubnetMask : ");		print_IPaddr (NetOurSubnetMask);		putc ('\n');	}	if (NetOurGatewayIP) {		puts ("NetOurGatewayIP	: ");		print_IPaddr (NetOurGatewayIP);		putc ('\n');	}	if (NetBootFileSize) {		printf ("NetBootFileSize : %d\n", NetBootFileSize);	}	if (NetOurHostName[0]) {		printf ("NetOurHostName  : %s\n", NetOurHostName);	}	if (NetOurRootPath[0]) {		printf ("NetOurRootPath  : %s\n", NetOurRootPath);	}	if (NetOurNISDomain[0]) {		printf ("NetOurNISDomain : %s\n", NetOurNISDomain);	}	if (NetBootFileSize) {		printf ("NetBootFileSize: %d\n", NetBootFileSize);	}#endif /* DEBUG_BOOTP_EXT */}/* *	Handle a BOOTP received packet. */static voidBootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len){	Bootp_t *bp;	char	*s;	debug ("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%d)\n",		src, dest, len, sizeof (Bootp_t));	bp = (Bootp_t *)pkt;	if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */		return;	/*	 *	Got a good BOOTP reply.	 Copy the data into our variables.	 */#ifdef CONFIG_STATUS_LED	status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF);#endif	BootpCopyNetParams(bp);		/* Store net parameters from reply */	/* Retrieve extended information (we must parse the vendor area) */	if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))		BootpVendorProcess((uchar *)&bp->bp_vend[4], len);	NetSetTimeout(0, (thand_f *)0);	debug ("Got good BOOTP\n");	if ((s = getenv("autoload")) != NULL) {		if (*s == 'n') {			/*			 * Just use BOOTP to configure system;			 * Do not use TFTP to load the bootfile.			 */			NetState = NETLOOP_SUCCESS;			return;#if (CONFIG_COMMANDS & CFG_CMD_NFS)		} else if (strcmp(s, "NFS") == 0) {			/*			 * Use NFS to load the bootfile.			 */			NfsStart();			return;#endif		}	}	TftpStart();}#endif	/* !CFG_CMD_DHCP *//* *	Timeout on BOOTP/DHCP request. */static voidBootpTimeout(void){	if (BootpTry >= TIMEOUT_COUNT) {		puts ("\nRetry count exceeded; starting again\n");		NetStartAgain ();	} else {		NetSetTimeout (TIMEOUT * CFG_HZ, BootpTimeout);		BootpRequest ();	}}/* *	Initialize BOOTP extension fields in the request. */#if (CONFIG_COMMANDS & CFG_CMD_DHCP)static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t RequestedIP){	u8 *start = e;	u8 *cnt;#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX)	u8 *x;#endif#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SEND_HOSTNAME)	char *hostname;#endif	*e++ = 99;		/* RFC1048 Magic Cookie */	*e++ = 130;	*e++ = 83;	*e++ = 99;	*e++ = 53;		/* DHCP Message Type */	*e++ = 1;	*e++ = message_type;	*e++ = 57;		/* Maximum DHCP Message Size */	*e++ = 2;	*e++ = (576 - 312 + OPT_SIZE) >> 8;	*e++ = (576 - 312 + OPT_SIZE) & 0xff;	if (ServerID) {		int tmp = ntohl (ServerID);		*e++ = 54;	/* ServerID */		*e++ = 4;		*e++ = tmp >> 24;		*e++ = tmp >> 16;		*e++ = tmp >> 8;		*e++ = tmp & 0xff;	}	if (RequestedIP) {		int tmp = ntohl (RequestedIP);		*e++ = 50;	/* Requested IP */		*e++ = 4;		*e++ = tmp >> 24;		*e++ = tmp >> 16;		*e++ = tmp >> 8;		*e++ = tmp & 0xff;	}#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SEND_HOSTNAME)	if ((hostname = getenv ("hostname"))) {		int hostnamelen = strlen (hostname);		*e++ = 12;	/* Hostname */		*e++ = hostnamelen;		memcpy (e, hostname, hostnamelen);		e += hostnamelen;	}#endif#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX)	if ((x = dhcp_vendorex_prep (e)))		return x - start;#endif	*e++ = 55;		/* Parameter Request List */	 cnt = e++;		/* Pointer to count of requested items */	*cnt = 0;#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SUBNETMASK)	*e++  = 1;		/* Subnet Mask */	*cnt += 1;#endif#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_TIMEOFFSET)	*e++  = 2;	*cnt += 1;#endif#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_GATEWAY)	*e++  = 3;		/* Router Option */	*cnt += 1;#endif#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS)	*e++  = 6;		/* DNS Server(s) */	*cnt += 1;#endif#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_HOSTNAME)	*e++  = 12;		/* Hostname */	*cnt += 1;#endif#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTFILESIZE)	*e++  = 13;		/* Boot File Size */	*cnt += 1;#endif#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTPATH)	*e++  = 17;		/* Boot path */	*cnt += 1;#endif#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NISDOMAIN)	*e++  = 40;		/* NIS Domain name request */	*cnt += 1;#endif#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NTPSERVER)	*e++  = 42;	*cnt += 1;#endif	*e++  = 255;		/* End of the list */	/* Pad to minimal length */#ifdef	CONFIG_DHCP_MIN_EXT_LEN	while ((e - start) <= CONFIG_DHCP_MIN_EXT_LEN)		*e++ = 0;#endif	return e - start;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -