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

📄 ipconfig.c

📁 嵌入式系统设计与实验教材二源码linux内核移植与编译
💻 C
📖 第 1 页 / 共 3 页
字号:
	ic_got_reply = IC_RARP;drop:	/* Show's over.  Nothing to see here.  */	spin_unlock(&ic_recv_lock);	/* Throw the packet out. */	kfree_skb(skb);	return 0;}/* *  Send RARP request packet over a signle interface. */static void __init ic_rarp_send_if(struct ic_device *d){	struct net_device *dev = d->dev;	arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,		 dev->dev_addr, dev->dev_addr);}#endif/* *	DHCP/BOOTP support. */#ifdef IPCONFIG_BOOTPstruct bootp_pkt {		/* BOOTP packet format */	struct iphdr iph;	/* IP header */	struct udphdr udph;	/* UDP header */	u8 op;			/* 1=request, 2=reply */	u8 htype;		/* HW address type */	u8 hlen;		/* HW address length */	u8 hops;		/* Used only by gateways */	u32 xid;		/* Transaction ID */	u16 secs;		/* Seconds since we started */	u16 flags;		/* Just what it says */	u32 client_ip;		/* Client's IP address if known */	u32 your_ip;		/* Assigned IP address */	u32 server_ip;		/* (Next, e.g. NFS) Server's IP address */	u32 relay_ip;		/* IP address of BOOTP relay */	u8 hw_addr[16];		/* Client's HW address */	u8 serv_name[64];	/* Server host name */	u8 boot_file[128];	/* Name of boot file */	u8 exten[312];		/* DHCP options / BOOTP vendor extensions */};/* packet ops */#define BOOTP_REQUEST	1#define BOOTP_REPLY	2/* DHCP message types */#define DHCPDISCOVER	1#define DHCPOFFER	2#define DHCPREQUEST	3#define DHCPDECLINE	4#define DHCPACK		5#define DHCPNAK		6#define DHCPRELEASE	7#define DHCPINFORM	8static int ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt);static struct packet_type bootp_packet_type __initdata = {	type:	__constant_htons(ETH_P_IP),	func:	ic_bootp_recv,};/* *  Initialize DHCP/BOOTP extension fields in the request. */static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 };#ifdef IPCONFIG_DHCPstatic void __initic_dhcp_init_options(u8 *options){	u8 mt = ((ic_servaddr == INADDR_NONE)		 ? DHCPDISCOVER : DHCPREQUEST);	u8 *e = options;#ifdef IPCONFIG_DEBUG	printk("DHCP: Sending message type %d\n", mt);#endif	memcpy(e, ic_bootp_cookie, 4);	/* RFC1048 Magic Cookie */	e += 4;	*e++ = 53;		/* DHCP message type */	*e++ = 1;	*e++ = mt;	if (mt == DHCPREQUEST) {		*e++ = 54;	/* Server ID (IP address) */		*e++ = 4;		memcpy(e, &ic_servaddr, 4);		e += 4;		*e++ = 50;	/* Requested IP address */		*e++ = 4;		memcpy(e, &ic_myaddr, 4);		e += 4;	}	/* always? */	{		static const u8 ic_req_params[] = {			1,	/* Subnet mask */			3,	/* Default gateway */			6,	/* DNS server */			12,	/* Host name */			15,	/* Domain name */			17,	/* Boot path */			40,	/* NIS domain name */		};		*e++ = 55;	/* Parameter request list */		*e++ = sizeof(ic_req_params);		memcpy(e, ic_req_params, sizeof(ic_req_params));		e += sizeof(ic_req_params);	}	*e++ = 255;	/* End of the list */}#endif /* IPCONFIG_DHCP */static void __init ic_bootp_init_ext(u8 *e){	memcpy(e, ic_bootp_cookie, 4);	/* RFC1048 Magic Cookie */	e += 4;	*e++ = 1;		/* Subnet mask request */	*e++ = 4;	e += 4;	*e++ = 3;		/* Default gateway request */	*e++ = 4;	e += 4;	*e++ = 5;		/* Name server reqeust */	*e++ = 8;	e += 8;	*e++ = 12;		/* Host name request */	*e++ = 32;	e += 32;	*e++ = 40;		/* NIS Domain name request */	*e++ = 32;	e += 32;	*e++ = 17;		/* Boot path */	*e++ = 40;	e += 40;	*e++ = 57;		/* set extension buffer size for reply */ 	*e++ = 2;	*e++ = 1;		/* 128+236+8+20+14, see dhcpd sources */ 	*e++ = 150;	*e++ = 255;		/* End of the list */}/* *  Initialize the DHCP/BOOTP mechanism. */static inline void ic_bootp_init(void){	dev_add_pack(&bootp_packet_type);}/* *  DHCP/BOOTP cleanup. */static inline void ic_bootp_cleanup(void){	dev_remove_pack(&bootp_packet_type);}/* *  Send DHCP/BOOTP request to single interface. */static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_diff){	struct net_device *dev = d->dev;	struct sk_buff *skb;	struct bootp_pkt *b;	int hh_len = (dev->hard_header_len + 15) & ~15;	struct iphdr *h;	/* Allocate packet */	skb = alloc_skb(sizeof(struct bootp_pkt) + hh_len + 15, GFP_KERNEL);	if (!skb)		return;	skb_reserve(skb, hh_len);	b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt));	memset(b, 0, sizeof(struct bootp_pkt));	/* Construct IP header */	skb->nh.iph = h = &b->iph;	h->version = 4;	h->ihl = 5;	h->tot_len = htons(sizeof(struct bootp_pkt));	h->frag_off = __constant_htons(IP_DF);	h->ttl = 64;	h->protocol = IPPROTO_UDP;	h->daddr = INADDR_BROADCAST;	h->check = ip_fast_csum((unsigned char *) h, h->ihl);	/* Construct UDP header */	b->udph.source = __constant_htons(68);	b->udph.dest = __constant_htons(67);	b->udph.len = htons(sizeof(struct bootp_pkt) - sizeof(struct iphdr));	/* UDP checksum not calculated -- explicitly allowed in BOOTP RFC */	/* Construct DHCP/BOOTP header */	b->op = BOOTP_REQUEST;	if (dev->type < 256) /* check for false types */		b->htype = dev->type;	else if (dev->type == ARPHRD_IEEE802_TR) /* fix for token ring */		b->htype = ARPHRD_IEEE802;	else {		printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);		b->htype = dev->type; /* can cause undefined behavior */	}	b->hlen = dev->addr_len;	b->your_ip = INADDR_NONE;	b->server_ip = INADDR_NONE;	memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);	b->secs = htons(jiffies_diff / HZ);	b->xid = d->xid;	/* add DHCP options or BOOTP extensions */#ifdef IPCONFIG_DHCP	if (ic_proto_enabled & IC_USE_DHCP)		ic_dhcp_init_options(b->exten);	else#endif		ic_bootp_init_ext(b->exten);	/* Chain packet down the line... */	skb->dev = dev;	skb->protocol = __constant_htons(ETH_P_IP);	if ((dev->hard_header &&	     dev->hard_header(skb, dev, ntohs(skb->protocol), dev->broadcast, dev->dev_addr, skb->len) < 0) ||	    dev_queue_xmit(skb) < 0)		printk("E");}/* *  Copy BOOTP-supplied string if not already set. */static int __init ic_bootp_string(char *dest, char *src, int len, int max){	if (!len)		return 0;	if (len > max-1)		len = max-1;	memcpy(dest, src, len);	dest[len] = '\0';	return 1;}/* *  Process BOOTP extensions. */static void __init ic_do_bootp_ext(u8 *ext){#ifdef IPCONFIG_DEBUG	u8 *c;	printk("DHCP/BOOTP: Got extension %d:",*ext);	for(c=ext+2; c<ext+2+ext[1]; c++)		printk(" %02x", *c);	printk("\n");#endif	switch (*ext++) {		case 1:		/* Subnet mask */			if (ic_netmask == INADDR_NONE)				memcpy(&ic_netmask, ext+1, 4);			break;		case 3:		/* Default gateway */			if (ic_gateway == INADDR_NONE)				memcpy(&ic_gateway, ext+1, 4);			break;		case 6:		/* DNS server */			if (ic_nameserver == INADDR_NONE)				memcpy(&ic_nameserver, ext+1, 4);			break;		case 12:	/* Host name */			ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);			ic_host_name_set = 1;			break;		case 15:	/* Domain name (DNS) */			ic_bootp_string(ic_domain, ext+1, *ext, sizeof(ic_domain));			break;		case 17:	/* Root path */			if (!root_server_path[0])				ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path));			break;		case 40:	/* NIS Domain name (_not_ DNS) */			ic_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);			break;	}}/* *  Receive BOOTP reply. */static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt){	struct bootp_pkt *b = (struct bootp_pkt *) skb->nh.iph;	struct iphdr *h = &b->iph;	struct ic_device *d;	int len;	/* One reply at a time, please. */	spin_lock(&ic_recv_lock);	/* If we already have a reply, just drop the packet */	if (ic_got_reply)		goto drop;	/* Find the ic_device that the packet arrived on */	d = ic_first_dev;	while (d && d->dev != dev)		d = d->next;	if (!d)		goto drop;  /* should never happen */	/* Check whether it's a BOOTP packet */	if (skb->pkt_type == PACKET_OTHERHOST ||	    skb->len < sizeof(struct udphdr) + sizeof(struct iphdr) ||	    h->ihl != 5 ||	    h->version != 4 ||	    ip_fast_csum((char *) h, h->ihl) != 0 ||	    skb->len < ntohs(h->tot_len) ||	    h->protocol != IPPROTO_UDP ||	    b->udph.source != __constant_htons(67) ||	    b->udph.dest != __constant_htons(68) ||	    ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))		goto drop;	/* Fragments are not supported */	if (h->frag_off & __constant_htons(IP_OFFSET | IP_MF)) {		printk(KERN_ERR "DHCP/BOOTP: Ignoring fragmented reply.\n");		goto drop;	}	/* Is it a reply to our BOOTP request? */	len = ntohs(b->udph.len) - sizeof(struct udphdr);	if (len < 300 ||				    /* See RFC 951:2.1 */	    b->op != BOOTP_REPLY ||	    b->xid != d->xid) {		printk("?");		goto drop;	}	/* Parse extensions */	if (!memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */                u8 *end = (u8 *) b + ntohs(b->iph.tot_len);		u8 *ext;#ifdef IPCONFIG_DHCP		if (ic_proto_enabled & IC_USE_DHCP) {			u32 server_id = INADDR_NONE;			int mt = 0;			ext = &b->exten[4];			while (ext < end && *ext != 0xff) {				u8 *opt = ext++;				if (*opt == 0)	/* Padding */					continue;				ext += *ext + 1;				if (ext >= end)					break;				switch (*opt) {				case 53:	/* Message type */					if (opt[1])						mt = opt[2];					break;				case 54:	/* Server ID (IP address) */					if (opt[1] >= 4)						memcpy(&server_id, opt + 2, 4);					break;				};			}#ifdef IPCONFIG_DEBUG			printk("DHCP: Got message type %d\n", mt);#endif			switch (mt) {			case DHCPOFFER:				/* While in the process of accepting one offer,				 * ignore all others.				 */				if (ic_myaddr != INADDR_NONE)					goto drop;				/* Let's accept that offer. */				ic_myaddr = b->your_ip;				ic_servaddr = server_id;#ifdef IPCONFIG_DEBUG				printk("DHCP: Offered address %u.%u.%u.%u",				       NIPQUAD(ic_myaddr));				printk(" by server %u.%u.%u.%u\n",				       NIPQUAD(ic_servaddr));#endif				/* The DHCP indicated server address takes				 * precedence over the bootp header one if				 * they are different.				 */				if ((server_id != INADDR_NONE) &&				    (b->server_ip != server_id))					b->server_ip = ic_servaddr;				break;			case DHCPACK:				/* Yeah! */				break;			default:				/* Urque.  Forget it*/				ic_myaddr = INADDR_NONE;				ic_servaddr = INADDR_NONE;				goto drop;			};			ic_dhcp_msgtype = mt;		}#endif /* IPCONFIG_DHCP */		ext = &b->exten[4];		while (ext < end && *ext != 0xff) {			u8 *opt = ext++;			if (*opt == 0)	/* Padding */				continue;			ext += *ext + 1;			if (ext < end)				ic_do_bootp_ext(opt);		}	}	/* We have a winner! */	ic_dev = dev;	ic_myaddr = b->your_ip;	ic_servaddr = b->server_ip;	if (ic_gateway == INADDR_NONE && b->relay_ip)

⌨️ 快捷键说明

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