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

📄 dhcpboot.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 3 页
字号:
	DHCPState = BOOTPSTATE_COMPLETE;

	/* Call loadBootFile() which will then kick off a tftp client
	 * transfer if both BOOTFILE and BOOTSRVR shell variables are
	 * loaded; otherwise, we are done.
	 */
	loadBootFile(1);

	return(0);
}

int
processDHCP(struct ether_header *ehdr,ushort size)
{
	struct	ip *ihdr;
	struct	Udphdr *uhdr;
	struct	dhcphdr *dhdr;
	uchar	buf[16], *op, msgtype;
	ulong	ip, temp_ip, leasetime;

	if (DHCPState == BOOTPSTATE_REQUEST)
		return(processBOOTP(ehdr,size));

	if (EtherVerbose & SHOW_HEX)
		printMem((uchar *)ehdr,size,EtherVerbose & SHOW_ASCII);

	ihdr = (struct ip *)(ehdr + 1);
	uhdr = (struct Udphdr *)((char *)ihdr + IP_HLEN(ihdr));
	dhdr = (struct dhcphdr *)(uhdr+1);

	/* Verify incoming transaction id matches the previous outgoing value: */
	if (xidCheck((char *)&dhdr->transaction_id,0) < 0)
		return(-1);

	op = DhcpGetOption(DHCPOPT_MESSAGETYPE,(char *)(dhdr+1));
	if (op)
		msgtype = *(op+2);
	else
		msgtype = DHCPUNKNOWN;

	if ((DHCPState == DHCPSTATE_SELECT) && (msgtype == DHCPOFFER)) {
		/* Target issued the DISCOVER, the incoming packet is the server's
		 * OFFER reply.  The function "ValidDHCPOffer() will return
		 * non-zero if the request is to be sent.
		 */
		if (ValidDHCPOffer(dhdr))
			SendDHCPRequest(dhdr);
		else if (EtherVerbose & SHOW_DHCP) {
			char ip[4];
			memcpy(ip,(char *)&ihdr->ip_src,4);
			printf("  DHCP offer from %d.%d.%d.%d ignored\n",
				ip[0],ip[1],ip[2],ip[3]);
		}
	}
	else if ((DHCPState == DHCPSTATE_REQUEST) && (msgtype == DHCPACK)) {
		ulong	cookie;

		/* Target issued the REQUEST, the incoming packet is the server's
		 * ACK reply.  We're done so load the environment now.
		 */

		/* If bootfile is nonzero, store it into BOOTFILE shell var: */
		if (dhdr->bootfile[0])
			DhcpSetEnv("BOOTFILE",dhdr->bootfile);

		/* Assign IP "server_ip" to the BOOTSRVR shell var (if non-zero): */
		memcpy((char *)&temp_ip,(char *)&dhdr->server_ip,4);
		if (temp_ip)
			DhcpSetEnv("BOOTSRVR",IpToString(temp_ip,buf));

		/* Assign IP "router_ip" to the RLYAGNT shell var (if non-zero): */
		memcpy((char *)&temp_ip,(char *)&dhdr->router_ip,4);
		if (temp_ip)
			DhcpSetEnv("RLYAGNT",IpToString(temp_ip,buf));

		/* Assign IP address loaded in "your_ip" to the IPADD shell var: */
		memcpy(BinIpAddr,(char *)&dhdr->your_ip,4);
		memcpy((char *)&temp_ip,(char *)&dhdr->your_ip,4);
		DhcpSetEnv("IPADD",IpToString(temp_ip,buf));

		/* If STANDARD_MAGIC_COOKIE exists, process options... */
		memcpy((char *)&cookie,(char *)&dhdr->magic_cookie,4);
		if (cookie == ecl(STANDARD_MAGIC_COOKIE)) {
			/* Assign subnet mask to NETMASK shell var (if found): */
			op = DhcpGetOption(DHCPOPT_SUBNETMASK,(char *)(dhdr+1));
			if (op) {
				memcpy((char *)&ip,op+2,4);
				DhcpSetEnv("NETMASK",IpToString(ip,buf));
			}

			/* Assign gateway IP to GIPADD shell var (if found):
			 * (the router option can have multiple entries, and they are
			 * supposed to be in order of preference, so use the first one).
	 		 */
			op = DhcpGetOption(DHCPOPT_ROUTER,(char *)(dhdr+1));
			if (op) {
				memcpy((char *)&ip,op+2,4);
				DhcpSetEnv("GIPADD",IpToString(ip,buf));
			}
			/* Process DHCPOPT_LEASETIME option as follows...
			 * If not set, assume infinite and clear DHCPLEASETIME shellvar.
			 * If set, then look for the presence of the DHCPLEASETIME shell
			 * variable and use it as a minimum.  If the incoming value is
			 * >= what is in the shell variable, accept it and load the shell
			 * variable with this value. If incoming lease time is less than
			 * what is stored in DHCPLEASETIME, ignore the request.
			 * If DHCPLEASETIME is not set, then just load the incoming lease
			 * into the DHCPLEASETIME shell variable and accept the offer.
			 */
			op = DhcpGetOption(DHCPOPT_LEASETIME,(char *)(dhdr+1));
			if (op) {
				memcpy((char *)&leasetime,op+2,4);
				leasetime = ecl(leasetime);
				if (getenv("DHCPLEASETIME")) {
					ulong	minleasetime;
					minleasetime = strtol(getenv("DHCPLEASETIME"),0,0);
					if (leasetime < minleasetime) {
						printf("DHCP: incoming lease time 0x%lx too small.\n",
							leasetime);
						return(-1);
					}
				}
				sprintf(buf,"0x%lx",leasetime);
				setenv("DHCPLEASETIME",buf);
			}
			else
				setenv("DHCPLEASETIME",0);
		}

		/* Check for vendor specific stuff... */
		DhcpVendorSpecific(dhdr);

		DhcpBootpDone(0,dhdr,
			size - ((int)((int)&dhdr->magic_cookie - (int)ehdr)));

		DHCPState = DHCPSTATE_BOUND;

		/* Call loadBootFile() which will then kick off a tftp client
		 * transfer if both BOOTFILE and BOOTSRVR shell variables are
		 * loaded; otherwise, we are done.
		 */
		loadBootFile(0);
	}
	return(0);
}

char *
DHCPop(op)
int	op;
{
	switch(op) {
	case DHCPBOOTP_REQUEST:
		return("REQUEST");
	case DHCPBOOTP_REPLY:
		return("REPLY");
	default:
		return("???");
	}
}

char *
DHCPopt(op)
int	op;
{
	switch(op) {
	case DHCPDISCOVER:
		return("DISCOVER");
	case DHCPOFFER:
		return("OFFER");
	case DHCPREQUEST:
		return("REQUEST");
	case DHCPDECLINE:
		return("DECLINE");
	case DHCPACK:
		return("ACK");
	case DHCPNACK:
		return("NACK");
	case DHCPRELEASE:
		return("RELEASE");
	default:
		return("???");

	}
}

/* printDhcpOptions():
 *	Verbosely display the DHCP options pointed to by the incoming
 *	options pointer.
 */
void
printDhcpOptions(uchar *options)
{
	int	i, safety, opt, optlen;

	safety = 0;
	while(*options != 0xff) {
		if (safety++ > 10000) {
			printf("Aborting, overflow likely\n");
			break;
		}
		opt = (int)*options++;
		if (opt == 0)	/* padding */
			continue;
		printf("    option %3d: ",opt);
		optlen = (int)*options++;
		if (opt==DHCPOPT_MESSAGETYPE) {
			printf("DHCP%s",DHCPopt(*options++));
		}
		/* Vendor specific information:
		 * Note that the data within this option is vendor specific.
		 * The RFC2132 says that the encapsulated data with this option
		 * SHOULD follow the same format as the outer-layer options, but
		 * is not mandatory.
		 */
		else if (opt==DHCPOPT_VENDORSPECIFICINFO) {
			int	vsopt, vsoptlen;

			printf("\n");
			while(*options != 0xff) {
				vsopt = (int)*options++;
				vsoptlen = (int)*options++;
				printf("       vso %3d: ",vsopt);
				if (!printDhcpVSopt(vsopt,vsoptlen,options)) {
					printf("0x");
					for(i=0;i<vsoptlen;i++)
						printf("%02x",*options++);
				}
				if (*options != 0xff)
					printf("\n");
			}
			options++;		/* Skip over the 0xff within this option sub-set */
		}
		else if ((opt < DHCPOPT_HOSTNAME) ||
		    (opt == DHCPOPT_BROADCASTADDRESS) ||
		    (opt == DHCPOPT_REQUESTEDIP) ||
		    (opt == DHCPOPT_SERVERID) ||
		    (opt == DHCPOPT_NISSERVER)) {
			for(i=0;i<optlen;i++)
				printf("%d ",*options++);
		}
		else if ((opt == DHCPOPT_NISDOMAINNAME) || (opt == DHCPOPT_CLASSID)) {
			for(i=0;i<optlen;i++)
				printf("%c",*options++);
		}
		else if (opt == DHCPOPT_CLIENTID) {
			printf("%d 0x",(int)*options++);
			for(i=1;i<optlen;i++)
				printf("%02x",*options++);
		}
		else {
			printf("0x");
			for(i=0;i<optlen;i++)
				printf("%02x",*options++);
		}
		printf("\n");
	}
}

/* printDhcp():
 *	Try to format the DHCP stuff...
 */
void
printDhcp(struct Udphdr *p)
{
	struct	dhcphdr *d;
	uchar 	*client_ip, *your_ip, *server_ip, *router_ip;
	ulong	cookie, xid;

	d = (struct dhcphdr *)(p+1);

	client_ip = (uchar *)&(d->client_ip);
	your_ip = (uchar *)&(d->your_ip);
	server_ip = (uchar *)&(d->server_ip);
	router_ip = (uchar *)&(d->router_ip);
	memcpy((char *)&xid,(char *)&d->transaction_id,4);
	/* xid = ecl(xid) */

	printf("  DHCP: sport dport ulen  sum\n");
	printf("        %4d  %4d %4d %4d\n",
		ecs(p->uh_sport), ecs(p->uh_dport), ecs(p->uh_ulen),ecs(p->uh_sum));
	printf("    op = %s, htype = %d, hlen = %d, hops = %d\n",
	    DHCPop(d->op),d->htype,d->hlen,d->hops);
	printf("    seconds = %d, flags = 0x%x, xid= 0x%lx\n",
		ecs(d->seconds),ecs(d->flags),xid);
	printf("    client_macaddr = %02x:%02x:%02x:%02x:%02x:%02x\n",
	    d->client_macaddr[0], d->client_macaddr[1],
	    d->client_macaddr[2], d->client_macaddr[3],
	    d->client_macaddr[4], d->client_macaddr[5]);
	printf("    client_ip = %d.%d.%d.%d\n",
	    client_ip[0],client_ip[1],client_ip[2],client_ip[3]);
	printf("    your_ip =   %d.%d.%d.%d\n",
	    your_ip[0],your_ip[1],your_ip[2],your_ip[3]);
	printf("    server_ip = %d.%d.%d.%d\n",
	    server_ip[0],server_ip[1],server_ip[2],server_ip[3]);
	printf("    router_ip = %d.%d.%d.%d\n",
	    router_ip[0],router_ip[1],router_ip[2],router_ip[3]);
	if (d->bootfile[0])
		printf("    bootfile: %s\n", d->bootfile);
	if (d->server_hostname[0])
		printf("    server_hostname: %s\n", d->server_hostname);

	/* If STANDARD_MAGIC_COOKIE doesn't exist, then don't process options... */
	memcpy((char *)&cookie,(char *)&d->magic_cookie,4);
	if (cookie != ecl(STANDARD_MAGIC_COOKIE))
		return;

	printDhcpOptions((uchar *)(d+1));
}

/* DhcpGetOption():
 *	Based on the incoming option pointer and a specified option value,
 *	search through the options list for the value and return a pointer
 *	to that option.
 */
uchar *
DhcpGetOption(unsigned char optval,unsigned char *options)
{
	int		safety;

	safety = 0;
	while(*options != 0xff) {
		if (safety++ > 1000)
			break;
		if (*options == 0) {	/* Skip over padding. */
			options++;
			continue;
		}
		if (*options == optval)
			return(options);
		options += ((*(options+1)) + 2);
	}
	return((char *)0);
}

int
DhcpSetEnv(char *name,char *value)
{
	if (EtherVerbose & SHOW_DHCP)
		printf("  Dhcp/Bootp SetEnv: %s = %s\n",name,value);
	return(setenv(name,value));
}

int
DhcpIPCheck(char *ipadd)
{
	char	verbose;

	if (!memcmp(ipadd,"DHCP",4)) {
		verbose = ipadd[4];
		DHCPState = DHCPSTATE_INITIALIZE;
	}
	else if (!memcmp(ipadd,"BOOTP",5)) {
		verbose = ipadd[5];
		DHCPState = BOOTPSTATE_INITIALIZE;
	}
	else {
		if (IpToBin(ipadd,BinIpAddr) < 0) {
			verbose = 0;
			DHCPState = BOOTPSTATE_INITIALIZE;
		}
		else {
			DHCPState = DHCPSTATE_NOTUSED;
			return(0);
		}
	}

	BinIpAddr[0] = 0; 
	BinIpAddr[1] = 0;
	BinIpAddr[2] = 0; 
	BinIpAddr[3] = 0;
	if (verbose == 'V')
		EtherVerbose = DHCP_VERBOSE;
	else if (verbose == 'v')
		EtherVerbose = SHOW_DHCP;
	return(0);
}

char *
dhcpStringState(int state)
{
	switch(state) {
		case DHCPSTATE_INITIALIZE:
			return("DHCP_INITIALIZE");
		case DHCPSTATE_SELECT:
			return("DHCP_SELECT");
		case DHCPSTATE_REQUEST:
			return("DHCP_REQUEST");
		case DHCPSTATE_BOUND:
			return("DHCP_BOUND");
		case DHCPSTATE_RENEW:
			return("DHCP_RENEW");
		case DHCPSTATE_REBIND:
			return("DHCP_REBIND");
		case DHCPSTATE_NOTUSED:
			return("DHCP_NOTUSED");
		case DHCPSTATE_RESTART:
			return("DHCP_RESTART");
		case BOOTPSTATE_INITIALIZE:
			return("BOOTP_INITIALIZE");
		case BOOTPSTATE_REQUEST:
			return("BOOTP_REQUEST");
		case BOOTPSTATE_RESTART:
			return("BOOTP_RESTART");
		case BOOTPSTATE_COMPLETE:
			return("BOOTP_COMPLETE");
		default:
			return("???");
	}
}

void
ShowDhcpStats()
{
	printf("Current DHCP State: %s\n",dhcpStringState(DHCPState));
}

#endif

⌨️ 快捷键说明

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