📄 netsrv.c
字号:
// Else if this is a "remove", remove the entry
else if( Op == CFGOP_REMOVE )
{
// If no network, return "pass"
if( !pr->hRoute )
return(0);
// Start calling STACK functions
llEnter();
// Remove the route
RtRemove( pr->hRoute, FLG_RTF_REPORT, RTC_NETUNREACH );
// DeRef it
RtDeRef( pr->hRoute );
pr->hRoute = 0;
// Stop calling STACK functions
llExit();
}
// Return success
return(1);
}
//--------------------------------------------------------------------------
// ServiceCallback()
//
// Function to receive callback information from NetTools Services
//--------------------------------------------------------------------------
static void ServiceCallback( HANDLE hCfgEntry, uint Status )
{
CISARGS *pa;
// If we can't get the info, just return
if( CfgEntryInfo( hCfgEntry, 0, (UINT8 **)(&pa) ) < 0 )
return;
// Save the report code
pa->ReportCode = Status;
// Callback status change if pCbSrv is set
if( pa->pCbSrv )
(pa->pCbSrv)( pa->Item, pa->Status, pa->ReportCode, hCfgEntry );
}
//--------------------------------------------------------------------------
// ServiceSpawn()
//
// Spawn a service that is known ready
//--------------------------------------------------------------------------
static void ServiceSpawn( HANDLE hCfg, HANDLE hCfgEntry )
{
CISARGS *pa;
NTARGS NTA;
(void)hCfg;
// If we can't get the info, just return
if( CfgEntryInfo( hCfgEntry, 0, (UINT8 **)(&pa) ) < 0 )
return;
// If the service is already running, return
if( pa->hService )
return;
// Set default state
pa->Status = CIS_SRV_STATUS_ENABLED;
pa->ReportCode = 0;
// Setup NetTools Arguments
if( !(pa->Mode & CIS_FLG_IFIDXVALID) || (pa->Mode & CIS_FLG_CALLBYIP) )
{
NTA.CallMode = NT_MODE_IPADDR;
NTA.IPAddr = pa->IPAddr;
}
else
{
NTA.CallMode = NT_MODE_IFIDX;
NTA.IfIdx = pa->IfIdx;
}
// Install our callback
NTA.hCallback = hCfgEntry;
NTA.pCb = &ServiceCallback;
// Launch Service
switch( pa->Item )
{
#if NETSRV_ENABLE_TELNET
case CFGITEM_SERVICE_TELNET:
{
CI_SERVICE_TELNET *pt = (CI_SERVICE_TELNET *)pa;
pa->hService = TelnetOpen( &NTA, &(pt->param) );
}
break;
#endif
#if NETSRV_ENABLE_HTTP
case CFGITEM_SERVICE_HTTP:
{
CI_SERVICE_HTTP *pt = (CI_SERVICE_HTTP *)pa;
pa->hService = httpOpen( &NTA, &(pt->param) );
}
break;
#endif
#if NETSRV_ENABLE_NAT
case CFGITEM_SERVICE_NAT:
{
CI_SERVICE_NAT *pt = (CI_SERVICE_NAT *)pa;
pa->hService = NATOpen( &NTA, &(pt->param) );
}
break;
#endif
#if NETSRV_ENABLE_DHCPSERVER
case CFGITEM_SERVICE_DHCPSERVER:
{
CI_SERVICE_DHCPS *pt = (CI_SERVICE_DHCPS *)pa;
pa->hService = DHCPSOpen( &NTA, &(pt->param) );
}
break;
#endif
#if NETSRV_ENABLE_DHCPCLIENT
case CFGITEM_SERVICE_DHCPCLIENT:
{
CI_SERVICE_DHCPC *pt = (CI_SERVICE_DHCPC *)pa;
pa->hService = DHCPOpen( &NTA, &(pt->param) );
}
break;
#endif
#if NETSRV_ENABLE_DNSSERVER
case CFGITEM_SERVICE_DNSSERVER:
pa->hService = DNSServerOpen( &NTA );
break;
#endif
}
// Adjust status on failure
if( !pa->hService )
{
pa->Status = CIS_SRV_STATUS_FAILED;
pa->ReportCode = 0;
}
// Callback status change if pCbSrv is set
if( pa->pCbSrv )
(pa->pCbSrv)( pa->Item, pa->Status, pa->ReportCode, hCfgEntry );
}
//--------------------------------------------------------------------------
// ServiceKill()
//
// Kill a service that may or may not be currently executing
//--------------------------------------------------------------------------
static void ServiceKill( HANDLE hCfg, HANDLE hCfgEntry )
{
CISARGS *pa;
(void)hCfg;
// If we can't get the info, just return
if( CfgEntryInfo( hCfgEntry, 0, (UINT8 **)(&pa) ) < 0 )
return;
// If the service is not running, return
if( pa->Status != CIS_SRV_STATUS_ENABLED )
return;
// Set status to DISABLED
pa->Status = CIS_SRV_STATUS_DISABLED;
pa->ReportCode = 0;
if( pa->hService )
{
switch( pa->Item )
{
#if NETSRV_ENABLE_TELNET
case CFGITEM_SERVICE_TELNET:
TelnetClose( pa->hService );
break;
#endif
#if NETSRV_ENABLE_HTTP
case CFGITEM_SERVICE_HTTP:
httpClose( pa->hService );
break;
#endif
#if NETSRV_ENABLE_NAT
case CFGITEM_SERVICE_NAT:
NATClose( pa->hService );
break;
#endif
#if NETSRV_ENABLE_DHCPSERVER
case CFGITEM_SERVICE_DHCPSERVER:
DHCPSClose( pa->hService );
break;
#endif
#if NETSRV_ENABLE_DHCPCLIENT
case CFGITEM_SERVICE_DHCPCLIENT:
DHCPClose( pa->hService );
break;
#endif
#if NETSRV_ENABLE_DNSSERVER
case CFGITEM_SERVICE_DNSSERVER:
DNSServerClose( pa->hService );
break;
#endif
}
}
// Clear service just to be safe
pa->hService = 0;
// Callback status change if pCbSrv is set
if( pa->pCbSrv )
(pa->pCbSrv)( pa->Item, pa->Status, pa->ReportCode, hCfgEntry );
}
//--------------------------------------------------------------------------
// ServiceScan()
//
// Scan services and Spawn and Kill as necessary
//--------------------------------------------------------------------------
static void ServiceScan( HANDLE hCfg )
{
CISARGS *pa;
HANDLE hCfgEntry;
int cfgret,Item;
// This is a standard walk of the configuration
for( Item=1; Item<=CFGITEM_SERVICE_MAX; Item++ )
{
cfgret = CfgGetEntry( hCfg, CFGTAG_SERVICE, Item, 1, &hCfgEntry );
while( cfgret == 1 )
{
// If we can't get the info, skip it
if( CfgEntryInfo( hCfgEntry, 0, (UINT8 **)(&pa) ) < 0 )
goto item_done;
// If we're waiting, see if there's an IP address ready
if( pa->Status == CIS_SRV_STATUS_WAIT )
{
// If the task is not using "ResolveIP", it can always
// start. Otherwise; see if there's an IP address
// available.
if( pa->Mode & CIS_FLG_RESOLVEIP )
{
// Here we must check and see if we have an address
if( !NtIfIdx2Ip(pa->IfIdx, &pa->IPAddr) )
goto item_done;
}
// If we get here, the service can start
ServiceSpawn( hCfg, hCfgEntry );
}
// Else we examine services that are running to see if they
// should be killed.
else if( pa->Status == CIS_SRV_STATUS_ENABLED )
{
HANDLE hTmp;
// If the task is not using "ResolveIP", it is never
// terminated here.
if( !(pa->Mode & CIS_FLG_RESOLVEIP) )
goto item_done;
// Verify the IP address still exists
llEnter();
hTmp = BindIPHost2IF( pa->IPAddr );
llExit();
// Kill the task if the IPAddr is no longer in the system
if( !hTmp )
{
// Kill the service
ServiceKill( hCfg, hCfgEntry );
// Set new service state based on behaviour flag
if( pa->Mode & CIS_FLG_RESTARTIPTERM )
pa->Status = CIS_SRV_STATUS_WAIT;
else
pa->Status = CIS_SRV_STATUS_IPTERM;
}
}
item_done:
// Get the next entry - also releases current entry
cfgret = CfgGetNextEntry( hCfg, hCfgEntry, &hCfgEntry );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -