📄 ipconfig.c
字号:
drop_unlock: /* Show's over. Nothing to see here. */ spin_unlock(&ic_recv_lock);drop: /* Throw the packet out. */ kfree_skb(skb); return 0;} #endif/* * Dynamic IP configuration -- DHCP, BOOTP, RARP. */#ifdef IPCONFIG_DYNAMICstatic int __init ic_dynamic(void){ int retries; struct ic_device *d; unsigned long start_jiffies, timeout, jiff; int do_bootp = ic_proto_have_if & IC_BOOTP; int do_rarp = ic_proto_have_if & IC_RARP; /* * If none of DHCP/BOOTP/RARP was selected, return with an error. * This routine gets only called when some pieces of information * are missing, and without DHCP/BOOTP/RARP we are unable to get it. */ if (!ic_proto_enabled) { printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n"); return -1; }#ifdef IPCONFIG_BOOTP if ((ic_proto_enabled ^ ic_proto_have_if) & IC_BOOTP) printk(KERN_ERR "DHCP/BOOTP: No suitable device found.\n");#endif#ifdef IPCONFIG_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 protocols */#ifdef IPCONFIG_BOOTP if (do_bootp) ic_bootp_init();#endif#ifdef IPCONFIG_RARP if (do_rarp) ic_rarp_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 ? ((ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP") : "", (do_bootp && do_rarp) ? " and " : "", do_rarp ? "RARP" : ""); start_jiffies = jiffies; d = ic_first_dev; retries = CONF_SEND_RETRIES; get_random_bytes(&timeout, sizeof(timeout)); timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM); for(;;) {#ifdef IPCONFIG_BOOTP if (do_bootp && (d->able & IC_BOOTP)) ic_bootp_send_if(d, jiffies - start_jiffies);#endif#ifdef IPCONFIG_RARP if (do_rarp && (d->able & IC_RARP)) ic_rarp_send_if(d);#endif jiff = jiffies + (d->next ? CONF_INTER_TIMEOUT : timeout); while (time_before(jiffies, jiff) && !ic_got_reply) { barrier(); cpu_relax(); }#ifdef IPCONFIG_DHCP /* DHCP isn't done until we get a DHCPACK. */ if ((ic_got_reply & IC_BOOTP) && (ic_proto_enabled & IC_USE_DHCP) && ic_dhcp_msgtype != DHCPACK) { ic_got_reply = 0; printk(","); continue; }#endif /* IPCONFIG_DHCP */ if (ic_got_reply) { printk(" OK\n"); break; } if ((d = d->next)) continue; if (! --retries) { printk(" timed out!\n"); break; } d = ic_first_dev; timeout = timeout CONF_TIMEOUT_MULT; if (timeout > CONF_TIMEOUT_MAX) timeout = CONF_TIMEOUT_MAX; printk("."); }#ifdef IPCONFIG_BOOTP if (do_bootp) ic_bootp_cleanup();#endif#ifdef IPCONFIG_RARP if (do_rarp) ic_rarp_cleanup();#endif if (!ic_got_reply) return -1; printk("IP-Config: Got %s answer from %u.%u.%u.%u, ", ((ic_got_reply & IC_RARP) ? "RARP" : (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"), NIPQUAD(ic_servaddr)); printk("my address is %u.%u.%u.%u\n", NIPQUAD(ic_myaddr)); return 0;}#endif /* IPCONFIG_DYNAMIC */#ifdef CONFIG_PROC_FSstatic int pnp_seq_show(struct seq_file *seq, void *v){ int i; if (ic_proto_used & IC_PROTO) seq_printf(seq, "#PROTO: %s\n", (ic_proto_used & IC_RARP) ? "RARP" : (ic_proto_used & IC_USE_DHCP) ? "DHCP" : "BOOTP"); else seq_puts(seq, "#MANUAL\n"); if (ic_domain[0]) seq_printf(seq, "domain %s\n", ic_domain); for (i = 0; i < CONF_NAMESERVERS_MAX; i++) { if (ic_nameservers[i] != INADDR_NONE) seq_printf(seq, "nameserver %u.%u.%u.%u\n", NIPQUAD(ic_nameservers[i])); } if (ic_servaddr != INADDR_NONE) seq_printf(seq, "bootserver %u.%u.%u.%u\n", NIPQUAD(ic_servaddr)); return 0;}static int pnp_seq_open(struct inode *indoe, struct file *file){ return single_open(file, pnp_seq_show, NULL);}static struct file_operations pnp_seq_fops = { .owner = THIS_MODULE, .open = pnp_seq_open, .read = seq_read, .llseek = seq_lseek, .release = single_release,};#endif /* CONFIG_PROC_FS *//* * Extract IP address from the parameter string if needed. Note that we * need to have root_server_addr set _before_ IPConfig gets called as it * can override it. */u32 __init root_nfs_parse_addr(char *name){ u32 addr; int octets = 0; char *cp, *cq; cp = cq = name; while (octets < 4) { while (*cp >= '0' && *cp <= '9') cp++; if (cp == cq || cp - cq > 3) break; if (*cp == '.' || octets == 3) octets++; if (octets < 4) cp++; cq = cp; } if (octets == 4 && (*cp == ':' || *cp == '\0')) { if (*cp == ':') *cp++ = '\0'; addr = in_aton(name); strcpy(name, cp); } else addr = INADDR_NONE; return addr;}/* * IP Autoconfig dispatcher. */static int __init ip_auto_config(void){ unsigned long jiff; u32 addr;#ifdef CONFIG_PROC_FS proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops);#endif /* CONFIG_PROC_FS */ if (!ic_enable) return 0; DBG(("IP-Config: Entered.\n"));#ifdef IPCONFIG_DYNAMIC try_try_again:#endif /* Give hardware a chance to settle */ jiff = jiffies + CONF_PRE_OPEN; while (time_before(jiffies, jiff)) cpu_relax(); /* Setup all network devices */ if (ic_open_devs() < 0) return -1; /* Give drivers a chance to settle */ jiff = jiffies + CONF_POST_OPEN; while (time_before(jiffies, jiff)) cpu_relax(); /* * 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 (MAJOR(ROOT_DEV) == UNNAMED_MAJOR && root_server_addr == INADDR_NONE && ic_servaddr == INADDR_NONE) ||#endif ic_first_dev->next) {#ifdef IPCONFIG_DYNAMIC int retries = CONF_OPEN_RETRIES; if (ic_dynamic() < 0) { ic_close_devs(); /* * I don't know why, but sometimes the * eepro100 driver (at least) gets upset and * doesn't work the first time it's opened. * But then if you close it and reopen it, it * works just fine. So we need to try that at * least once before giving up. * * Also, if the root will be NFS-mounted, we * have nowhere to go if DHCP fails. So we * just have to keep trying forever. * * -- Chip */#ifdef CONFIG_ROOT_NFS if (ROOT_DEV == Root_NFS) { printk(KERN_ERR "IP-Config: Retrying forever (NFS root)...\n"); goto try_try_again; }#endif if (--retries) { printk(KERN_ERR "IP-Config: Reopening network devices...\n"); goto try_try_again; } /* Oh, well. At least we tried. */ printk(KERN_ERR "IP-Config: Auto-configuration of network failed.\n"); return -1; }#else /* !DYNAMIC */ printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n"); ic_close_devs(); return -1;#endif /* IPCONFIG_DYNAMIC */ } else { /* Device selected manually or only one device -> use it */ ic_dev = ic_first_dev->dev; } addr = root_nfs_parse_addr(root_server_path); if (root_server_addr == INADDR_NONE) root_server_addr = addr; /* * 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; /* * Record which protocol was actually used. */#ifdef IPCONFIG_DYNAMIC ic_proto_used = ic_got_reply | (ic_proto_enabled & IC_USE_DHCP);#endif#ifndef IPCONFIG_SILENT /* * Clue in the operator. */ printk("IP-Config: Complete:"); printk("\n device=%s", ic_dev->name); printk(", addr=%u.%u.%u.%u", NIPQUAD(ic_myaddr)); printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask)); printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway)); printk(",\n host=%s, domain=%s, nis-domain=%s", system_utsname.nodename, ic_domain, system_utsname.domainname); printk(",\n bootserver=%u.%u.%u.%u", NIPQUAD(ic_servaddr)); printk(", rootserver=%u.%u.%u.%u", NIPQUAD(root_server_addr)); printk(", rootpath=%s", root_server_path); printk("\n");#endif /* !SILENT */ return 0;}late_initcall(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>:<PROTO> * * 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 * <PROTO>: * off|none - don't do autoconfig at all (DEFAULT) * on|any - use any configured protocol * dhcp|bootp|rarp - use only the specified protocol * both - use both BOOTP and RARP (not DHCP) */static int __init ic_proto_name(char *name){ if (!strcmp(name, "on") || !strcmp(name, "any")) { return 1; }#ifdef CONFIG_IP_PNP_DHCP else if (!strcmp(name, "dhcp")) { ic_proto_enabled &= ~IC_RARP; return 1; }#endif#ifdef CONFIG_IP_PNP_BOOTP else if (!strcmp(name, "bootp")) { ic_proto_enabled &= ~(IC_RARP | IC_USE_DHCP); return 1; }#endif#ifdef CONFIG_IP_PNP_RARP else if (!strcmp(name, "rarp")) { ic_proto_enabled &= ~(IC_BOOTP | IC_USE_DHCP); return 1; }#endif#ifdef IPCONFIG_DYNAMIC else if (!strcmp(name, "both")) { ic_proto_enabled &= ~IC_USE_DHCP; /* backward compat :-( */ 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; ic_enable = (*addrs && (strcmp(addrs, "off") != 0) && (strcmp(addrs, "none") != 0)); if (!ic_enable) 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'; strlcpy(system_utsname.domainname, dp, sizeof(system_utsname.domainname)); } strlcpy(system_utsname.nodename, ip, sizeof(system_utsname.nodename)); ic_host_name_set = 1; break; case 5: strlcpy(user_dev_name, ip, sizeof(user_dev_name)); 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 + -