U2PseudoHeader::U2PseudoHeader(const Packet* p)
{
assert(p->flow);
-
+
if ( p->flow->key->version == 0x4 )
{
cook_eth(p, u.v4.eth);
cook_ip4(p, u.v4.ip4);
- cook_tcp(p, u.v4.tcp);
+ memset(&(u.v4.proto), 0, sizeof(u.v4.proto));
+ if (p->ip_proto_next == IpProtocol::UDP)
+ cook_udp(p, u.v4.proto.udp);
+ else
+ cook_tcp(p, u.v4.proto.tcp);
+
size = sizeof(u.v4) - offset;
}
else if ( p->flow->key->version == 0x6 )
{
cook_eth(p, u.v6.eth);
cook_ip6(p, u.v6.ip6);
- cook_tcp(p, u.v6.tcp);
+ memset(&(u.v6.proto), 0, sizeof(u.v6.proto));
+
+ if (p->ip_proto_next == IpProtocol::UDP)
+ cook_udp(p, u.v6.proto.udp);
+ else
+ cook_tcp(p, u.v6.proto.tcp);
+
size = sizeof(u.v6) - offset;
}
else size = 0;
void U2PseudoHeader::cook_ip4(const Packet* p, ip::IP4Hdr& h)
{
- const uint16_t overhead = sizeof(h) + sizeof(tcp::TCPHdr);
+ const uint16_t overhead = (p->ip_proto_next == IpProtocol::UDP) ?
+ (sizeof(h) + sizeof(udp::UDPHdr)) : (sizeof(h) + sizeof(tcp::TCPHdr));
+
const uint16_t max_data = IP_MAXPACKET - overhead;
dsize = p->dsize;
h.ip_verhl = 0x45;
h.ip_len = htons(overhead + dsize);
- h.ip_proto = IpProtocol::TCP;
+
+ if (p->ip_proto_next == IpProtocol::UDP)
+ h.ip_proto = IpProtocol::UDP;
+ else
+ h.ip_proto = IpProtocol::TCP;
+
h.ip_ttl = u2_ttl;
if (p->is_from_client())
void U2PseudoHeader::cook_ip6(const Packet* p, ip::IP6Hdr& h)
{
- const uint16_t overhead = sizeof(tcp::TCPHdr);
+ const uint16_t overhead = (p->ip_proto_next == IpProtocol::UDP) ?
+ sizeof(udp::UDPHdr) : sizeof(tcp::TCPHdr);
+
const uint16_t max_data = IP_MAXPACKET - overhead;
dsize = p->dsize;
h.ip6_vtf = htonl(0x60 << 24);
h.ip6_payload_len = htons(overhead + dsize);
- h.ip6_next = IpProtocol::TCP;
+
+ if (p->ip_proto_next == IpProtocol::UDP)
+ h.ip6_next = IpProtocol::UDP;
+ else
+ h.ip6_next = IpProtocol::TCP;
+
h.ip6_hoplim = u2_ttl;
if (p->is_from_client())
}
}
+void U2PseudoHeader::cook_udp(const Packet* p, udp::UDPHdr& h)
+{
+ h.uh_sport = htons(p->ptrs.sp);
+ h.uh_dport = htons(p->ptrs.dp);
+ h.uh_len = 0;
+ h.uh_len = htons(sizeof(h) + p->dsize);
+}
+
void U2PseudoHeader::cook_tcp(const Packet* p, tcp::TCPHdr& h)
{
h.th_sport = htons(p->ptrs.sp);
#include "protocols/ipv4.h"
#include "protocols/ipv6.h"
#include "protocols/tcp.h"
+#include "protocols/udp.h"
#include "main/snort_types.h"
void cook_ip4(const Packet*, ip::IP4Hdr&);
void cook_ip6(const Packet*, ip::IP6Hdr&);
void cook_tcp(const Packet*, tcp::TCPHdr&);
+ void cook_udp(const Packet*, udp::UDPHdr&);
static const unsigned offset = 2;
static const unsigned max_size =
uint8_t align[offset];
eth::EtherHdr eth;
ip::IP4Hdr ip4;
- tcp::TCPHdr tcp;
+ union
+ {
+ tcp::TCPHdr tcp;
+ udp::UDPHdr udp;
+ } proto;
} v4;
struct
uint8_t align[offset];
eth::EtherHdr eth;
ip::IP6Hdr ip6;
- tcp::TCPHdr tcp;
+ union
+ {
+ tcp::TCPHdr tcp;
+ udp::UDPHdr udp;
+ } proto;
} v6;
uint8_t buf[max_size];