📄 net.c
字号:
/* * Copyright 1999-2006 Red Hat, Inc. * * David Cantrell <dcantrell@redhat.com> * * All Rights Reserved. * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of Red Hat shall not be * used in advertising or otherwise to promote the sale, use or other dealings * in this Software without prior written authorization from Red Hat. * */#include <sys/types.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/utsname.h>#include <arpa/inet.h>#include <errno.h>#include <popt.h>#include <resolv.h>#include <net/if.h>#include <newt.h>#include <stdlib.h>#include <string.h>#include <strings.h>#include <unistd.h>#include <kudzu/kudzu.h>#include "../isys/dns.h"#include "../isys/isys.h"#include "../isys/net.h"#include "../isys/wireless.h"#include "../isys/nl.h"#include "../isys/str.h"#include "lang.h"#include "loader.h"#include "loadermisc.h"#include "log.h"#include "method.h"#include "net.h"#include "windows.h"/* boot flags */extern int flags;char *netServerPrompt = \ N_("Please enter the following information:\n" "\n" " o the name or IP number of your %s server\n" " o the directory on that server containing\n" " %s for your architecture\n");/** * Callback function for the CIDR entry boxes on the manual TCP/IP * configuration window. * * @param co The entry field that triggered the callback. * @param dptr Pointer to intfconfig_s data structure for this field. * @see intfconfig_s */static void cidrCallback(newtComponent co, void * dptr) { struct intfconfig_s * data = dptr; int cidr, upper = 0; if (co == data->cidr4Entry) { if (data->cidr4 == NULL && data->ipv4 == NULL) return; cidr = atoi(data->cidr4); if (strcmp(data->ipv4, "")) upper = 32; } else if (co == data->cidr6Entry) { if (data->cidr6 == NULL && data->ipv6 == NULL) return; cidr = atoi(data->cidr6); if (strcmp(data->ipv6, "")) upper = 128; } if (upper != 0) { if (cidr < 1 || cidr > upper) { newtWinMessage(_("Invalid Prefix"), _("Retry"), _("Prefix must be between 1 and 32 " "for IPv4 networks or between 1 and 128 " "for IPv6 networks")); } }}static void ipCallback(newtComponent co, void * dptr) { int i; char *buf, *octet; struct intfconfig_s * data = dptr; if (co == data->ipv4Entry) { /* do we need to guess a netmask for the user? */ if (data->cidr4 == NULL && data->ipv4 != NULL) { buf = strdup(data->ipv4); octet = strtok(buf, "."); i = atoi(octet); free(buf); free(octet); if (i >= 0 && i <= 127) newtEntrySet(data->cidr4Entry, "8", 1); else if (i >= 128 && i <= 191) newtEntrySet(data->cidr4Entry, "16", 1); else if (i >= 192 && i <= 222) newtEntrySet(data->cidr4Entry, "24", 1); } return; } else if (co == data->ipv6Entry) { /* users must provide a mask, we can't guess for ipv6 */ return; }}static void setMethodSensitivity(void *dptr, int radio_button_count) { int i = 0; for (i = 0; i < radio_button_count; i++) { newtCheckboxSetFlags(*((newtComponent *) dptr), NEWT_FLAG_DISABLED, NEWT_FLAGS_TOGGLE); dptr += sizeof (newtComponent); } return;}static void v4MethodCallback(newtComponent co, void *dptr) { setMethodSensitivity(dptr, 2); return;}static void v6MethodCallback(newtComponent co, void *dptr) { setMethodSensitivity(dptr, 3); return;}static int waitForLink(char * dev) { extern int num_link_checks; int tries = 0; /* try to wait for a valid link -- if the status is unknown or * up continue, else sleep for 1 second and try again for up * to five times */ logMessage(DEBUGLVL, "waiting for link %s...", dev); while (tries < num_link_checks) { if (get_link_status(dev) != 0) break; sleep(1); tries++; } logMessage(DEBUGLVL, " %d seconds.", tries); if (tries < num_link_checks) return 0; logMessage(WARNING, " no network link detected on %s", dev); return 1;}static void parseEthtoolSettings(struct loaderData_s * loaderData) { char * option, * buf; ethtool_duplex duplex = ETHTOOL_DUPLEX_UNSPEC; ethtool_speed speed = ETHTOOL_SPEED_UNSPEC; buf = strdup(loaderData->ethtool); option = strtok(buf, " "); while (option) { if (option[strlen(option) - 1] == '\"') option[strlen(option) - 1] = '\0'; if (option[0] == '\"') option++; if (!strncmp(option, "duplex", 6)) { if (!strncmp(option + 7, "full", 4)) duplex = ETHTOOL_DUPLEX_FULL; else if (!strncmp(option + 7, "half", 4)) duplex = ETHTOOL_DUPLEX_HALF; else logMessage(WARNING, "Unknown duplex setting: %s", option + 7); option = strtok(NULL, " "); } else if (!strncmp("speed", option, 5)) { if (!strncmp(option + 6, "1000", 4)) speed = ETHTOOL_SPEED_1000; else if (!strncmp(option + 6, "100", 3)) speed = ETHTOOL_SPEED_100; else if (!strncmp(option + 6, "10", 2)) speed = ETHTOOL_SPEED_10; else logMessage(WARNING, "Unknown speed setting: %s", option + 6); option = strtok(NULL, " "); } else { logMessage(WARNING, "Unknown ethtool setting: %s", option); } option = strtok(NULL, " "); } setEthtoolSettings(loaderData->netDev, speed, duplex); free(buf);}void initLoopback(void) { struct ifreq req; int s; s = socket(AF_INET, SOCK_DGRAM, 0); memset(&req, 0, sizeof(req)); strcpy(req.ifr_name, "lo"); if (ioctl(s, SIOCGIFFLAGS, &req)) { logMessage(LOG_ERR, "ioctl SIOCGIFFLAGS failed: %d %s\n", errno, strerror(errno)); close(s); return; } req.ifr_flags |= (IFF_UP | IFF_RUNNING); if (ioctl(s, SIOCSIFFLAGS, &req)) { logMessage(LOG_ERR, "ioctl SIOCSIFFLAGS failed: %d %s\n", errno, strerror(errno)); close(s); return; } close(s); return;}static int getWirelessConfig(struct networkDeviceConfig *cfg, char * ifname) { char * wepkey = ""; char * essid = ""; int rc = 0; char * buf; if (cfg->wepkey != NULL) { wepkey = strdup(cfg->wepkey); } if (cfg->essid != NULL) { essid = strdup(cfg->essid); } else { essid = get_essid(ifname); } buf = sdupprintf(_("%s is a wireless network adapter. Please " "provide the ESSID and encryption key needed " "to access your wireless network. If no key " "is needed, leave this field blank and the " "install will continue."), ifname); do { struct newtWinEntry entry[] = { { N_("ESSID"), (const char **)&essid, 0 }, { N_("Encryption Key"), (const char **) &wepkey, 0 }, { NULL, NULL, 0 } }; rc = newtWinEntries(_("Wireless Settings"), buf, 40, 5, 10, 30, entry, _("OK"), _("Back"), NULL); if (rc == 2) return LOADER_BACK; /* set stuff up */ } while (rc == 2); if (cfg->wepkey != NULL) free(cfg->wepkey); if (wepkey && (strlen(wepkey) > 0)) cfg->wepkey = strdup(wepkey); else cfg->wepkey = NULL; if (cfg->essid != NULL) free(cfg->essid); if (essid && (strlen(essid) > 0)) cfg->essid = strdup(essid); else cfg->essid = NULL; return LOADER_OK;}static int getDnsServers(struct networkDeviceConfig * cfg) { int rc; struct in_addr addr; struct in6_addr addr6; const char * ns = ""; struct newtWinEntry entry[] = { { N_("Nameserver IP"), &ns, 0 }, { NULL, NULL, 0 } }; do { rc = newtWinEntries(_("Missing Nameserver"), _("Your IP address request returned configuration " "information, but it did not include a nameserver address. " "If you do not have this information, you can leave " "the field blank and the install will continue."), 61, 0, 0, 45, entry, _("OK"), _("Back"), NULL); if (rc == 2) return LOADER_BACK; rc = 0; if (!ns || !*ns) { cfg->dev.numDns = 0; break; } else { if (inet_pton(AF_INET, ns, &addr) >= 1) cfg->dev.dnsServers[0] = ip_addr_in(&addr); else if (inet_pton(AF_INET6, ns, &addr6) >= 1) cfg->dev.dnsServers[0] = ip_addr_in6(&addr6); else rc = 2; } if (rc) { newtWinMessage(_("Invalid IP Information"), _("Retry"), _("You entered an invalid IP address.")); } else { cfg->dev.set |= PUMP_NETINFO_HAS_DNS; cfg->dev.numDns = 1; } } while (rc == 2); return LOADER_OK;}void printLoaderDataIPINFO(struct loaderData_s *loaderData) { logMessage(DEBUGLVL, "loaderData->ipinfo_set = |%d|", loaderData->ipinfo_set); logMessage(DEBUGLVL, "loaderData->ipv4 = |%s|", loaderData->ipv4); logMessage(DEBUGLVL, "loaderData->ipv6info_set = |%d|", loaderData->ipv6info_set); logMessage(DEBUGLVL, "loaderData->ipv6 = |%s|", loaderData->ipv6); logMessage(DEBUGLVL, "loaderData->netmask = |%s|", loaderData->netmask); logMessage(DEBUGLVL, "loaderData->gateway = |%s|", loaderData->gateway); logMessage(DEBUGLVL, "loaderData->dns = |%s|", loaderData->dns); logMessage(DEBUGLVL, "loaderData->hostname = |%s|", loaderData->hostname); logMessage(DEBUGLVL, "loaderData->noDns = |%d|", loaderData->noDns); logMessage(DEBUGLVL, "loaderData->netDev_set = |%d|", loaderData->netDev_set); logMessage(DEBUGLVL, "loaderData->netDev = |%s|", loaderData->netDev); logMessage(DEBUGLVL, "loaderData->netCls_set = |%d|", loaderData->netCls_set); logMessage(DEBUGLVL, "loaderData->netCls = |%s|", loaderData->netCls);}/* given loader data from kickstart, populate network configuration struct */void setupNetworkDeviceConfig(struct networkDeviceConfig * cfg, struct loaderData_s * loaderData) { struct in_addr addr; struct in6_addr addr6; char * c; /* set to 1 to get ks network struct logged */#if 0 printLoaderDataIPINFO(loaderData);#endif cfg->noipv4 = 0; if (FL_NOIPV6(flags)) { cfg->noipv6 = 1; } else { cfg->noipv6 = 0; } if (loaderData->ethtool) { parseEthtoolSettings(loaderData); } if (loaderData->netCls_set) { cfg->vendor_class = loaderData->netCls; } else { cfg->vendor_class = NULL; } if (loaderData->ipinfo_set) { if (is_wireless_interface(loaderData->netDev)) { if (loaderData->essid) { logMessage(INFO, "setting specified essid of %s",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -