예제 #1
0
파일: route.c 프로젝트: rickcaudill/Pyro
int main( int argc, char **argv )
{
	uint8 anAddress[4];
	uint8 anMask[4];
	uint8 anGateway[4] = { 0, 0, 0, 0 };
	const char *pzGateway = NULL, *pzProgram;
	const char *pzCommand, *pzNetAddr, *pzNetMask;
	struct rtentry sRoute;
	bool bLong = false;
	bool bNetSet = false, bMaskSet = false, bGwSet = false;
	int c;
	
	if ( (pzProgram = strrchr( *argv, '/' )) != NULL )
		++pzProgram;
	else
		pzProgram = *argv;

	memset( &sRoute, 0, sizeof( sRoute ) );

	sRoute.rt_metric = 0;
	sRoute.rt_flags = RTF_UP | RTF_STATIC; /* Not necessary */

	while ( ( c = getopt_long( argc, argv, "hlqvi:g:", long_opts, ( int * )0 ) ) != EOF )
	{
		switch ( c )
		{
		case 0:
			break;
		case 'l':
			bLong = true;
			break;
		case 'v':
			g_nShowVersion = true;
			break;
		case 'h':
			g_nShowHelp = true;
			break;
		default:
			usage( pzProgram, 0 );
			return ( EXIT_FAILURE );
		}
	}

	argc -= optind;
	argv += optind;
	
	if ( (pzCommand = *argv++) == NULL )
	{
		usage( pzProgram, 0 );
	
		return ( EXIT_FAILURE );
	}
	
	/* Check command is valid */
	if ( strcmp( pzCommand, "list" ) == 0 )
	{
		list_routes( bLong );
		
		return ( EXIT_SUCCESS );
	}
	else if ( strcmp( pzCommand, "add" ) != 0 && strcmp( pzCommand, "del" ) != 0 )
	{
		usage( pzProgram, 0 );

		return ( EXIT_FAILURE );
	}
	
	
	/* Add or delete a route */
	/* Look for address parameter */
	while ( *argv )
	{
		const char *pzInstruction = *argv++;
    char *pzArg = *argv++;
		
		if ( pzArg == NULL )
		{
			/* No argument */
			usage( pzProgram, 0 );

			return ( EXIT_FAILURE );
		}

		if ( strcmp( pzInstruction, "net" ) == 0 )
		{
			char *pzStr;
			
			if( bNetSet == true )
			{
				usage( pzProgram, 0 );

				return ( EXIT_FAILURE );
			}
			
			if( strcmp( pzArg, "default" ) == 0 )
			{
				bNetSet = true;
				bMaskSet = true;
			}
			else
			{
				if( (pzStr = strchr( pzArg, '/' )) != NULL )
				{
					/* CIDR notation in address parameter */
					int nBits;
					uint32 nIpAddr = 0xFFFFFFFF;
					
					*pzStr++ = 0;
					
					if( (nBits = atoi( pzStr )) < 32 )
						nIpAddr <<= (32 - nBits);

					*((uint32 *)&((struct sockaddr_in *)&sRoute.rt_genmask)->sin_addr) = htonl( nIpAddr );
					bMaskSet = true;
				}
				
				/* Interpret as IP address */
				parse_ipaddress( (uint8*)&((struct sockaddr_in *)&sRoute.rt_dst)->sin_addr, pzArg );
				bNetSet = true;
			}
		}
		else if ( strcmp( pzInstruction, "mask" ) == 0 )
		{
			if( bMaskSet == true )
			{
				usage( pzProgram, 0 );

				return ( EXIT_FAILURE );
			}
			
			parse_ipaddress( (uint8*)&((struct sockaddr_in *)&sRoute.rt_genmask)->sin_addr, pzArg );
			bMaskSet = true;
		}
		else if ( strcmp( pzInstruction, "gw" ) == 0 )
		{
			if( bGwSet == true )
			{
				usage( pzProgram, 0 );

				return ( EXIT_FAILURE );
			}
			
			parse_ipaddress( (uint8*)&((struct sockaddr_in *)&sRoute.rt_gateway)->sin_addr, pzArg );
			sRoute.rt_flags |= RTF_GATEWAY;
			bGwSet = true;
		}
		else
		{
			usage( pzProgram, 0 );

			return ( EXIT_FAILURE );
		}
	}
	
	/* Check for required arguments */
	if( !bNetSet || !bMaskSet )
	{
		usage( pzProgram, 0 );

		return ( EXIT_FAILURE );
	}
	
	/* Perform action */
	if ( strcmp( pzCommand, "add" ) == 0 )
	{
		add_route( &sRoute );
	}
	else if ( strcmp( pzCommand, "del" ) == 0 )
	{
		del_route( &sRoute );
	}
	
	return ( EXIT_SUCCESS );
}
예제 #2
0
파일: route.cpp 프로젝트: mmanley/Antares
int
main(int argc, char** argv)
{
	if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")))
		usage(0);

	int32 mode = RTM_LIST;

	if (argc > 1) {
		if (!strcmp(argv[1], "delete")
			|| !strcmp(argv[1], "del")
			|| !strcmp(argv[1], "-d")) {
			// delete route
			if (argc < 3)
				usage(1);

			mode = RTM_DELETE;
		} else if (!strcmp(argv[1], "add")
			|| !strcmp(argv[1], "-a")) {
			// add route
			if (argc < 3)
				usage(1);

			mode = RTM_ADD;
		} else if (!strcmp(argv[1], "get")) {
			// get route for destination
			if (argc < 3)
				usage(1);

			mode = RTM_GET;
		}
	}

	int32 i = 2;
	int32 interfaceIndex = i;
	bool familySpecified = false;
	int32 familyIndex = 0;
	const char *interface = NULL;
	sockaddr_storage destination;
	sockaddr_storage mask;
	sockaddr_storage gateway;
	bool hasDestination = false, hasGateway = false, hasMask = false;
	bool defaultRoute = false;

	route_entry route;
	memset(&route, 0, sizeof(route_entry));

	while (i < argc && i < 5) {
		// try to parse address family
		if (i <= 3 && familyIndex == -1 && get_address_family(argv[i], familyIndex)) {
			familySpecified = true;
			if (i == 2)
				interfaceIndex = -1;
		}

		if (!strcmp(argv[i], "default")) {
			defaultRoute = true;
			route.flags = RTF_DEFAULT;
			i++;
			break;
		} else if (parse_address(familyIndex, argv[i], destination)) {
			hasDestination = true;
			i++;
			break;
		}

		i++;
	}

	if (!defaultRoute && !hasDestination && mode != RTM_LIST)
		usage(1);

	if (i == 3)
		interfaceIndex = -1;
	if (interfaceIndex != -1 && interfaceIndex < argc)
		interface = argv[interfaceIndex];

	if (i < argc && parse_address(familyIndex, argv[i], mask)) {
		hasMask = true;
		i++;
	}

	// parse options and flags

	while (i < argc) {
		if (!strcmp(argv[i], "gw") || !strcmp(argv[i], "gateway")) {
			if (!parse_address(familyIndex, argv[i + 1], gateway)) {
				fprintf(stderr, "%s: Option 'gw' needs valid address parameter\n",
					kProgramName);
				exit(1);
			}
			hasGateway = true;
			i++;
		} else if (!strcmp(argv[i], "nm") || !strcmp(argv[i], "netmask")) {
			if (hasMask) {
				fprintf(stderr, "%s: Netmask is specified twice\n",
					kProgramName);
				exit(1);
			}
			if (!parse_address(familyIndex, argv[i + 1], mask)) {
				fprintf(stderr, "%s: Option 'netmask' needs valid address parameter\n",
					kProgramName);
				exit(1);
			}
			hasMask = true;
			i++;
		} else if (!strcmp(argv[i], "mtu")) {
			route.mtu = argv[i + 1] ? strtol(argv[i + 1], NULL, 0) : 0;
			if (route.mtu <= 500) {
				fprintf(stderr, "%s: Option 'mtu' exptected valid max transfer unit size\n",
					kProgramName);
				exit(1);
			}
			i++;
		} else if (!strcmp(argv[i], "host")) {
			route.flags |= RTF_HOST;
		} else if (!strcmp(argv[i], "local")) {
			route.flags |= RTF_LOCAL;
		} else if (!strcmp(argv[i], "reject")) {
			route.flags |= RTF_REJECT;
		} else
			usage(1);

		i++;
	}

	if (hasDestination)
		route.destination = (sockaddr *)&destination;
	if (hasMask)
		route.mask = (sockaddr *)&mask;
	if (hasGateway) {
		route.gateway = (sockaddr *)&gateway;
		route.flags |= RTF_GATEWAY;
	}

	// we need a socket to talk to the networking stack
	int socket = ::socket(kFamilies[familyIndex].family, SOCK_DGRAM, 0);
	if (socket < 0) {
		fprintf(stderr, "%s: The requested address family is not available.\n",
			kProgramName);
		return 1;
	}

	switch (mode) {
		case RTM_ADD:
			if (interface == NULL) {
				fprintf(stderr, "%s: You need to specify an interface when adding a route.\n",
					kProgramName);
				usage(1);
			}

			add_route(socket, interface, route);
			break;
		case RTM_DELETE:
			if (interface == NULL) {
				fprintf(stderr, "%s: You need to specify an interface when removing a route.\n",
					kProgramName);
				usage(1);
			}

			delete_route(socket, interface, route);
			break;

		case RTM_LIST:
			if (familySpecified)
				list_routes(socket, interface, route);
			else {
				for (int32 i = 0; kFamilies[i].family >= 0; i++) {
					int socket = ::socket(kFamilies[familyIndex].family, SOCK_DGRAM, 0);
					if (socket < 0)
						continue;

					list_routes(socket, interface, route);
					close(socket);
				}
			}
			break;

		case RTM_GET:
			get_route(socket, route);
			break;
	}

	close(socket);
	return 0;
}