📄 ipin.c
字号:
if( Opt == IPOPT_RR || Opt == IPOPT_SSRR || Opt == IPOPT_LSRR )
{
// Get the offset
w = pIpHdr->Options[OptIdx+2];
// Offset less than 4 is illegal
if( w<4 )
{
// This is an ICMP error
// Give the whole works to ICMP
ips.dwBadoptions++;
w = IPHDR_SIZE+OptIdx+2;
ICMPGenPacket( pIpHdr, hIFRx, ICMP_PARAMPROB, w, 0 );
PktFree( hPkt );
return;
}
// Make offset Zero based (is normally 1 based)
w--;
}
// Process Option
switch( Opt )
{
// OPTION: NOP
case IPOPT_NOP:
default:
break;
// OPTION: Record Route
case IPOPT_RR:
// Ignore if there's no more room
if( (w+4) >= OptSize )
break;
// Get the IP of the outgoing IF (or local host)
if( !(IPTmp = IPRouteIP( hIFRx, IPDst, IPSrc, Opt )) )
{
// If no address found, we have an error
// Give the whole works to ICMP
ips.dwCantforward++;
if( IP_FORWARDING )
ICMPGenPacket( pIpHdr, hIFRx, ICMP_UNREACH,
ICMP_UNREACH_HOST, 0 );
PktFree( hPkt );
return;
}
// Save IP addr in the header
mmCopy( pIpHdr->Options+OptIdx+w, (UINT8 *)&IPTmp, 4 );
// Bump the offset
pIpHdr->Options[OptIdx+2] += sizeof(IPN);
break;
// OPTION: Source Route
case IPOPT_LSRR:
case IPOPT_SSRR:
// If the packet isn't addressed to us, there's not much
// to do.
if( !BindFindByHost( 0, IPDst) )
{
// If using SSRR or not routing, this is an error
if( Opt == IPOPT_SSRR || !IP_FORWARDING )
{
ips.dwCantforward++;
ICMPGenPacket( pIpHdr, hIFRx, ICMP_UNREACH,
ICMP_UNREACH_SRCFAIL, 0 );
PktFree( hPkt );
return;
}
// Here we're using LSRR, but we can't do anything
break;
}
// Here we know the packet is for us. If we're at the
// end of the source route, we're done
if( w >= OptSize )
break;
// Get the IP addr of the next hop
mmCopy( (UINT8 *)&IPDst, pIpHdr->Options+OptIdx+w, 4 );
// If we don't forward, or we can't get the next hop,
// this is an error
if( !IP_FORWARDING ||
!(IPTmp = IPRouteIP( hIFRx, IPDst, IPSrc, Opt )) )
{
ips.dwCantforward++;
ICMPGenPacket( pIpHdr, hIFRx, ICMP_UNREACH,
ICMP_UNREACH_SRCFAIL, 0 );
PktFree( hPkt );
return;
}
// Save outgoing IP addr in the header
mmCopy( pIpHdr->Options+OptIdx+w, (UINT8 *)&IPTmp, 4 );
// Patch the next hop destination
WrNet32( &pIpHdr->dwIPDst, IPDst );
// Bump the offset
pIpHdr->Options[OptIdx+2] += sizeof(IPN);
// Set Source Routing
SrcRoute = 1;
// The packet is now "from" us (local IF)
// This suspends normal error checks for looping packets
PktSetIFRx( hPkt, 0 );
break;
}
}
}
//
// If we have a filtered NET, then a packet from outside the
// filtered net can not enter the filtered net
//
if( IP_FILTERENABLE && _IPFltMask )
{
// If the destination is in the protected net and the source
// is not, drop the packet.
if( ( IPDst & _IPFltMask ) == _IPFltAddr &&
( IPSrc & _IPFltMask ) != _IPFltAddr )
{
ips.dwFiltered++;
PktFree( hPkt );
return;
}
}
//
// If not source routing, see if the packet is for us.
//
if( !SrcRoute )
{
// We take the following packets:
// - The Dst is an all 0's BCast
// - The Dst is an all 1's BCast
// - The Dst is a Multicast Addr
// - The Dst is one of our host addresses
// - Sent directly to a non-configured IF
if( IPDst == INADDR_ANY || IPDst == INADDR_BROADCAST ||
IN_MULTICAST(IPDst) || BindFindByHost( 0, IPDst ) ||
( !(PktFlags & (FLG_PKT_MACMCAST|FLG_PKT_MACBCAST)) &&
hIFRx && !BindFindByIF( hIFRx ) ) )
{
// The packet is for us!!!
//
// First we must reassemble any fragmented packets
//
if( pIpHdr->FlagOff & ~HNC16(IP_DF) )
{
// Packet is fragmented
//
// We pass the packet to the IPReasm function, which
// consumes the packet. When a packet is ready, it is
// resubmitted to IpRxPacket
//
IPReasm( hPkt, hFrag, pIpHdr );
return;
}
#ifdef _INCLUDE_NAT_CODE
if( IP_NATENABLE )
{
// NAT Processing for Received Packets
NatRC = NatIpRxInput( hPkt, pIpHdr );
if( NatRC > 0 )
goto forward_post_nat;
if( NatRC < 0 )
return;
}
#endif
// Track packets we deliver to upper layers
ips.dwDelivered++;
// Dispatch the IP packet
switch( pIpHdr->Protocol )
{
case IPPROTO_ICMP:
ICMPInput( hPkt );
break;
case IPPROTO_TCP:
TcpInput( hPkt );
break;
case IPPROTO_UDP:
UdpInput( hPkt );
break;
case 2: //IGMP
default:
ips.dwDelivered--;
ips.dwNoproto++;
RawInput( hPkt );
break;
}
return;
}
}
// If we get here, the packet is not for us
// Verify Packet can be forwarded
// We can not foward ...
// - if the packet was rx'd on a local IF AND we're not source
// routing (this is loop caused by a bad route configuration)
// - if forwarding disabled
// - if addressed to an experimental, multicast, or loopback IP
// - if mac addr received on was broadcast
if( (!hIFRx && !SrcRoute) || !IP_FORWARDING ||
IPDst == INADDR_ANY || IPDst == INADDR_BROADCAST ||
IN_EXPERIMENTAL(IPDst) || IN_MULTICAST(IPDst) ||
IN_LOOPBACK(IPDst) || (PktFlags & FLG_PKT_MACBCAST) )
{
ips.dwCantforwardBA++;
PktFree( hPkt );
return;
}
//
// Forward Packet
//
// Process Time to Live
w = pIpHdr->Ttl;
if( w < 2 )
{
ips.dwExpired++;
ICMPGenPacket( pIpHdr, hIFRx, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0 );
PktFree( hPkt );
return;
}
pIpHdr->Ttl = (UINT8)(w-1);
#ifdef _INCLUDE_NAT_CODE
// NAT Processing for Transmitted Packets
if( IP_NATENABLE && NatIpTxInput( hPkt, pIpHdr ) )
return;
forward_post_nat:
#endif
// Set the IPTx Flags
// Send the packet
if( SrcRoute )
IPTxPacket( hPkt, FLG_IPTX_FORWARDING|FLG_IPTX_SRCROUTE );
else
IPTxPacket( hPkt, FLG_IPTX_FORWARDING );
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -