Merge remote-tracking branch 'cathugger/master'

pull/31/head
Jeff Becker 6 years ago
commit 8bf28940d1
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -155,7 +155,7 @@ namespace llarp
// update ip packet (after packet gets out of network) // update ip packet (after packet gets out of network)
void void
UpdatePacketOnDst(huint32_t nsrcIP, huint32_t ndstIP); UpdatePacketOnDst(huint32_t nSrcIP, huint32_t nDstIP);
// update ip packet (before packet gets inserted into network) // update ip packet (before packet gets inserted into network)
void void

@ -57,18 +57,23 @@ namespace llarp
{ {
uint32_t h; uint32_t h;
constexpr huint32_t operator &(huint32_t x) const { return huint32_t{h & x.h}; } constexpr huint32_t
constexpr huint32_t operator |(huint32_t x) const { return huint32_t{h | x.h}; } operator &(huint32_t x) const { return huint32_t{uint32_t(h & x.h)}; }
constexpr huint32_t operator ~() const { return huint32_t{~h}; } constexpr huint32_t
operator |(huint32_t x) const { return huint32_t{uint32_t(h | x.h)}; }
constexpr huint32_t
operator ~() const { return huint32_t{uint32_t(~h)}; }
inline huint32_t operator ++() { ++h; return *this; } inline huint32_t operator ++() { ++h; return *this; }
inline huint32_t operator --() { --h; return *this; } inline huint32_t operator --() { --h; return *this; }
constexpr bool operator <(huint32_t x) const { return h < x.h; } constexpr bool operator <(huint32_t x) const { return h < x.h; }
constexpr bool operator ==(huint32_t x) const { return h == x.h; } constexpr bool operator ==(huint32_t x) const { return h == x.h; }
struct Hash struct Hash
{ {
inline size_t inline size_t
operator()(huint32_t x) const operator ()(huint32_t x) const
{ {
return std::hash< uint32_t >{}(x.h); return std::hash< uint32_t >{}(x.h);
} }
@ -79,36 +84,107 @@ namespace llarp
{ {
uint32_t n; uint32_t n;
constexpr nuint32_t operator &(nuint32_t x) const { return nuint32_t{n & x.n}; } constexpr nuint32_t
constexpr nuint32_t operator |(nuint32_t x) const { return nuint32_t{n | x.n}; } operator &(nuint32_t x) const { return nuint32_t{uint32_t(n & x.n)}; }
constexpr nuint32_t operator ~() const { return nuint32_t{~n}; } constexpr nuint32_t
operator |(nuint32_t x) const { return nuint32_t{uint32_t(n | x.n)}; }
constexpr nuint32_t
operator ~() const { return nuint32_t{uint32_t(~n)}; }
inline nuint32_t operator ++() { ++n; return *this; } inline nuint32_t operator ++() { ++n; return *this; }
inline nuint32_t operator --() { --n; return *this; } inline nuint32_t operator --() { --n; return *this; }
constexpr bool operator <(nuint32_t x) const { return n < x.n; } constexpr bool operator <(nuint32_t x) const { return n < x.n; }
constexpr bool operator ==(nuint32_t x) const { return n == x.n; } constexpr bool operator ==(nuint32_t x) const { return n == x.n; }
struct Hash struct Hash
{ {
inline size_t inline size_t
operator()(nuint32_t x) const operator ()(nuint32_t x) const
{ {
return std::hash< uint32_t >{}(x.n); return std::hash< uint32_t >{}(x.n);
} }
}; };
}; };
struct huint16_t
{
uint16_t h;
constexpr huint16_t
operator &(huint16_t x) const { return huint16_t{uint16_t(h & x.h)}; }
constexpr huint16_t
operator |(huint16_t x) const { return huint16_t{uint16_t(h | x.h)}; }
constexpr huint16_t
operator ~() const { return huint16_t{uint16_t(~h)}; }
inline huint16_t operator ++() { ++h; return *this; }
inline huint16_t operator --() { --h; return *this; }
constexpr bool operator <(huint16_t x) const { return h < x.h; }
constexpr bool operator ==(huint16_t x) const { return h == x.h; }
struct Hash
{
inline size_t
operator ()(huint16_t x) const
{
return std::hash< uint16_t >{}(x.h);
}
};
};
struct nuint16_t
{
uint16_t n;
constexpr nuint16_t
operator &(nuint16_t x) const { return nuint16_t{uint16_t(n & x.n)}; }
constexpr nuint16_t
operator |(nuint16_t x) const { return nuint16_t{uint16_t(n | x.n)}; }
constexpr nuint16_t
operator ~() const { return nuint16_t{uint16_t(~n)}; }
inline nuint16_t operator ++() { ++n; return *this; }
inline nuint16_t operator --() { --n; return *this; }
constexpr bool operator <(nuint16_t x) const { return n < x.n; }
constexpr bool operator ==(nuint16_t x) const { return n == x.n; }
struct Hash
{
inline size_t
operator ()(nuint16_t x) const
{
return std::hash< uint16_t >{}(x.n);
}
};
};
// clang-format on // clang-format on
static inline nuint32_t
xhtonl(huint32_t x)
{
return nuint32_t{htonl(x.h)};
}
static inline huint32_t static inline huint32_t
xntohl(nuint32_t x) xntohl(nuint32_t x)
{ {
return huint32_t{ntohl(x.n)}; return huint32_t{ntohl(x.n)};
} }
static inline nuint32_t static inline nuint16_t
xhtonl(huint32_t x) xhtons(huint16_t x)
{ {
return nuint32_t{htonl(x.h)}; return nuint16_t{htons(x.h)};
}
static inline huint16_t
xntohs(nuint16_t x)
{
return huint16_t{ntohs(x.n)};
} }
struct Addr struct Addr

@ -76,68 +76,59 @@ namespace llarp
return htons(sum); return htons(sum);
} }
static std::map< static void
byte_t, checksumDstTCP(byte_t *pld, size_t psz, huint32_t oSrcIP, huint32_t oDstIP,
std::function< void(const ip_header *ohdr, byte_t *pld, size_t psz, huint32_t nSrcIP, huint32_t nDstIP)
huint32_t oSrcIP, huint32_t oDstIP, {
huint32_t nSrcIP, huint32_t nDstIP) > > uint16_t *check = (uint16_t *)(pld + 16);
protoDstCheckSummer = {
// {RFC3022} says that IPv4 hdr isn't included in ICMP checksum calc *check = deltachksum(*check, oSrcIP, oDstIP, nSrcIP, nDstIP);
// and that we don't need to modify it }
{// TCP
6, static void
[](const ip_header *ohdr, byte_t *pld, size_t psz, checksumDstUDP(const ip_header *ohdr, byte_t *pld, size_t psz,
huint32_t oSrcIP, huint32_t oDstIP, huint32_t nSrcIP, huint32_t oSrcIP, huint32_t oDstIP, huint32_t nSrcIP,
huint32_t nDstIP) { huint32_t nDstIP)
uint16_t *check = (uint16_t *)(pld + 16); {
uint16_t *check = (uint16_t *)(pld + 6);
*check = deltachksum(*check, oSrcIP, oDstIP, nSrcIP, nDstIP); if(*check != 0xFFff)
}}, {
{// UDP if(*check == 0x0000)
17, return; // don't change zero
[](const ip_header *ohdr, byte_t *pld, size_t psz,
huint32_t oSrcIP, huint32_t oDstIP, huint32_t nSrcIP, *check = deltachksum(*check, oSrcIP, oDstIP, nSrcIP, nDstIP);
huint32_t nDstIP) { if(*check == 0x0000)
uint16_t *check = (uint16_t *)(pld + 6); *check = 0xFFff;
if(*check != 0xFFff) }
{ else
if(*check == 0x0000) {
return; // don't change zero // such checksum can mean 2 things: 0x0000 or 0xFFff
// we can only know by looking at data :<
*check = deltachksum(*check, oSrcIP, oDstIP, nSrcIP, nDstIP);
if(*check == 0x0000) auto pakcs = *check; // save
*check = 0xFFff;
} *check = 0; // zero checksum before calculation
else
{ auto cs =
// such checksum can mean 2 things: 0x0000 or 0xFFff ipchksum(pld, psz,
// we can only know by looking at data :<
auto pakcs = *check; // save
*check = 0; // zero checksum before calculation
auto cs = ipchksum(
pld, psz,
ipchksum_pseudoIPv4(nuint32_t{ohdr->saddr}, ipchksum_pseudoIPv4(nuint32_t{ohdr->saddr},
nuint32_t{ohdr->daddr}, 17, psz)); nuint32_t{ohdr->daddr}, 17, psz));
auto new_cs = deltachksum(cs, oSrcIP, oDstIP, nSrcIP, nDstIP); auto new_cs = deltachksum(cs, oSrcIP, oDstIP, nSrcIP, nDstIP);
if(cs != 0x0000 && cs != 0xFFff) if(cs != 0x0000 && cs != 0xFFff)
{ {
// packet was bad - sabotage new checksum // packet was bad - sabotage new checksum
new_cs += pakcs - cs; new_cs += pakcs - cs;
} }
// 0x0000 is reserved for no checksum // 0x0000 is reserved for no checksum
if(new_cs == 0x0000) if(new_cs == 0x0000)
new_cs = 0xFFff; new_cs = 0xFFff;
// put it in // put it in
*check = new_cs; *check = new_cs;
} }
}}, }
};
void void
IPv4Packet::UpdatePacketOnDst(huint32_t nSrcIP, huint32_t nDstIP) IPv4Packet::UpdatePacketOnDst(huint32_t nSrcIP, huint32_t nDstIP)
{ {
@ -151,11 +142,17 @@ namespace llarp
// L4 checksum // L4 checksum
auto proto = hdr->protocol; auto proto = hdr->protocol;
auto itr = protoDstCheckSummer.find(proto); auto ihs = size_t(hdr->ihl * 4);
size_t ihs; auto pld = buf + ihs;
if(itr != protoDstCheckSummer.end() && (ihs = size_t(hdr->ihl * 4)) <= sz) auto psz = sz - ihs;
switch(proto)
{ {
itr->second(hdr, buf + ihs, sz - ihs, oSrcIP, oDstIP, nSrcIP, nDstIP); case 6:
checksumDstTCP(pld, psz, oSrcIP, oDstIP, nSrcIP, nDstIP);
break;
case 17:
checksumDstUDP(hdr, pld, psz, oSrcIP, oDstIP, nSrcIP, nDstIP);
break;
} }
// write new IP addresses // write new IP addresses
@ -163,65 +160,59 @@ namespace llarp
hdr->daddr = xhtonl(nDstIP).n; hdr->daddr = xhtonl(nDstIP).n;
} }
static std::map< static void
byte_t, checksumSrcTCP(byte_t *pld, size_t psz, huint32_t oSrcIP, huint32_t oDstIP)
std::function< void(const ip_header *ohdr, byte_t *pld, size_t psz, {
huint32_t oSrcIP, huint32_t oDstIP) > > uint16_t *check = (uint16_t *)(pld + 16);
protoSrcCheckSummer = {
{// TCP *check = deltachksum(*check, oSrcIP, oDstIP, huint32_t{0}, huint32_t{0});
6, }
[](const ip_header *ohdr, byte_t *pld, size_t psz,
huint32_t oSrcIP, huint32_t oDstIP) { static void
uint16_t *check = (uint16_t *)(pld + 16); checksumSrcUDP(const ip_header *ohdr, byte_t *pld, size_t psz,
huint32_t oSrcIP, huint32_t oDstIP)
*check = deltachksum(*check, oSrcIP, oDstIP, huint32_t{0}, {
huint32_t{0}); uint16_t *check = (uint16_t *)(pld + 6);
}}, if(*check != 0xFFff)
{// UDP {
17, if(*check == 0x0000)
[](const ip_header *ohdr, byte_t *pld, size_t psz, return; // don't change zero
huint32_t oSrcIP, huint32_t oDstIP) {
uint16_t *check = (uint16_t *)(pld + 6); *check =
if(*check != 0xFFff) deltachksum(*check, oSrcIP, oDstIP, huint32_t{0}, huint32_t{0});
{ if(*check == 0x0000)
if(*check == 0x0000) *check = 0xFFff;
return; // don't change zero }
else
*check = deltachksum(*check, oSrcIP, oDstIP, huint32_t{0}, {
huint32_t{0}); // such checksum can mean 2 things: 0x0000 or 0xFFff
if(*check == 0x0000) // we can only know by looking at data :<
*check = 0xFFff;
} auto pakcs = *check; // save
else
{ *check = 0; // zero checksum before calculation
// such checksum can mean 2 things: 0x0000 or 0xFFff
// we can only know by looking at data :< auto cs =
ipchksum(pld, psz,
auto pakcs = *check; // save
*check = 0; // zero checksum before calculation
auto cs = ipchksum(
pld, psz,
ipchksum_pseudoIPv4(nuint32_t{ohdr->saddr}, ipchksum_pseudoIPv4(nuint32_t{ohdr->saddr},
nuint32_t{ohdr->daddr}, 17, psz)); nuint32_t{ohdr->daddr}, 17, psz));
auto new_cs = deltachksum(cs, oSrcIP, oDstIP, huint32_t{0}, auto new_cs =
huint32_t{0}); deltachksum(cs, oSrcIP, oDstIP, huint32_t{0}, huint32_t{0});
if(cs != 0x0000 && cs != 0xFFff) if(cs != 0x0000 && cs != 0xFFff)
{ {
// packet was bad - sabotage new checksum // packet was bad - sabotage new checksum
new_cs += pakcs - cs; new_cs += pakcs - cs;
} }
// 0x0000 is reserved for no checksum // 0x0000 is reserved for no checksum
if(new_cs == 0x0000) if(new_cs == 0x0000)
new_cs = 0xFFff; new_cs = 0xFFff;
// put it in // put it in
*check = new_cs; *check = new_cs;
} }
}}, }
};
void void
IPv4Packet::UpdatePacketOnSrc() IPv4Packet::UpdatePacketOnSrc()
{ {
@ -232,11 +223,17 @@ namespace llarp
// L4 // L4
auto proto = hdr->protocol; auto proto = hdr->protocol;
auto itr = protoSrcCheckSummer.find(proto); auto ihs = size_t(hdr->ihl * 4);
size_t ihs; auto pld = buf + ihs;
if(itr != protoSrcCheckSummer.end() && (ihs = size_t(hdr->ihl * 4)) <= sz) auto psz = sz - ihs;
switch(proto)
{ {
itr->second(hdr, buf + ihs, sz - ihs, oSrcIP, oDstIP); case 6:
checksumSrcTCP(pld, psz, oSrcIP, oDstIP);
break;
case 17:
checksumSrcUDP(hdr, pld, psz, oSrcIP, oDstIP);
break;
} }
// IPv4 // IPv4

Loading…
Cancel
Save