void netman_static_ifup(NetmanIfConfig *config) { printf("[static] attempting configuration of %s\n", config->ifname); StaticConfig *statconf = (StaticConfig*) config->data; // write the DNS servers char dnspath[256]; sprintf(dnspath, "/run/dns/ipv4/%s.if", config->ifname); FILE *fp = fopen(dnspath, "w"); if (fp == NULL) { fprintf(stderr, "[static] WARNING: failed to open %s: cannot configure DNS servers!\n", dnspath); } else { size_t i; fprintf(fp, "# DNS servers from static configuration\n"); for (i=0; i<statconf->dnscount; i++) { char buffer[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &statconf->dns[i], buffer, INET_ADDRSTRLEN); fprintf(fp, "%s\n", buffer); }; fclose(fp); }; // remove all routes if (_glidix_route_clear(AF_INET, config->ifname) != 0) { fprintf(stderr, "[static] cannot clear IPv4 routes of %s: %s\n", config->ifname, strerror(errno)); return; }; // assign addresses if (_glidix_netconf_addr(AF_INET, config->ifname, statconf->addrs, sizeof(IPNetIfAddr4)*statconf->addrcount) != 0) { fprintf(stderr, "[static] failed to configure %s: %s\n", config->ifname, strerror(errno)); return; }; // add all routes int i; for (i=0; i<statconf->routecount; i++) { if (_glidix_route_add(AF_INET, -1, &statconf->routes[i])) { fprintf(stderr, "[static] failed to add route to %s: %s\n", config->ifname, strerror(errno)); _glidix_netconf_addr(AF_INET, config->ifname, NULL, 0); _glidix_route_clear(AF_INET, config->ifname); unlink(dnspath); return; }; }; // wait until we're put down free(statconf); while (netman_running()) pause(); printf("[static] removing configuration\n"); _glidix_netconf_addr(AF_INET, config->ifname, NULL, 0); _glidix_route_clear(AF_INET, config->ifname); unlink(dnspath); };
int mainUtil(int argc, char *argv[]) { if (strcmp(argv[1], "add") == 0) { if (argc < 4) { fprintf(stderr, "USAGE:\t%s add subnet interface [-g gateway] [-i index] [-6]\n", argv[0]); fprintf(stderr, "\tAdds an entry for the specified subnet to the routing table. If the\n"); fprintf(stderr, "\tnetwork size is not given, adds just the specified address. You can\n"); fprintf(stderr, "\talso optionally specify a gateway, as well as the position within the\n"); fprintf(stderr, "\tinterface's routing table. The '-6' indicates that the route is IPv6.\n"); return 1; }; char subnet[INET6_ADDRSTRLEN+4]; char gateway[INET6_ADDRSTRLEN] = ""; char ifname[16]; int pos = -1; int family = AF_INET; if (strlen(argv[2]) > (INET6_ADDRSTRLEN+4)) { fprintf(stderr, "%s: invalid address or subnet: %s\n", argv[0], argv[2]); return 1; }; if (strlen(argv[3]) > 15) { fprintf(stderr, "%s: invalid interface name: %s\n", argv[0], argv[3]); return 1; }; strcpy(subnet, argv[2]); strcpy(ifname, argv[3]); int i; for (i=4; i<argc; i++) { if (strcmp(argv[i], "-g") == 0) { i++; if (strlen(argv[i]) > 15) { fprintf(stderr, "%s: invalid gateway: %s\n", argv[0], argv[i]); return 1; }; strcpy(gateway, argv[i]); } else if (strcmp(argv[i], "-i") == 0) { i++; pos = atoi(argv[i]); } else if (strcmp(argv[i], "-6") == 0) { family = AF_INET6; } else { fprintf(stderr, "%s: unrecognised command-line option: %s\n", argv[0], argv[i]); return 1; }; }; if (gateway[0] == 0) { if (family == AF_INET) { strcpy(gateway, "0.0.0.0"); } else { strcpy(gateway, "::"); }; }; _glidix_gen_route genroute; _glidix_in_route *inroute = (_glidix_in_route*) &genroute; _glidix_in6_route *in6route = (_glidix_in6_route*) &genroute; if (family == AF_INET) strcpy(inroute->ifname, ifname); else strcpy(in6route->ifname, ifname); if (family == AF_INET) memset(&inroute->mask, 0xFF, 4); else memset(&in6route->mask, 0xFF, 16); char *slashpos = strchr(subnet, '/'); if (slashpos != NULL) { *slashpos = 0; int netsize = atoi(slashpos+1); int maxNetSize = 32; if (family == AF_INET6) maxNetSize = 128; if ((netsize < 0) || (netsize > maxNetSize)) { fprintf(stderr, "%s: invalid subnet size: /%d\n", argv[0], netsize); return 1; }; uint8_t *out; if (family == AF_INET) out = (uint8_t*) &inroute->mask; else out = (uint8_t*) &in6route->mask; if (family == AF_INET) memset(out, 0, 4); else memset(out, 0, 16); while (netsize >= 8) { *out++ = 0xFF; netsize -= 8; }; if (netsize > 0) { // number of bits at the end that should be 0 int zeroBits = 8 - netsize; // make a number which has this many '1's at the end, and then NOT it *out = ~((1 << zeroBits)-1); }; }; if (family == AF_INET) { if (inet_pton(AF_INET, subnet, &inroute->dest) != 1) { fprintf(stderr, "%s: failed to parse address %s: %s\n", argv[0], subnet, strerror(errno)); return 1; }; if (inet_pton(AF_INET, gateway, &inroute->gateway) != 1) { fprintf(stderr, "%s: failed to parse address %s: %s\n", argv[0], gateway, strerror(errno)); return 1; }; } else { if (inet_pton(AF_INET6, subnet, &in6route->dest) != 1) { fprintf(stderr, "%s: failed to parse address %s: %s\n", argv[0], subnet, strerror(errno)); return 1; }; if (inet_pton(AF_INET6, gateway, &in6route->gateway) != 1) { fprintf(stderr, "%s: failed to parse address %s: %s\n", argv[0], gateway, strerror(errno)); return 1; }; }; if (family == AF_INET) inroute->flags = 0; else in6route->flags = 0; if (_glidix_route_add(family, pos, &genroute) != 0) { fprintf(stderr, "%s: failed to add the route: %s\n", argv[0], strerror(errno)); return 1; }; return 0; } else if (strcmp(argv[1], "clear") == 0) { if (argc != 3) { fprintf(stderr, "USAGE:\t%s clear <interface>\n", argv[0]); fprintf(stderr, "\tDelete all IPv4 routes of an interface.\n"); fprintf(stderr, "\tSee also: clear6\n"); return 1; }; if (_glidix_route_clear(AF_INET, argv[2]) != 0) { fprintf(stderr, "%s: cannot clear %s: %s\n", argv[0], argv[2], strerror(errno)); return 1; }; return 0; } else if (strcmp(argv[1], "clear6") == 0) { if (argc != 3) { fprintf(stderr, "USAGE:\t%s clear6 <interface>\n", argv[0]); fprintf(stderr, "\tDelete all IPv6 routes of an interface.\n"); fprintf(stderr, "\tSee also: clear\n"); return 1; }; if (_glidix_route_clear(AF_INET6, argv[2]) != 0) { fprintf(stderr, "%s: cannot clear6 %s: %s\n", argv[0], argv[2], strerror(errno)); return 1; }; return 0; } else { fprintf(stderr, "%s: unknown command: %s\n", argv[0], argv[1]); return 1; }; };