Esempio n. 1
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. 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[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);
}