📄 main.c
字号:
bail: packet_close(); return 0;}static int add_one_dev(struct netdev *dev){ struct state *state; state = malloc(sizeof(struct state)); if (!state) return -1; state->dev = dev; state->expire = time(NULL); state->retry_period = 1; /* * Select the state that we start from. */ if (dev->caps & CAP_DHCP && dev->ip_addr == INADDR_ANY) { state->restart_state = state->state = DEVST_DHCPDISC; } else if (dev->caps & CAP_DHCP) { state->restart_state = state->state = DEVST_DHCPREQ; } else if (dev->caps & CAP_BOOTP) { state->restart_state = state->state = DEVST_BOOTP; } state->next = slist; slist = state; return 0;}static void parse_addr(uint32_t * addr, const char *ip){ struct in_addr in; if (inet_aton(ip, &in) == 0) { fprintf(stderr, "%s: can't parse IP address '%s'\n", progname, ip); longjmp(abort_buf, 1); } *addr = in.s_addr;}static unsigned int parse_proto(const char *ip){ unsigned int caps = 0; if (*ip == '\0' || strcmp(ip, "on") == 0 || strcmp(ip, "any") == 0) caps = CAP_BOOTP | CAP_DHCP | CAP_RARP; else if (strcmp(ip, "both") == 0) caps = CAP_BOOTP | CAP_RARP; else if (strcmp(ip, "dhcp") == 0) caps = CAP_BOOTP | CAP_DHCP; else if (strcmp(ip, "bootp") == 0) caps = CAP_BOOTP; else if (strcmp(ip, "rarp") == 0) caps = CAP_RARP; else if (strcmp(ip, "none") == 0 || strcmp(ip, "static") == 0 || strcmp(ip, "off") == 0) goto bail; else { fprintf(stderr, "%s: invalid protocol '%s'\n", progname, ip); longjmp(abort_buf, 1); } bail: return caps;}static int add_all_devices(struct netdev *template);static int parse_device(struct netdev *dev, const char *ip){ char *cp; int i, opt; int is_ip = 0; DEBUG(("IP-Config: parse_device: \"%s\"\n", ip)); if (strncmp(ip, "ip=", 3) == 0) { ip += 3; is_ip = 1; } else if (strncmp(ip, "nfsaddrs=", 9) == 0) { ip += 9; is_ip = 1; /* Not sure about this...? */ } if (!strchr(ip, ':')) { /* Only one option, e.g. "ip=dhcp", or it's an interface name */ if (is_ip) { dev->caps = parse_proto(ip); bringup_first = 1; } else { dev->name = ip; } } else { for (i = opt = 0; ip && *ip; ip = cp, opt++) { if ((cp = strchr(ip, ':'))) { *cp++ = '\0'; } if (opt > 6) { fprintf(stderr, "%s: too many options for %s\n", progname, dev->name); longjmp(abort_buf, 1); } if (*ip == '\0') continue; DEBUG(("IP-Config: opt #%d: '%s'\n", opt, ip)); switch (opt) { case 0: parse_addr(&dev->ip_addr, ip); dev->caps = 0; break; case 1: parse_addr(&dev->ip_server, ip); break; case 2: parse_addr(&dev->ip_gateway, ip); break; case 3: parse_addr(&dev->ip_netmask, ip); break; case 4: strncpy(dev->hostname, ip, SYS_NMLN - 1); dev->hostname[SYS_NMLN - 1] = '\0'; break; case 5: dev->name = ip; break; case 6: dev->caps = parse_proto(ip); break; } } } if (dev->name == NULL || dev->name[0] == '\0' || strcmp(dev->name, "all") == 0) { add_all_devices(dev); return 0; } return 1;}static void bringup_device(struct netdev *dev){ if (netdev_up(dev) == 0) { if (dev->caps) { add_one_dev(dev); } else { complete_device(dev); } }}static void bringup_one_dev(struct netdev *template, struct netdev *dev){ if (template->ip_addr != INADDR_NONE) dev->ip_addr = template->ip_addr; if (template->ip_server != INADDR_NONE) dev->ip_server = template->ip_server; if (template->ip_gateway != INADDR_NONE) dev->ip_gateway = template->ip_gateway; if (template->ip_netmask != INADDR_NONE) dev->ip_netmask = template->ip_netmask; if (template->ip_nameserver[0] != INADDR_NONE) dev->ip_nameserver[0] = template->ip_nameserver[0]; if (template->ip_nameserver[1] != INADDR_NONE) dev->ip_nameserver[1] = template->ip_nameserver[1]; if (template->hostname[0] != '\0') strcpy(dev->hostname, template->hostname); dev->caps &= template->caps; bringup_device(dev);}static struct netdev *add_device(const char *info){ struct netdev *dev; int i; dev = malloc(sizeof(struct netdev)); if (dev == NULL) { fprintf(stderr, "%s: out of memory\n", progname); longjmp(abort_buf, 1); } memset(dev, 0, sizeof(struct netdev)); dev->caps = default_caps; if (parse_device(dev, info) == 0) goto bail; if (netdev_init_if(dev) == -1) goto bail; if (bootp_init_if(dev) == -1) goto bail; printf("IP-Config: %s hardware address", dev->name); for (i = 0; i < dev->hwlen; i++) printf("%c%02x", i == 0 ? ' ' : ':', dev->hwaddr[i]); printf(" mtu %d%s%s\n", dev->mtu, dev->caps & CAP_DHCP ? " DHCP" : dev->caps & CAP_BOOTP ? " BOOTP" : "", dev->caps & CAP_RARP ? " RARP" : ""); return dev; bail: free(dev); return NULL;}static int add_all_devices(struct netdev *template){ DIR *d; struct dirent *de; struct netdev *dev; char t[PATH_MAX], p[255]; int i, fd; unsigned long flags; d = opendir(sysfs_class_net); if (!d) return 0; while ((de = readdir(d)) != NULL) { /* This excludes devices beginning with dots or "dummy", as well as . or .. */ if (de->d_name[0] == '.' || !strcmp(de->d_name, "..")) continue; i = snprintf(t, PATH_MAX - 1, "%s/%s/flags", sysfs_class_net, de->d_name); if (i < 0 || i >= PATH_MAX - 1) continue; t[i] = '\0'; fd = open(t, O_RDONLY); if (fd < 0) { perror(t); continue; } i = read(fd, &p, sizeof(p) - 1); close(fd); if (i < 0) { perror(t); continue; } p[i] = '\0'; flags = strtoul(p, NULL, 0); /* Heuristic for if this is a reasonable boot interface. This is the same logic the in-kernel ipconfig uses... */ if (!(flags & IFF_LOOPBACK) && (flags & (IFF_BROADCAST | IFF_POINTOPOINT))) { DEBUG(("Trying to bring up %s\n", de->d_name)); if (!(dev = add_device(de->d_name))) continue; bringup_one_dev(template, dev); } } closedir(d); return 1;}static int check_autoconfig(void){ int ndev = 0, nauto = 0; struct state *s; for (s = slist; s; s = s->next) { ndev++; if (s->dev->caps) nauto++; } if (ndev == 0) { if (configured == 0) { fprintf(stderr, "%s: no devices to configure\n", progname); longjmp(abort_buf, 1); } } return nauto;}static void set_vendor_identifier(const char *id){ int len = strlen(id); if (len >= 255) { fprintf(stderr, "%s: invalid vendor class identifier: " "%s\n", progname, id); longjmp(abort_buf, 1); } memcpy(vendor_class_identifier+2, id, len); vendor_class_identifier[0] = 60; vendor_class_identifier[1] = len; vendor_class_identifier_len = len+2;}int main(int argc, char *argv[]) __attribute__ ((weak, alias("ipconfig_main")));int ipconfig_main(int argc, char *argv[]){ struct netdev *dev; int c, port; int err; /* If progname is set we're invoked from another program */ if (!progname) { struct timeval now; progname = argv[0]; gettimeofday(&now, NULL); srand48(now.tv_usec ^ (now.tv_sec << 24)); } if ((err = setjmp(abort_buf))) return err; /* Default vendor identifier */ set_vendor_identifier("Linux ipconfig"); do { c = getopt(argc, argv, "c:d:i:onp:t:"); if (c == EOF) break; switch (c) { case 'c': default_caps = parse_proto(optarg); break; case 'p': port = atoi(optarg); if (port <= 0 || port > USHRT_MAX) { fprintf(stderr, "%s: invalid port number %d\n", progname, port); longjmp(abort_buf, 1); } cfg_local_port = port; cfg_remote_port = cfg_local_port - 1; break; case 't': loop_timeout = atoi(optarg); if (loop_timeout < 0) { fprintf(stderr, "%s: invalid timeout %d\n", progname, loop_timeout); longjmp(abort_buf, 1); } break; case 'i': set_vendor_identifier(optarg); break; case 'o': bringup_first = 1; break; case 'n': do_not_config = 1; break; case 'd': dev = add_device(optarg); if (dev) bringup_device(dev); break; case '?': fprintf(stderr, "%s: invalid option -%c\n", progname, optopt); longjmp(abort_buf, 1); } } while (1); for (c = optind; c < argc; c++) { dev = add_device(argv[c]); if (dev) bringup_device(dev); } if (check_autoconfig()) { if (cfg_local_port != LOCAL_PORT) { printf("IP-Config: binding source port to %d, " "dest to %d\n", cfg_local_port, cfg_remote_port); } loop(); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -