@ -77,35 +77,34 @@ namespace llarp
}
static std : : map <
byte_t , std : : function < void ( const ip_header * , byte_t * , size_t ) > >
byte_t ,
std : : function < void ( const ip_header * ohdr , byte_t * pld , size_t psz ,
huint32_t oSrcIP , huint32_t oDstIP ,
huint32_t nSrcIP , huint32_t nDstIP ) > >
protoDstCheckSummer = {
// {RFC3022} says that IPv4 hdr isn't included in ICMP checksum calc
// and that we don't need to modify it
{ // TCP
6 ,
[ ] ( const ip_header * hdr , byte_t * pkt , size_t sz ) {
auto hlen = size_t ( hdr - > ihl * 4 ) ;
[ ] ( const ip_header * ohdr , byte_t * pld , size_t psz ,
huint32_t oSrcIP , huint32_t oDstIP , huint32_t nSrcIP ,
huint32_t nDstIP ) {
uint16_t * check = ( uint16_t * ) ( pld + 16 ) ;
uint16_t * check = ( uint16_t * ) ( pkt + hlen + 16 ) ;
* check = deltachksum ( * check , huint32_t { 0 } , huint32_t { 0 } ,
xntohl ( nuint32_t { hdr - > saddr } ) ,
xntohl ( nuint32_t { hdr - > daddr } ) ) ;
* check = deltachksum ( * check , oSrcIP , oDstIP , nSrcIP , nDstIP ) ;
} } ,
{ // UDP
17 ,
[ ] ( const ip_header * hdr, byte_t * pkt , size_t sz ) {
auto hlen = size_t ( hdr - > ihl * 4 ) ;
uint16_t * check = ( uint16_t * ) ( p kt + hlen + 6 ) ;
[ ] ( const ip_header * ohdr , byte_t * pld , size_t psz ,
huint32_t oSrcIP , huint32_t oDstIP , huint32_t nSrcIP ,
huint32_t nDstIP ) {
uint16_t * check = ( uint16_t * ) ( p ld + 6 ) ;
if ( * check ! = 0xFFff )
{
if ( * check = = 0x0000 )
return ; // don't change zero
* check = deltachksum ( * check , huint32_t { 0 } , huint32_t { 0 } ,
xntohl ( nuint32_t { hdr - > saddr } ) ,
xntohl ( nuint32_t { hdr - > daddr } ) ) ;
* check = deltachksum ( * check , oSrcIP , oDstIP , nSrcIP , nDstIP ) ;
if ( * check = = 0x0000 )
* check = 0xFFff ;
}
@ -113,83 +112,83 @@ namespace llarp
{
// such checksum can mean 2 things: 0x0000 or 0xFFff
// we can only know by looking at data :<
if ( hlen > sz )
return ; // malformed, bail out
auto oldcs = * check ;
auto pakcs = * check ; // save
* check = 0 ; // zero checksum before calculation
auto cs =
ipchksum( pkt + hlen , sz - hlen ,
ipchksum_pseudoIPv4 ( nuint32_t { 0 } , nuint32_t { 0 } ,
17 , sz - hlen ) ) ;
auto cs = ipchksum (
pld, psz ,
ipchksum_pseudoIPv4 ( nuint32_t { ohdr - > saddr } ,
nuint32_t { ohdr - > daddr } , 17 , psz ) ) ;
auto mod_cs = deltachksum ( cs , huint32_t { 0 } , huint32_t { 0 } ,
xntohl ( nuint32_t { hdr - > saddr } ) ,
xntohl ( nuint32_t { hdr - > daddr } ) ) ;
auto new_cs = deltachksum ( cs , oSrcIP , oDstIP , nSrcIP , nDstIP ) ;
if ( cs ! = 0x0000 & & cs ! = 0xFFff )
{
// packet was bad - sabotage new checksum
mod_cs + = cs - old cs;
new_cs + = pakcs - cs;
}
// 0x0000 is reserved for no checksum
if ( mod _cs = = 0x0000 )
mod _cs = 0xFFff ;
if ( new _cs = = 0x0000 )
new _cs = 0xFFff ;
// put it in
* check = mod _cs;
* check = new _cs;
}
} } ,
} ;
void
IPv4Packet : : Update ChecksumsOnDst( )
IPv4Packet : : Update PacketOnDst( huint32_t nSrcIP , huint32_t nDstIP )
{
auto hdr = Header ( ) ;
auto oSrcIP = xntohl ( nuint32_t { hdr - > saddr } ) ;
auto oDstIP = xntohl ( nuint32_t { hdr - > daddr } ) ;
// IPv4 checksum
hdr - > check = deltachksum ( hdr - > check , huint32_t { 0 } , huint32_t { 0 } ,
xntohl ( nuint32_t { hdr - > saddr } ) ,
xntohl ( nuint32_t { hdr - > daddr } ) ) ;
hdr - > check = deltachksum ( hdr - > check , oSrcIP , oDstIP , nSrcIP , nDstIP ) ;
// L4 checksum
auto proto = hdr - > protocol ;
auto itr = protoDstCheckSummer . find ( proto ) ;
if ( itr ! = protoDstCheckSummer . end ( ) )
size_t ihs ;
if ( itr ! = protoDstCheckSummer . end ( ) & & ( ihs = size_t ( hdr - > ihl * 4 ) ) < = sz )
{
itr - > second ( hdr , buf , sz ) ;
itr - > second ( hdr , buf + ihs , sz - ihs , oSrcIP , oDstIP , nSrcIP , nDstIP ) ;
}
// write new IP addresses
hdr - > saddr = xhtonl ( nSrcIP ) . n ;
hdr - > daddr = xhtonl ( nDstIP ) . n ;
}
static std : : map <
byte_t , std : : function < void ( const ip_header * , byte_t * , size_t ) > >
byte_t ,
std : : function < void ( const ip_header * ohdr , byte_t * pld , size_t psz ,
huint32_t oSrcIP , huint32_t oDstIP ) > >
protoSrcCheckSummer = {
{ // TCP
6 ,
[ ] ( const ip_header * hdr , byte_t * pkt , size_t sz ) {
auto hlen = size_t ( hdr - > ihl * 4 ) ;
[ ] ( const ip_header * ohdr , byte_t * pld , size_t psz ,
huint32_t oSrcIP , huint32_t oDstIP ) {
uint16_t * check = ( uint16_t * ) ( pld + 16 ) ;
uint16_t * check = ( uint16_t * ) ( pkt + hlen + 16 ) ;
* check = deltachksum ( * check , xntohl ( nuint32_t { hdr - > saddr } ) ,
xntohl ( nuint32_t { hdr - > daddr } ) , huint32_t { 0 } ,
* check = deltachksum ( * check , oSrcIP , oDstIP , huint32_t { 0 } ,
huint32_t { 0 } ) ;
} } ,
{ // UDP
17 ,
[ ] ( const ip_header * hdr , byte_t * pkt , size_t sz ) {
auto hlen = size_t ( hdr - > ihl * 4 ) ;
uint16_t * check = ( uint16_t * ) ( pkt + hlen + 6 ) ;
[ ] ( const ip_header * ohdr , byte_t * pld , size_t psz ,
huint32_t oSrcIP , huint32_t oDstIP ) {
uint16_t * check = ( uint16_t * ) ( pld + 6 ) ;
if ( * check ! = 0xFFff )
{
if ( * check = = 0x0000 )
return ; // don't change zero
* check = deltachksum ( * check , xntohl ( nuint32_t { hdr - > saddr } ) ,
xntohl ( nuint32_t { hdr - > daddr } ) ,
huint32_t { 0 } , huint32_t { 0 } ) ;
* check = deltachksum ( * check , oSrcIP , oDstIP , huint32_t { 0 } ,
huint32_t { 0 } ) ;
if ( * check = = 0x0000 )
* check = 0xFFff ;
}
@ -197,52 +196,56 @@ namespace llarp
{
// such checksum can mean 2 things: 0x0000 or 0xFFff
// we can only know by looking at data :<
if ( hlen > sz )
return ; // malformed, bail out
auto oldcs = * check ;
auto pakcs = * check ; // save
* check = 0 ; // zero checksum before calculation
auto cs = ipchksum (
p kt + hlen , sz - hlen ,
ipchksum_pseudoIPv4 ( nuint32_t { hdr- > saddr } ,
nuint32_t { hdr- > daddr } , 17 , sz - hlen ) ) ;
p ld, psz ,
ipchksum_pseudoIPv4 ( nuint32_t { o hdr- > saddr } ,
nuint32_t { o hdr- > daddr } , 17 , p sz) ) ;
auto mod_cs = deltachksum ( cs , xntohl ( nuint32_t { hdr - > saddr } ) ,
xntohl ( nuint32_t { hdr - > daddr } ) ,
huint32_t { 0 } , huint32_t { 0 } ) ;
auto new_cs = deltachksum ( cs , oSrcIP , oDstIP , huint32_t { 0 } ,
huint32_t { 0 } ) ;
if ( cs ! = 0x0000 & & cs ! = 0xFFff )
{
// packet was bad - sabotage new checksum
mod_cs + = cs - old cs;
new_cs + = pakcs - cs;
}
// 0x0000 is reserved for no checksum
if ( mod _cs = = 0x0000 )
mod _cs = 0xFFff ;
if ( new _cs = = 0x0000 )
new _cs = 0xFFff ;
// put it in
* check = mod _cs;
* check = new _cs;
}
} } ,
} ;
void
IPv4Packet : : Update Checksums OnSrc( )
IPv4Packet : : Update Packet OnSrc( )
{
auto hdr = Header ( ) ;
auto oSrcIP = xntohl ( nuint32_t { hdr - > saddr } ) ;
auto oDstIP = xntohl ( nuint32_t { hdr - > daddr } ) ;
// L4
auto proto = hdr - > protocol ;
auto itr = protoSrcCheckSummer . find ( proto ) ;
if ( itr ! = protoSrcCheckSummer . end ( ) )
size_t ihs ;
if ( itr ! = protoSrcCheckSummer . end ( ) & & ( ihs = size_t ( hdr - > ihl * 4 ) ) < = sz )
{
itr - > second ( hdr , buf , sz ) ;
itr - > second ( hdr , buf + ihs , sz - ihs , oSrcIP , oDstIP ) ;
}
// IPv4
hdr - > check = deltachksum ( hdr - > check , xntohl ( nuint32_t { hdr - > saddr } ) ,
xntohl ( nuint32_t { hdr - > daddr } ) , huint32_t { 0 } ,
huint32_t { 0 } ) ;
hdr - > check =
deltachksum ( hdr - > check , oSrcIP , oDstIP , huint32_t { 0 } , huint32_t { 0 } ) ;
// clear addresses
hdr - > saddr = 0 ;
hdr - > daddr = 0 ;
}
} // namespace net
} // namespace llarp