Esempio n. 1
0
File: main.c Progetto: odit/rv042
int main (int argc, char** argv)
{
	char descDocUrl[7+15+1+5+1+sizeof(g_vars.descDocName)+1]; // http://ipaddr:port/docName<null>
	char intIpAddress[16];     // Server internal ip address
	sigset_t sigsToCatch;
	int ret, signum, arg = 1, foreground = 0;

	if (argc < 3 || argc > 4) {
	  printf("Usage: upnpd [-f] <external ifname> <internal ifname>\n");
	  printf("  -f\tdon't daemonize\n");
	  printf("Example: upnpd ppp0 eth0\n");
	  exit(0);
	}

	parseConfigFile(&g_vars);

	// check for '-f' option
	if (strcmp(argv[arg], "-f") == 0) {
		foreground = 1;
		arg++;
	}

	// Save interface names for later use
	strncpy(g_vars.extInterfaceName, argv[arg++], IFNAMSIZ);
	strncpy(g_vars.intInterfaceName, argv[arg++], IFNAMSIZ);

	// Get the internal ip address to start the daemon on
	if (GetIpAddressStr(intIpAddress, g_vars.intInterfaceName) == 0) {
		fprintf(stderr, "Invalid internal interface name '%s'\n", g_vars.intInterfaceName);
		exit(EXIT_FAILURE);
	}

	if (!foreground) {
		struct rlimit resourceLimit = { 0, 0 };
		pid_t pid, sid;
		unsigned int i;

		// Put igd in the background as a daemon process.
		pid = fork();
		if (pid < 0)
		{
			perror("Error forking a new process.");
			exit(EXIT_FAILURE);
		}
		if (pid > 0)
			exit(EXIT_SUCCESS);

		// become session leader
		if ((sid = setsid()) < 0)
		{
			perror("Error running setsid");
			exit(EXIT_FAILURE);
		}

		// close all file handles
		resourceLimit.rlim_max = 0;
		ret = getrlimit(RLIMIT_NOFILE, &resourceLimit);
		if (ret == -1) /* shouldn't happen */
		{
		    perror("error in getrlimit()");
		    exit(EXIT_FAILURE);
		}
		if (0 == resourceLimit.rlim_max)
		{
		    fprintf(stderr, "Max number of open file descriptors is 0!!\n");
		    exit(EXIT_FAILURE);
		}	
		for (i = 0; i < resourceLimit.rlim_max; i++)
		    close(i);
	
		// fork again so child can never acquire a controlling terminal
		pid = fork();
		if (pid < 0)
		{
			perror("Error forking a new process.");
			exit(EXIT_FAILURE);
		}
		if (pid > 0)
			exit(EXIT_SUCCESS);
	
		if ((chdir("/")) < 0)
		{
			perror("Error setting root directory");
			exit(EXIT_FAILURE);
		}
	}

	umask(0);

// End Daemon initialization

	openlog("upnpd", LOG_CONS | LOG_NDELAY | LOG_PID | (foreground ? LOG_PERROR : 0), LOG_LOCAL6);

	// Initialize UPnP SDK on the internal Interface
	trace(3, "Initializing UPnP SDK ... ");
	if ( (ret = UpnpInit(intIpAddress,0) ) != UPNP_E_SUCCESS)
	{
		syslog (LOG_ERR, "Error Initializing UPnP SDK on IP %s ",intIpAddress);
		syslog (LOG_ERR, "  UpnpInit returned %d", ret);
		UpnpFinish();
		exit(1);
	}
	trace(2, "UPnP SDK Successfully Initialized.");

	// Set the Device Web Server Base Directory
	trace(3, "Setting the Web Server Root Directory to %s",g_vars.xmlPath);
	if ( (ret = UpnpSetWebServerRootDir(g_vars.xmlPath)) != UPNP_E_SUCCESS )
	{
		syslog (LOG_ERR, "Error Setting Web Server Root Directory to: %s", g_vars.xmlPath);
		syslog (LOG_ERR, "  UpnpSetWebServerRootDir returned %d", ret); 
		UpnpFinish();
		exit(1);
	}
	trace(2, "Succesfully set the Web Server Root Directory.");

	//initialize the timer thread for expiration of mappings
	if (ExpirationTimerThreadInit()!=0) {
	  syslog(LOG_ERR,"ExpirationTimerInit failed");
	  UpnpFinish();
	  exit(1);
	}

	// Form the Description Doc URL to pass to RegisterRootDevice
	sprintf(descDocUrl, "http://%s:%d/%s", UpnpGetServerIpAddress(),
				UpnpGetServerPort(), g_vars.descDocName);

	// Register our IGD as a valid UPnP Root device
	trace(3, "Registering the root device with descDocUrl %s", descDocUrl);
	if ( (ret = UpnpRegisterRootDevice(descDocUrl, EventHandler, &deviceHandle,
					   &deviceHandle)) != UPNP_E_SUCCESS )
	{
		syslog(LOG_ERR, "Error registering the root device with descDocUrl: %s", descDocUrl);
		syslog(LOG_ERR, "  UpnpRegisterRootDevice returned %d", ret);
		UpnpFinish();
		exit(1);
	}

	trace(2, "IGD root device successfully registered.");
	
	// Initialize the state variable table.
	StateTableInit(descDocUrl);
	
	// Record the startup time, for uptime
	startup_time = time(NULL);
	
	// Send out initial advertisements of our device's services with timeouts of 30 minutes
	if ( (ret = UpnpSendAdvertisement(deviceHandle, 1800) != UPNP_E_SUCCESS ))
	{
		syslog(LOG_ERR, "Error Sending Advertisements.  Exiting ...");
		UpnpFinish();
		exit(1);
	}
	trace(2, "Advertisements Sent.  Listening for requests ... ");
	
	// Loop until program exit signals received
	do {
	  sigemptyset(&sigsToCatch);
	  sigaddset(&sigsToCatch, SIGINT);
	  sigaddset(&sigsToCatch, SIGTERM);
	  sigaddset(&sigsToCatch, SIGUSR1);
	  pthread_sigmask(SIG_SETMASK, &sigsToCatch, NULL);
	  sigwait(&sigsToCatch, &signum);
	  trace(3, "Caught signal %d...\n", signum);
	  switch (signum) {
	  case SIGUSR1:
	    DeleteAllPortMappings();
	    break;
	  default:
	    break;
	  }
	} while (signum!=SIGTERM && signum!=SIGINT);

	trace(2, "Shutting down on signal %d...\n", signum);

	// Cleanup UPnP SDK and free memory
	DeleteAllPortMappings();
	ExpirationTimerThreadShutdown();

	UpnpUnRegisterRootDevice(deviceHandle);
	UpnpFinish();

	// Exit normally
	return (0);
}
Esempio n. 2
0
int main (int argc, char** argv)
{
	int ret = UPNP_E_SUCCESS;
	int signal;	
	char descDocUrl[50];
	char descDocName[20];
	char xmlPath[50];
	char intIpAddress[32];     // Server internal ip address
	char extIpAddress[32];
	sigset_t sigsToCatch;
	pid_t pid,sid;

	if (argc != 3)
   {
      printf("Usage: upnpd <external ifname> <internal ifname>\n");
      printf("Example: upnpd ppp0 eth0\n");
      printf("Example: upnpd eth1 eth0\n");
      exit(0);
   }

	parseConfigFile(&g_forwardRules,&g_debug,g_iptables,
		        g_forwardChainName,g_preroutingChainName,
			g_upstreamBitrate,g_downstreamBitrate,
			descDocName,xmlPath);

	// Save the interface names for later uses
	strcpy(g_extInterfaceName, argv[1]);
	strcpy(g_intInterfaceName, argv[2]);

	// Get the internal and external ip address to start the daemon on
		
	/* Added by Yanhua */
	while( (GetIpAddressStr(intIpAddress, g_intInterfaceName)==0) || 
		(GetIpAddressStr(extIpAddress, g_extInterfaceName)==0) )
	{  
		sleep(2);
	}
#if 0	
	// Put igd in the background as a daemon process.
	pid = vfork();
	if (pid < 0)
	{
		perror("Error forking a new process.");
		exit(EXIT_FAILURE);
	}
	if (pid > 0)
		exit(EXIT_SUCCESS);
	if ((sid = setsid()) < 0)
	{
		perror("Error running setsid");
		exit(EXIT_FAILURE);
	}
	if ((chdir("/")) < 0)
	{
		perror("Error setting root directory");
		exit(EXIT_FAILURE);
	}
	
	umask(0);
	close(STDERR_FILENO);
	close (STDIN_FILENO);
	close (STDOUT_FILENO);	
#endif

// End Daemon initialization
	
	// Initialize UPnP SDK on the internal Interface
	if (g_debug) syslog(LOG_DEBUG, "Initializing UPnP SDK ... ");
	if ( (ret = UpnpInit(intIpAddress,0) ) != UPNP_E_SUCCESS)
	{
		syslog (LOG_ERR, "Error Initializing UPnP SDK on IP %s ",intIpAddress);
		syslog (LOG_ERR, "  UpnpInit returned %d", ret);
	
		UpnpFinish();
		exit(1);
	}
	if (g_debug) syslog(LOG_DEBUG, "UPnP SDK Successfully Initialized.");
	// Set the Device Web Server Base Directory
	if (g_debug) syslog(LOG_DEBUG, "Setting the Web Server Root Directory to %s",xmlPath);
	if ( (ret = UpnpSetWebServerRootDir(xmlPath)) != UPNP_E_SUCCESS )
	{
		syslog (LOG_ERR, "Error Setting Web Server Root Directory to: %s", xmlPath);
		syslog (LOG_ERR, "  UpnpSetWebServerRootDir returned %d", ret); 
	
		UpnpFinish();
		exit(1);
	}
	if (g_debug) syslog(LOG_DEBUG, "Succesfully set the Web Server Root Directory.");


	// Form the Description Doc URL to pass to RegisterRootDevice
	sprintf(descDocUrl, "http://%s:%d/%s", UpnpGetServerIpAddress(),
				UpnpGetServerPort(), descDocName);
	// Register our IGD as a valid UPnP Root device
	if (g_debug) syslog(LOG_DEBUG, "Registering the root device with descDocUrl %s", descDocUrl);
	if ( (ret = UpnpRegisterRootDevice(descDocUrl, EventHandler, &deviceHandle,
													&deviceHandle)) != UPNP_E_SUCCESS )
	{		
		syslog(LOG_ERR, "Error registering the root device with descDocUrl: %s", descDocUrl);
		syslog(LOG_ERR, "  UpnpRegisterRootDevice returned %d", ret);
		UpnpFinish();
		exit(1);
	}

	syslog (LOG_DEBUG, "IGD root device successfully registered.");
	// Initialize the state variable table.
	StateTableInit(descDocUrl);
	
	// Record the startup time, for uptime
	/* Modified by Yanhua */
#if 0	
	startup_time = time(NULL);
#endif	
	{
	struct sysinfo info;
   	sysinfo(&info);
	startup_time = (long int)info.uptime;
	}
	
	
	// Send out initial advertisements of our device's services with timeouts of 30 minutes
	if ( (ret = UpnpSendAdvertisement(deviceHandle, 1800) != UPNP_E_SUCCESS ))
	{
		syslog(LOG_ERR, "Error Sending Advertisements.  Exiting ...");
		UpnpFinish();
		exit(1);
	}
	syslog(LOG_DEBUG, "Advertisements Sent.  Listening for requests ... ");
	
	// Loop until program exit signals recieved
	sigemptyset(&sigsToCatch);
	sigaddset(&sigsToCatch, SIGINT);
	sigaddset(&sigsToCatch, SIGTERM);
	//sigwait(&sigsToCatch, &signal);
	pthread_sigmask(SIG_SETMASK, &sigsToCatch, NULL);
	sigwait(&sigsToCatch, &signal);
	syslog(LOG_DEBUG, "Shutting down on signal %d...\n", signal);

	// Cleanup UPnP SDK and free memory
	pmlist_FreeList(); 

	UpnpUnRegisterRootDevice(deviceHandle);
	UpnpFinish();

	// Exit normally
	return (1);
}
Esempio n. 3
0
int main (int argc, char** argv)
{
	int ret = UPNP_E_SUCCESS;
	int signal;	
	char descDocUrl[50];
	char descDocName[20];
	char xmlPath[50];
	char intIpAddress[16];     // Server internal ip address
	char extIpAddress[16];     // Server internal ip address
	sigset_t sigsToCatch;
	FILE *f;

	pid_t pid,sid;

	if (argc != 3)
   {
      printf("Usage: upnpd <external ifname> <internal ifname>\n");
      printf("Example: upnpd ppp0 eth0\n");
      printf("Example: upnpd eth1 eth0\n");
      exit(0);
   }

	parseConfigFile(&g_forwardRules,&g_debug,g_iptables,
		        g_forwardChainName,g_preroutingChainName,
			g_upstreamBitrate,g_downstreamBitrate,
			descDocName,xmlPath);
	// Save the interface names for later uses
	strcpy(g_extInterfaceName, argv[1]);
	strcpy(g_intInterfaceName, argv[2]);

	openlog("upnpd", LOG_PID | LOG_CONS, LOG_USER);

	// Get the internal ip address to start the daemon on
	GetIpAddressStr(intIpAddress, g_intInterfaceName);	
	GetIpAddressStr(extIpAddress, g_extInterfaceName);	

	// Put igd in the background as a daemon process.
	pid = fork();
	if (pid < 0)
	{
		perror("Error forking a new process.");
		cleanup();
		exit(EXIT_FAILURE);
	}

	if (pid > 0)
		exit(EXIT_SUCCESS);

	/* if we are here, we know we are the demonized version */

	//open a state file
	f = fopen(STATE_FILE, "w");
	if (!f) {
		syslog(LOG_ERR, "failed to open %s: %m", STATE_FILE);
	} else {
		fprintf(f, "external %s %s\ninternal %s %s\n", g_extInterfaceName,
				extIpAddress, g_intInterfaceName, intIpAddress);
		fclose(f);
	}
	atexit(cleanup);

	if ((sid = setsid()) < 0)
	{
		perror("Error running setsid");
		exit(EXIT_FAILURE);
	}
	if ((chdir("/")) < 0)
	{
		perror("Error setting root directory");
		exit(EXIT_FAILURE);
	}
	
	umask(0);
	close(STDERR_FILENO);
	close (STDIN_FILENO);
	close (STDOUT_FILENO);	


// End Daemon initialization

	// Initialize UPnP SDK on the internal Interface
	if (g_debug) syslog(LOG_DEBUG, "Initializing UPnP SDK ... ");
	if ( (ret = UpnpInit(intIpAddress,0) ) != UPNP_E_SUCCESS)
	{
		syslog (LOG_ERR, "Error Initializing UPnP SDK on IP %s ",intIpAddress);
		syslog (LOG_ERR, "  UpnpInit returned %d", ret);
		UpnpFinish();
		exit(1);
	}
	if (g_debug) syslog(LOG_DEBUG, "UPnP SDK Successfully Initialized.");

	// Set the Device Web Server Base Directory
	if (g_debug) syslog(LOG_DEBUG, "Setting the Web Server Root Directory to %s",xmlPath);
	if ( (ret = UpnpSetWebServerRootDir(xmlPath)) != UPNP_E_SUCCESS )
	{
		syslog (LOG_ERR, "Error Setting Web Server Root Directory to: %s", xmlPath);
		syslog (LOG_ERR, "  UpnpSetWebServerRootDir returned %d", ret); 
		UpnpFinish();
		exit(1);
	}
	if (g_debug) syslog(LOG_DEBUG, "Succesfully set the Web Server Root Directory.");


	// Form the Description Doc URL to pass to RegisterRootDevice
	sprintf(descDocUrl, "http://%s:%d/%s", UpnpGetServerIpAddress(),
				UpnpGetServerPort(), descDocName);

	// Register our IGD as a valid UPnP Root device
	if (g_debug) syslog(LOG_DEBUG, "Registering the root device with descDocUrl %s", descDocUrl);
	if ( (ret = UpnpRegisterRootDevice(descDocUrl, EventHandler, &deviceHandle,
													&deviceHandle)) != UPNP_E_SUCCESS )
	{
		syslog(LOG_ERR, "Error registering the root device with descDocUrl: %s", descDocUrl);
		syslog(LOG_ERR, "  UpnpRegisterRootDevice returned %d", ret);
		UpnpFinish();
		exit(1);
	}

	syslog (LOG_DEBUG, "IGD root device successfully registered.");
	
	// Initialize the state variable table.
	StateTableInit(descDocUrl);
	
	// Record the startup time, for uptime
	startup_time = time(NULL);
	
	// Send out initial advertisements of our device's services with timeouts of 30 minutes
	if ( (ret = UpnpSendAdvertisement(deviceHandle, 1800) != UPNP_E_SUCCESS ))
	{
		syslog(LOG_ERR, "Error Sending Advertisements.  Exiting ...");
		UpnpFinish();
		exit(1);
	}
	syslog(LOG_DEBUG, "Advertisements Sent.  Listening for requests ... ");
	
	// Loop until program exit signals recieved
	// and now also recreate the current portmappings on SIGUSR1
	while (1) {
		sigemptyset(&sigsToCatch);
		sigaddset(&sigsToCatch, SIGINT);
		sigaddset(&sigsToCatch, SIGTERM);
		sigaddset(&sigsToCatch, SIGQUIT);
		sigaddset(&sigsToCatch, SIGABRT);
		sigaddset(&sigsToCatch, SIGHUP);
		sigaddset(&sigsToCatch, SIGUSR1);
		sigaddset(&sigsToCatch, SIGUSR2);
		//sigwait(&sigsToCatch, &signal);
		pthread_sigmask(SIG_SETMASK, &sigsToCatch, NULL);
		sigwait(&sigsToCatch, &signal);
		if (signal == SIGUSR1) {
			syslog(LOG_DEBUG, "signal SIGUSR1 received - rebuilding portmappings\n");
			//rebuild all the portmappings
			pmlist_RecreateAll();
		} else if (signal == SIGHUP || signal == SIGUSR2) {
			//nothing
		} else {
			break;
		}
	}
	syslog(LOG_DEBUG, "Shutting down on signal %d...\n", signal);

	// Cleanup UPnP SDK and free memory
	pmlist_FreeList(); 

	UpnpUnRegisterRootDevice(deviceHandle);
	UpnpFinish();

	// Exit normally
	return (1);
}