📄 ipconfig.c
字号:
} } /* We have a winner! */ ic_dev = dev; ic_myaddr = b->your_ip; ic_servaddr = b->server_ip; if (ic_gateway == NONE && b->relay_ip) ic_gateway = b->relay_ip; if (ic_nameservers[0] == NONE) ic_nameservers[0] = ic_servaddr; ic_got_reply = IC_BOOTP;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) schedule_timeout_uninterruptible(1);#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) { ic_myaddr = NONE; 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] != NONE) seq_printf(seq, "nameserver %u.%u.%u.%u\n", NIPQUAD(ic_nameservers[i])); } if (ic_servaddr != 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 const 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. */__be32 __init root_nfs_parse_addr(char *name){ __be32 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); memmove(name, cp, strlen(cp) + 1); } else addr = NONE; return addr;}/* * IP Autoconfig dispatcher. */static int __init ip_auto_config(void){ __be32 addr;#ifdef CONFIG_PROC_FS proc_net_fops_create(&init_net, "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 */ msleep(CONF_PRE_OPEN); /* Setup all network devices */ if (ic_open_devs() < 0) return -1; /* Give drivers a chance to settle */ ssleep(CONF_POST_OPEN); /* * 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 == NONE ||#ifdef CONFIG_ROOT_NFS (root_server_addr == NONE && ic_servaddr == NONE && ROOT_DEV == Root_NFS) ||#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 == 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", utsname()->nodename, ic_domain, 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. See Documentation/nfsroot.txt. */static int __init ic_proto_name(char *name){ if (!strcmp(name, "on") || !strcmp(name, "any")) { return 1; } if (!strcmp(name, "off") || !strcmp(name, "none")) { return 0; }#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 = 1; /* * If any dhcp, bootp etc options are set, leave autoconfig on * and skip the below static IP processing. */ if (ic_proto_name(addrs)) return 1; /* If no static IP is given, turn off autoconfig and bail. */ if (*addrs == 0 || strcmp(addrs, "off") == 0 || strcmp(addrs, "none") == 0) { ic_enable = 0; return 1; } /* Parse string for static IP assignment. */ 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 = NONE; break; case 1: if ((ic_servaddr = in_aton(ip)) == INADDR_ANY) ic_servaddr = NONE; break; case 2: if ((ic_gateway = in_aton(ip)) == INADDR_ANY) ic_gateway = NONE; break; case 3: if ((ic_netmask = in_aton(ip)) == INADDR_ANY) ic_netmask = NONE; break; case 4: if ((dp = strchr(ip, '.'))) { *dp++ = '\0'; strlcpy(utsname()->domainname, dp, sizeof(utsname()->domainname)); } strlcpy(utsname()->nodename, ip, sizeof(utsname()->nodename)); ic_host_name_set = 1; break; case 5: strlcpy(user_dev_name, ip, sizeof(user_dev_name)); break; case 6: if (ic_proto_name(ip) == 0 && ic_myaddr == NONE) { ic_enable = 0; } 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 + -