diff --git a/src/decode.h b/src/decode.h index 9981517d25..ceff23f4d9 100644 --- a/src/decode.h +++ b/src/decode.h @@ -421,6 +421,9 @@ typedef struct Packet_ uint8_t *ext_pkt; uint32_t pktlen; + /* Incoming interface */ + struct LiveDevice_ *livedev; + PacketAlerts alerts; /** packet number in the pcap file, matches wireshark */ @@ -574,6 +577,7 @@ typedef struct DecodeThreadVars_ SCMutexInit(&(p)->tunnel_mutex, NULL); \ PACKET_RESET_CHECKSUMS((p)); \ (p)->pkt = ((uint8_t *)(p)) + sizeof(Packet); \ + (p)->livedev = NULL; \ } #else #define PACKET_INITIALIZE(p) { \ @@ -583,6 +587,7 @@ typedef struct DecodeThreadVars_ SCMutexInit(&(p)->cuda_mutex, NULL); \ SCCondInit(&(p)->cuda_cond, NULL); \ (p)->pkt = ((uint8_t *)(p)) + sizeof(Packet); \ + (p)->livedev = NULL; \ } #endif @@ -649,6 +654,7 @@ typedef struct DecodeThreadVars_ (p)->next = NULL; \ (p)->prev = NULL; \ (p)->root = NULL; \ + (p)->livedev = NULL; \ PACKET_RESET_CHECKSUMS((p)); \ PACKET_PROFILING_RESET((p)); \ } while (0) @@ -887,7 +893,7 @@ void AddressDebugPrint(Address *); #define PKT_TUNNEL 0x1000 #define PKT_TUNNEL_VERDICTED 0x2000 -#define PKT_IGNORE_CHECKSUM 0x4000 /**< Packet checksum is not computed (TX packet for example) */ +#define PKT_IGNORE_CHECKSUM 0x4000 /**< Packet checksum is not computed (TX packet for example) */ /** \brief return 1 if the packet is a pseudo packet */ #define PKT_IS_PSEUDOPKT(p) ((p)->flags & PKT_PSEUDO_STREAM_END) diff --git a/src/stream-tcp.c b/src/stream-tcp.c index 9894e584ef..42218ca6da 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -48,6 +48,7 @@ #include "util-unittest.h" #include "util-print.h" #include "util-debug.h" +#include "util-device.h" #include "stream-tcp-private.h" #include "stream-tcp-reassemble.h" @@ -3848,6 +3849,9 @@ static inline int StreamTcpValidateChecksum(Packet *p) if (p->tcpvars.comp_csum != p->tcph->th_sum) { ret = 0; SCLogDebug("Checksum of received packet %p is invalid",p); + if (p->livedev) { + SC_ATOMIC_ADD(p->livedev->invalid_checksums, 1); + } } return ret; diff --git a/src/util-checksum.c b/src/util-checksum.c index 1fd5ca9c0b..d08d2058d4 100644 --- a/src/util-checksum.c +++ b/src/util-checksum.c @@ -25,6 +25,8 @@ #include "suricata-common.h" +#include "util-checksum.h" + int ReCalculateChecksum(Packet *p) { if (PKT_IS_IPV4(p)) { @@ -57,3 +59,27 @@ int ReCalculateChecksum(Packet *p) return 0; } + + +int ChecksumAutoModeCheck(uint32_t thread_count, + uint32_t iface_count, + uint32_t iface_fail) +{ + if (thread_count == CHECKSUM_SAMPLE_COUNT) { + if (iface_fail != 0) { + if ((iface_count / iface_fail) < CHECKSUM_INVALID_RATIO) { + SCLogInfo("More than 1/10 of invalid checksum, assuming checksum offloading is used (%d/%d)", + iface_fail, + iface_count); + return 1; + } else { + SCLogInfo("Less than 1/10 of invalid checksum, assuming checksum offloading is NOT used (%d/%d)", + iface_fail, + iface_count); + } + } else { + SCLogInfo("No packet with invalid checksum, assuming checksum offloading is NOT used"); + } + } + return 0; +} diff --git a/src/util-checksum.h b/src/util-checksum.h index 47815730d3..949b482bda 100644 --- a/src/util-checksum.h +++ b/src/util-checksum.h @@ -24,7 +24,14 @@ #ifndef __UTIL_CHECKSUM_H__ #define __UTIL_CHECKSUM_H__ - int ReCalculateChecksum(Packet *p); +int ChecksumAutoModeCheck(uint32_t thread_count, + uint32_t iface_count, + uint32_t iface_fail); + +/* constant linked with detection of interface with + * invalid checksums */ +#define CHECKSUM_SAMPLE_COUNT 1000 +#define CHECKSUM_INVALID_RATIO 5 #endif diff --git a/src/util-device.c b/src/util-device.c index 7549f3a89a..0397c1d741 100644 --- a/src/util-device.c +++ b/src/util-device.c @@ -48,6 +48,9 @@ int LiveRegisterDevice(char *dev) } pd->dev = SCStrdup(dev); + SC_ATOMIC_INIT(pd->pkts); + SC_ATOMIC_INIT(pd->invalid_checksums); + pd->ignore_checksum = 0; TAILQ_INSERT_TAIL(&live_devices, pd, next); SCLogDebug("Pcap device \"%s\" registered.", dev); diff --git a/src/util-device.h b/src/util-device.h index ce6997f3b9..f3f9019078 100644 --- a/src/util-device.h +++ b/src/util-device.h @@ -23,6 +23,9 @@ /** storage for live device names */ typedef struct LiveDevice_ { char *dev; /**< the device (e.g. "eth0") */ + int ignore_checksum; + SC_ATOMIC_DECLARE(uint32_t, pkts); + SC_ATOMIC_DECLARE(uint32_t, invalid_checksums); TAILQ_ENTRY(LiveDevice_) next; } LiveDevice;