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

📄 ipconfig.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 *  Send BOOTP request to single interface. */static void __init ic_bootp_send_if(struct ic_device *d, u32 jiffies){	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 = 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 = 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 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;	memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);	b->secs = htons(jiffies / HZ);	b->xid = ic_bootp_xid;	ic_bootp_init_ext(b->vendor_area);	/* 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");}/* *  Send BOOTP requests to all interfaces. */static void __init ic_bootp_send(u32 jiffies){	struct ic_device *d;	for(d=ic_first_dev; d; d=d->next)		if (d->able & IC_BOOTP)			ic_bootp_send_if(d, jiffies);}/* *  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;	strncpy(dest, src, len);	dest[len] = '\0';	return 1;}/* *  Process BOOTP extension. */static void __init ic_do_bootp_ext(u8 *ext){#ifdef IPCONFIG_DEBUG	u8 *c;	printk("BOOTP: Got extension %02x",*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 12:	/* Host name */			ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);			ic_host_name_set = 1;			break;		case 40:	/* NIS Domain name */			ic_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);			break;		case 17:	/* Root path */			if (!root_server_path[0])				ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path));			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;	int len;	/* If we already have a reply, just drop the packet */	if (ic_got_reply)		goto drop;	/* 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 != htons(67) ||	    b->udph.dest != htons(68) ||	    ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))		goto drop;	/* Fragments are not supported */	if (h->frag_off & htons(IP_OFFSET|IP_MF)) {		printk(KERN_ERR "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 != ic_bootp_xid) {		printk("?");		goto drop;	}	/* Extract basic fields */	ic_myaddr = b->your_ip;	ic_servaddr = b->server_ip;	ic_got_reply = IC_BOOTP;	ic_dev = dev;	/* Parse extensions */	if (b->vendor_area[0] == 99 &&	/* Check magic cookie */	    b->vendor_area[1] == 130 &&	    b->vendor_area[2] == 83 &&	    b->vendor_area[3] == 99) {		u8 *ext = &b->vendor_area[4];                u8 *end = (u8 *) b + ntohs(b->iph.tot_len);		while (ext < end && *ext != 0xff) {			if (*ext == 0)		/* Padding */				ext++;			else {				u8 *opt = ext;				ext += ext[1] + 2;				if (ext <= end)					ic_do_bootp_ext(opt);			}		}	}	if (ic_gateway == INADDR_NONE && b->relay_ip)		ic_gateway = b->relay_ip;drop:	kfree_skb(skb);	return 0;}	#endif/* *	Dynamic IP configuration -- BOOTP and RARP. */#ifdef CONFIG_IP_PNP_DYNAMICstatic int __init ic_dynamic(void){	int retries;	unsigned long timeout, jiff;	unsigned long start_jiffies;	int do_rarp = ic_proto_have_if & IC_RARP;	int do_bootp = ic_proto_have_if & IC_BOOTP;	/*	 * If neither BOOTP nor RARP was selected, return with an error. This	 * routine gets only called when some pieces of information are mis-	 * sing, and without BOOTP and RARP we are not able to get that in-	 * formation.	 */	if (!ic_proto_enabled) {		printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n");		return -1;	}#ifdef CONFIG_IP_PNP_BOOTP	if ((ic_proto_enabled ^ ic_proto_have_if) & IC_BOOTP)		printk(KERN_ERR "BOOTP: No suitable device found.\n");#endif#ifdef CONFIG_IP_PNP_RARP	if ((ic_proto_enabled ^ ic_proto_have_if) & IC_RARP)		printk(KERN_ERR "RARP: No suitable device found.\n");#endif	if (!ic_proto_have_if)		/* Error message already printed */		return -1;	/*	 * Setup RARP and BOOTP protocols	 */#ifdef CONFIG_IP_PNP_RARP	if (do_rarp)		ic_rarp_init();#endif#ifdef CONFIG_IP_PNP_BOOTP	if (do_bootp)		ic_bootp_init();#endif	/*	 * Send requests and wait, until we get an answer. This loop	 * seems to be a terrible waste of CPU time, but actually there is	 * only one process running at all, so we don't need to use any	 * scheduler functions.	 * [Actually we could now, but the nothing else running note still 	 *  applies.. - AC]	 */	printk(KERN_NOTICE "Sending %s%s%s requests...",	        do_bootp ? "BOOTP" : "",		do_bootp && do_rarp ? " and " : "",		do_rarp ? "RARP" : "");	start_jiffies = jiffies;	retries = CONF_RETRIES;	get_random_bytes(&timeout, sizeof(timeout));	timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);	for(;;) {#ifdef CONFIG_IP_PNP_BOOTP		if (do_bootp)			ic_bootp_send(jiffies - start_jiffies);#endif#ifdef CONFIG_IP_PNP_RARP		if (do_rarp)			ic_rarp_send();#endif		printk(".");		jiff = jiffies + timeout;		while (jiffies < jiff && !ic_got_reply)			barrier();		if (ic_got_reply) {			printk(" OK\n");			break;		}		if (! --retries) {			printk(" timed out!\n");			break;		}		timeout = timeout CONF_TIMEOUT_MULT;		if (timeout > CONF_TIMEOUT_MAX)			timeout = CONF_TIMEOUT_MAX;	}#ifdef CONFIG_IP_PNP_RARP	if (do_rarp)		ic_rarp_cleanup();#endif#ifdef CONFIG_IP_PNP_BOOTP	if (do_bootp)		ic_bootp_cleanup();#endif	if (!ic_got_reply)		return -1;	printk("IP-Config: Got %s answer from %u.%u.%u.%u, ",		(ic_got_reply & IC_BOOTP) ? "BOOTP" : "RARP",		NIPQUAD(ic_servaddr));	printk("my address is %u.%u.%u.%u\n", NIPQUAD(ic_myaddr));	return 0;}#endif/* *	IP Autoconfig dispatcher. */static int __init ip_auto_config(void){	if (!ic_enable)		return 0;	DBG(("IP-Config: Entered.\n"));	/* Setup all network devices */	if (ic_open_devs() < 0)		return -1;	/*	 * If the config information is insufficient (e.g., our IP address or	 * IP address of the boot server is missing or we have multiple network	 * interfaces and no default was set), use BOOTP or RARP to get the	 * missing values.	 */	if (ic_myaddr == INADDR_NONE ||#ifdef CONFIG_ROOT_NFS	    (root_server_addr == INADDR_NONE && ic_servaddr == INADDR_NONE) ||#endif	    ic_first_dev->next) {#ifdef CONFIG_IP_PNP_DYNAMIC		if (ic_dynamic() < 0) {			printk(KERN_ERR "IP-Config: Auto-configuration of network failed.\n");			ic_close_devs();			return -1;		}#else		printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n");		ic_close_devs();		return -1;#endif	} else {		ic_dev = ic_first_dev->dev;	/* Device selected manually or only one device -> use it */	}	/*	 * Use defaults whereever applicable.	 */	if (ic_defaults() < 0)		return -1;	/*	 * Close all network devices except the device we've	 * autoconfigured and set up routes.	 */	ic_close_devs();	if (ic_setup_if() < 0 || ic_setup_routes() < 0)		return -1;	DBG(("IP-Config: device=%s, local=%08x, server=%08x, boot=%08x, gw=%08x, mask=%08x\n",	    ic_dev->name, ic_myaddr, ic_servaddr, root_server_addr, ic_gateway, ic_netmask));	DBG(("IP-Config: host=%s, domain=%s, path=`%s'\n", system_utsname.nodename,	    system_utsname.domainname, root_server_path));	return 0;}module_init(ip_auto_config);/* *  Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel *  command line parameter. It consists of option fields separated by colons in *  the following order: * *  <client-ip>:<server-ip>:<gw-ip>:<netmask>:<host name>:<device>:<bootp|rarp> * *  Any of the fields can be empty which means to use a default value: *	<client-ip>	- address given by BOOTP or RARP *	<server-ip>	- address of host returning BOOTP or RARP packet *	<gw-ip>		- none, or the address returned by BOOTP *	<netmask>	- automatically determined from <client-ip>, or the *			  one returned by BOOTP *	<host name>	- <client-ip> in ASCII notation, or the name returned *			  by BOOTP *	<device>	- use all available devices *	<bootp|rarp|both|off> - use both protocols to determine my own address */static int __init ic_proto_name(char *name){	if (!strcmp(name, "off")) {		ic_proto_enabled = 0;		return 1;	}#ifdef CONFIG_IP_PNP_BOOTP	else if (!strcmp(name, "bootp")) {		ic_proto_enabled &= ~IC_RARP;		return 1;	}#endif#ifdef CONFIG_IP_PNP_RARP	else if (!strcmp(name, "rarp")) {		ic_proto_enabled &= ~IC_BOOTP;		return 1;	}#endif#ifdef CONFIG_IP_PNP_DYNAMIC	else if (!strcmp(name, "both")) {		return 1;	}#endif	return 0;}static int __init ip_auto_config_setup(char *addrs){	char *cp, *ip, *dp;	int num = 0;	ic_set_manually = 1;	if (!strcmp(addrs, "off")) {		ic_enable = 0;		return 1;	}	if (ic_proto_name(addrs))		return 1;	/* Parse the whole string */	ip = addrs;	while (ip && *ip) {		if ((cp = strchr(ip, ':')))			*cp++ = '\0';		if (strlen(ip) > 0) {			DBG(("IP-Config: Parameter #%d: `%s'\n", num, ip));			switch (num) {			case 0:				if ((ic_myaddr = in_aton(ip)) == INADDR_ANY)					ic_myaddr = INADDR_NONE;				break;			case 1:				if ((ic_servaddr = in_aton(ip)) == INADDR_ANY)					ic_servaddr = INADDR_NONE;				break;			case 2:				if ((ic_gateway = in_aton(ip)) == INADDR_ANY)					ic_gateway = INADDR_NONE;				break;			case 3:				if ((ic_netmask = in_aton(ip)) == INADDR_ANY)					ic_netmask = INADDR_NONE;				break;			case 4:				if ((dp = strchr(ip, '.'))) {					*dp++ = '\0';					strncpy(system_utsname.domainname, dp, __NEW_UTS_LEN);					system_utsname.domainname[__NEW_UTS_LEN] = '\0';				}				strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN);				system_utsname.nodename[__NEW_UTS_LEN] = '\0';				ic_host_name_set = 1;				break;			case 5:				strncpy(user_dev_name, ip, IFNAMSIZ);				user_dev_name[IFNAMSIZ-1] = '\0';				break;			case 6:				ic_proto_name(ip);				break;			}		}		ip = cp;		num++;	}	return 1;}static int __init nfsaddrs_config_setup(char *addrs){	return ip_auto_config_setup(addrs);}__setup("ip=", ip_auto_config_setup);__setup("nfsaddrs=", nfsaddrs_config_setup);

⌨️ 快捷键说明

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