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

📄 ipconfig.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
drop_unlock:	/* Show's over.  Nothing to see here.  */	spin_unlock(&ic_recv_lock);drop:	/* Throw the packet out. */	kfree_skb(skb);	return 0;}/* *  Send RARP request packet over a single 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 */	__be32 xid;		/* Transaction ID */	__be16 secs;		/* Seconds since we started */	__be16 flags;		/* Just what it says */	__be32 client_ip;		/* Client's IP address if known */	__be32 your_ip;		/* Assigned IP address */	__be32 server_ip;		/* (Next, e.g. NFS) Server's IP address */	__be32 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, struct net_device *orig_dev);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 == 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 request */	*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){	int i;	for (i = 0; i < CONF_NAMESERVERS_MAX; i++)		ic_nameservers[i] = NONE;	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 = LL_RESERVED_SPACE(dev);	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_reset_network_header(skb);	h = ip_hdr(skb);	h->version = 4;	h->ihl = 5;	h->tot_len = htons(sizeof(struct bootp_pkt));	h->frag_off = htons(IP_DF);	h->ttl = 64;	h->protocol = IPPROTO_UDP;	h->daddr = htonl(INADDR_BROADCAST);	h->check = ip_fast_csum((unsigned char *) h, h->ihl);	/* Construct UDP header */	b->udph.source = htons(68);	b->udph.dest = 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 if (dev->type == ARPHRD_FDDI)		b->htype = ARPHRD_ETHER;	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 = NONE;	b->server_ip = 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 = htons(ETH_P_IP);	if (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){       u8 servers;       int i;#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 == NONE)				memcpy(&ic_netmask, ext+1, 4);			break;		case 3:		/* Default gateway */			if (ic_gateway == NONE)				memcpy(&ic_gateway, ext+1, 4);			break;		case 6:		/* DNS server */			servers= *ext/4;			if (servers > CONF_NAMESERVERS_MAX)				servers = CONF_NAMESERVERS_MAX;			for (i = 0; i < servers; i++) {				if (ic_nameservers[i] == NONE)					memcpy(&ic_nameservers[i], ext+1+4*i, 4);			}			break;		case 12:	/* Host name */			ic_bootp_string(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(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 net_device *orig_dev){	struct bootp_pkt *b;	struct iphdr *h;	struct ic_device *d;	int len, ext_len;	if (dev->nd_net != &init_net)		goto drop;	/* Perform verifications before taking the lock.  */	if (skb->pkt_type == PACKET_OTHERHOST)		goto drop;	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)		return NET_RX_DROP;	if (!pskb_may_pull(skb,			   sizeof(struct iphdr) +			   sizeof(struct udphdr)))		goto drop;	b = (struct bootp_pkt *)skb_network_header(skb);	h = &b->iph;	if (h->ihl != 5 || h->version != 4 || h->protocol != IPPROTO_UDP)		goto drop;	/* Fragments are not supported */	if (h->frag_off & htons(IP_OFFSET | IP_MF)) {		if (net_ratelimit())			printk(KERN_ERR "DHCP/BOOTP: Ignoring fragmented "			       "reply.\n");		goto drop;	}	if (skb->len < ntohs(h->tot_len))		goto drop;	if (ip_fast_csum((char *) h, h->ihl))		goto drop;	if (b->udph.source != htons(67) || b->udph.dest != htons(68))		goto drop;	if (ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))		goto drop;	len = ntohs(b->udph.len) - sizeof(struct udphdr);	ext_len = len - (sizeof(*b) -			 sizeof(struct iphdr) -			 sizeof(struct udphdr) -			 sizeof(b->exten));	if (ext_len < 0)		goto drop;	/* Ok the front looks good, make sure we can get at the rest.  */	if (!pskb_may_pull(skb, skb->len))		goto drop;	b = (struct bootp_pkt *)skb_network_header(skb);	h = &b->iph;	/* 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_unlock;	/* 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_unlock;  /* should never happen */	/* Is it a reply to our BOOTP request? */	if (b->op != BOOTP_REPLY ||	    b->xid != d->xid) {		if (net_ratelimit())			printk(KERN_ERR "DHCP/BOOTP: Reply not for us, "			       "op[%x] xid[%x]\n",			       b->op, b->xid);		goto drop_unlock;	}	/* Parse extensions */	if (ext_len >= 4 &&	    !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) {			__be32 server_id = 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 != NONE)					goto drop_unlock;				/* 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 != NONE) &&				    (b->server_ip != server_id))					b->server_ip = ic_servaddr;				break;			case DHCPACK:				if (memcmp(dev->dev_addr, b->hw_addr, dev->addr_len) != 0)					goto drop_unlock;				/* Yeah! */				break;			default:				/* Urque.  Forget it*/				ic_myaddr = NONE;				ic_servaddr = NONE;				goto drop_unlock;			}			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);

⌨️ 快捷键说明

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