📄 sockpcb.c
字号:
// If we got here, the addr is OK
ps->dwLIP = dwLIP;
ps->LPort = LPort;
ps->OptionFlags |= SockOpts;
return(0);
}
//--------------------------------------------------------------------
// SockPcbConnect()
//
// Set the foreign address to that specified in FIP and FPort
//--------------------------------------------------------------------
int SockPcbConnect( HANDLE hSock, IPN dwFIP, uint FPort )
{
SOCK *ps = (SOCK *)hSock;
SOCK *psTmp;
int wc;
#ifdef _STRONG_CHECKING
if( ps->Type != HTYPE_SOCK )
{
DbgPrintf(DBG_ERROR,"SockPcbConnect: HTYPE %04x",ps->Type);
return( 0 );
}
if( ps->SockProt > 4 )
{
DbgPrintf(DBG_ERROR,"SockPcbConnect: Invalid SockProt");
return( 0 );
}
#endif
// Anything goes with Raw sockets
if( ps->SockProt == SOCKPROT_RAW )
goto SockPcbConnectOk;
// Verify that we have a local binding
// Note that dwLIP can be NULL if one really odd case...
if( !ps->dwLIP || !ps->LPort )
{
// We can bind to [0.0.0.0] if we've specified an IFTx device
if( !ps->LPort || !ps->hIFTx )
return( EINVAL );
}
// Verify we have a desired IP, and port
if( !dwFIP || !FPort )
return( EINVAL );
// Find the best match
psTmp = SockPcbFind( pSockList[ps->SockProt],
ps->dwLIP, ps->LPort, dwFIP, FPort, &wc, 0 );
// Check for conflict
if( psTmp && psTmp != ps && wc == 0 )
return( EADDRINUSE );
SockPcbConnectOk:
// If we got here, the addr is OK
ps->dwFIP = dwFIP;
ps->FPort = FPort;
return(0);
}
//--------------------------------------------------------------------
// SockPcbResolve()
//
// Find the "best" match given the supplied parameters, and
// potentially spawn a new socket from an "accepting" (listening)
// socket.
//--------------------------------------------------------------------
HANDLE SockPcbResolve
(
uint SockProt,
IPN dwLIP,
uint LPort,
IPN dwFIP,
uint FPort,
uint Match
)
{
SOCK *ps;
SOCK *psSpawn;
int wc;
// The first thing to do is the find the best match
ps = SockPcbFind( pSockList[SockProt],
dwLIP, LPort, dwFIP, FPort, &wc, 0 );
// Return NULL for no match, or for wildcard match when EXACT required
if( !ps || (wc && Match == SOCK_RESOLVE_EXACT) )
return(0);
// If match type is not SPAWN, then we return what we got
if( Match != SOCK_RESOLVE_SPAWN )
return( ps );
// We have a match type of SPAWN with wildcards. Here, we only return
// a socket if we can spawn it. i.e.: exact match is a failure
if( !wc )
return(0);
// If we're out of connect space, abort
if( ps->ConnTotal >= ps->ConnMax )
return(0);
// Create a new socket - return NULL if we can't create it
if( SockNew(ps->Family, ps->SockType, ps->Protocol, 0, (HANDLE *)&psSpawn) )
return(0);
// Inherit SOCKET Options
psSpawn->OptionFlags |= ps->OptionFlags & ~(SO_ACCEPTCONN);
psSpawn->dwLingerTime = ps->dwLingerTime;
psSpawn->dwRxTimeout = ps->dwRxTimeout;
psSpawn->dwTxTimeout = ps->dwTxTimeout;
// Inherit IP Options
psSpawn->IpFlags = ps->IpFlags;
psSpawn->IpTtl = ps->IpTtl;
psSpawn->IpTos = ps->IpTos;
if( ps->IpOptSize )
{
psSpawn->IpOptSize = ps->IpOptSize;
mmCopy( psSpawn->IpOptions, ps->IpOptions, ps->IpOptSize );
}
// Inherit Some Protocol Options
SockPrInherit( ps, psSpawn );
// We're going to cheat here. We know the specified parameters do
// not conflict (as there was no exact match).
psSpawn->dwLIP = dwLIP;
psSpawn->LPort = LPort;
psSpawn->dwFIP = dwFIP;
psSpawn->FPort = FPort;
// Enqueue the spawned packet onto the parent's Pending queue
psSpawn->pParent = ps;
psSpawn->pPending = ps->pPending;
ps->pPending = psSpawn;
psSpawn->StateFlags |= SS_PENDINGQ;
ps->ConnTotal++;
return( psSpawn );
}
//--------------------------------------------------------------------
// SockPcbResolveChain()
//
// This is a chain version of PCB resolve, finding all sockets which
// match the selection criteria.
//--------------------------------------------------------------------
HANDLE SockPcbResolveChain
(
HANDLE hSock,
uint SockProt,
uint Prot,
IPN dwLIP,
uint LPort,
IPN dwFIP,
uint FPort
)
{
SOCK *ps = (SOCK *)hSock;
// We chain off the supplied SOCK, or start at the head of the list
// on a NULL
if( !ps )
ps = pSockList[SockProt];
else
ps = ps->pProtNext;
// Find a match
if( SockProt != SOCKPROT_RAW )
ps = SockPcbFind( ps, dwLIP, LPort, dwFIP, FPort, 0, 1 );
else
ps = SockPcbFindRaw( ps, Prot, dwLIP, dwFIP, 0, 1 );
return(ps);
}
//--------------------------------------------------------------------
// SockPcbCleanup()
//
// Abort all closing sockets
//--------------------------------------------------------------------
void SockPcbCleanup()
{
SOCK *ps;
int GotOne;
// The only type of socket that can be "closing" is TCP
// We'll search and we'll search until no Closing socket lives
do
{
GotOne = 0;
ps = pSockList[SOCKPROT_TCP];
while( ps )
{
if( ps->StateFlags & SS_CLOSING )
{
GotOne = 1;
SockIntAbort( ps );
break;
}
ps = ps->pProtNext;
}
} while( GotOne );
}
//--------------------------------------------------------------------
// SockCtlError()
//
// Called to notify the socket layer that an error has occurred
//--------------------------------------------------------------------
void SockPcbCtlError( uint Code, IPHDR *pIpHdr )
{
IPN dwLIP,dwFIP;
uint offset,SockProt;
int wc;
UDPHDR *pUdpHdr;
SOCK *ps;
dwFIP = RdNet32( &pIpHdr->dwIPDst );
dwLIP = RdNet32( &pIpHdr->dwIPSrc );
// Get the offset to the transport hdr (assume UDP)
offset = (pIpHdr->VerLen & 0xF) * 4;
pUdpHdr = (UDPHDR *)(((UINT8 *)pIpHdr)+offset);
// Get the correct SockProt to notify
if( pIpHdr->Protocol == 6 )
SockProt = SOCKPROT_TCP;
else if( pIpHdr->Protocol == 17 )
SockProt = SOCKPROT_UDP;
else
return;
// Notify all exact matches
ps = pSockList[SockProt];
while( ps )
{
// Find a match
ps = SockPcbFind( ps, dwLIP, pUdpHdr->SrcPort,
dwFIP, pUdpHdr->DstPort, &wc, 1 );
// Notify the protocol
if( ps && !wc )
{
// For redirect errors, we just update the route.
if( Code >= PRC_REDIRECT_NET && Code <= PRC_REDIRECT_TOSHOST )
SockValidateRoute( ps );
else
SockPrCtlError( ps, Code );
}
// Get the next matching socket
if( ps )
ps = ps->pProtNext;
}
}
//--------------------------------------------------------------------
// SockPcbRtChange()
//
// Called to notify the socket layer that a route has changed
//--------------------------------------------------------------------
void SockPcbRtChange( HANDLE hRt )
{
SOCK *ps;
int i;
for( i=SOCKPROT_TCP; i<=SOCKPROT_RAW; i++ )
{
ps = pSockList[i];
while(ps)
{
if( ps->hRoute == hRt )
{
ps->hRoute = 0;
RtDeRef( hRt );
}
SockValidateRoute( ps );
ps = ps->pProtNext;
}
}
}
//--------------------------------------------------------------------
// SockGetPcb()
//
// Return socket PCB list
//--------------------------------------------------------------------
int SockGetPcb( uint SockProt, uint BufSize, UINT8 *pBuf )
{
SOCK *ps;
SOCKPCB *ppcb;
int i;
if( SockProt<SOCKPROT_TCP || SockProt>SOCKPROT_RAW )
return(0);
ps = pSockList[ SockProt ];
i=0;
while( ps && BufSize >= sizeof( SOCKPCB ))
{
ppcb = (SOCKPCB *)pBuf;
ppcb->IPAddrLocal = ps->dwLIP;
ppcb->PortLocal = ps->LPort;
ppcb->IPAddrForeign = ps->dwFIP;
ppcb->PortForeign = ps->FPort;
if( ps->hTP )
ppcb->State = SockPrGetState( ps, ps->hTP );
else
ppcb->State = 0;
if( !ppcb->State && (ps->OptionFlags & SO_ACCEPTCONN) )
ppcb->State = 1;
i++;
BufSize -= sizeof(SOCKPCB);
pBuf += sizeof(SOCKPCB);
ps = ps->pProtNext;
}
return(i);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -