Example #1
0
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);
};
Example #2
0
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;
	};
};