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

📄 bootp_proto.c

📁 klibc精简化的c程序库
💻 C
字号:
/* * BOOTP packet protocol handling. */#include <sys/types.h>#include <sys/uio.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <netinet/in.h>#include "ipconfig.h"#include "netdev.h"#include "bootp_packet.h"#include "bootp_proto.h"#include "packet.h"static uint8_t bootp_options[312] = {	[  0] = 99, 130, 83, 99,/* RFC1048 magic cookie */	[  4] = 1, 4,		/*   4-  9 subnet mask */	[ 10] = 3, 4,		/*  10- 15 default gateway */	[ 16] = 5, 8,		/*  16- 25 nameserver */	[ 26] = 12, 32,		/*  26- 59 host name */	[ 60] = 40, 32,		/*  60- 95 nis domain name */	[ 96] = 17, 40,		/*  96-137 boot path */	[138] = 57, 2, 1, 150,	/* 138-141 extension buffer */	[142] = 255,		/* end of list */};/* * Send a plain bootp request packet with options */int bootp_send_request(struct netdev *dev){	struct bootp_hdr bootp;	struct iovec iov[] = {		/* [0] = ip + udp headers */		[1] = {&bootp, sizeof(bootp)},		[2] = {bootp_options, 312}	};	memset(&bootp, 0, sizeof(struct bootp_hdr));	bootp.op	= BOOTP_REQUEST, bootp.htype = dev->hwtype;	bootp.hlen	= dev->hwlen;	bootp.xid	= dev->bootp.xid;	bootp.ciaddr	= dev->ip_addr;	bootp.secs	= htons(time(NULL) - dev->open_time);	memcpy(bootp.chaddr, dev->hwaddr, 16);	DEBUG(("-> bootp xid 0x%08x secs 0x%08x ",	       bootp.xid, ntohs(bootp.secs)));	return packet_send(dev, iov, 2);}/* * Parse a bootp reply packet */int bootp_parse(struct netdev *dev, struct bootp_hdr *hdr,		uint8_t *exts, int extlen){	dev->bootp.gateway	= hdr->giaddr;	dev->ip_addr		= hdr->yiaddr;	dev->ip_server		= hdr->siaddr;	dev->ip_netmask		= INADDR_ANY;	dev->ip_broadcast	= INADDR_ANY;	dev->ip_gateway		= hdr->giaddr;	dev->ip_nameserver[0]	= INADDR_ANY;	dev->ip_nameserver[1]	= INADDR_ANY;	dev->hostname[0]	= '\0';	dev->nisdomainname[0]	= '\0';	dev->bootpath[0]	= '\0';	memcpy(&dev->filename, &hdr->boot_file, FNLEN);	if (extlen >= 4 && exts[0] == 99 && exts[1] == 130 &&	    exts[2] == 83 && exts[3] == 99) {		uint8_t *ext;		for (ext = exts + 4; ext - exts < extlen;) {			int len;			uint8_t opt = *ext++;			if (opt == 0)				continue;			else if (opt == 255)				break;			len = *ext++;			switch (opt) {			case 1:	/* subnet mask */				if (len == 4)					memcpy(&dev->ip_netmask, ext, 4);				break;			case 3:	/* default gateway */				if (len >= 4)					memcpy(&dev->ip_gateway, ext, 4);				break;			case 6:	/* DNS server */				if (len >= 4)					memcpy(&dev->ip_nameserver, ext,					       len >= 8 ? 8 : 4);				break;			case 12:	/* host name */				if (len > sizeof(dev->hostname) - 1)					len = sizeof(dev->hostname) - 1;				memcpy(&dev->hostname, ext, len);				dev->hostname[len] = '\0';				break;			case 15:	/* domain name */				if (len > sizeof(dev->dnsdomainname) - 1)					len = sizeof(dev->dnsdomainname) - 1;				memcpy(&dev->dnsdomainname, ext, len);				dev->dnsdomainname[len] = '\0';				break;			case 17:	/* root path */				if (len > sizeof(dev->bootpath) - 1)					len = sizeof(dev->bootpath) - 1;				memcpy(&dev->bootpath, ext, len);				dev->bootpath[len] = '\0';				break;			case 26:	/* interface MTU */				if (len == 2)					dev->mtu = (ext[0] << 8) + ext[1];				break;			case 28:	/* broadcast addr */				if (len == 4)					memcpy(&dev->ip_broadcast, ext, 4);				break;			case 40:	/* NIS domain name */				if (len > sizeof(dev->nisdomainname) - 1)					len = sizeof(dev->nisdomainname) - 1;				memcpy(&dev->nisdomainname, ext, len);				dev->nisdomainname[len] = '\0';				break;			case 54: 	/* server identifier */				if (len == 4 && !dev->ip_server)					memcpy(&dev->ip_server, ext, 4);				break;			}			ext += len;		}	}	/*	 * Got packet.	 */	return 1;}/* * Receive a bootp reply and parse packet */int bootp_recv_reply(struct netdev *dev){	struct bootp_hdr bootp;	uint8_t bootp_options[312];	struct iovec iov[] = {		/* [0] = ip + udp headers */		[1] = {&bootp, sizeof(struct bootp_hdr)},		[2] = {bootp_options, 312}	};	int ret;	ret = packet_recv(iov, 3);	if (ret <= 0)		return ret;	if (ret < sizeof(struct bootp_hdr) ||	    bootp.op != BOOTP_REPLY ||	/* RFC951 7.5 */	    bootp.xid != dev->bootp.xid ||	    memcmp(bootp.chaddr, dev->hwaddr, 16))		return 0;	ret -= sizeof(struct bootp_hdr);	return bootp_parse(dev, &bootp, bootp_options, ret);}/* * Initialise interface for bootp. */int bootp_init_if(struct netdev *dev){	short flags;	/*	 * Get the device flags	 */	if (netdev_getflags(dev, &flags))		return -1;	/*	 * We can't do DHCP nor BOOTP if this device	 * doesn't support broadcast.	 */	if (dev->mtu < 364 || (flags & IFF_BROADCAST) == 0) {		dev->caps &= ~(CAP_BOOTP | CAP_DHCP);		return 0;	}	/*	 * Get a random XID	 */	dev->bootp.xid = (uint32_t) lrand48();	dev->open_time = time(NULL);	return 0;}

⌨️ 快捷键说明

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