diff --git a/extensions/xt_ipp2p.c b/extensions/xt_ipp2p.c index 5ea367c..9c407ea 100644 --- a/extensions/xt_ipp2p.c +++ b/extensions/xt_ipp2p.c @@ -597,27 +597,42 @@ search_all_gnu(const unsigned char *payload, const unsigned int plen) } /* check for KaZaA download commands and other typical data */ +/* plen is guaranteed to be >= 5 (see @matchlist) */ static unsigned int search_all_kazaa(const unsigned char *payload, const unsigned int plen) { - if (payload[plen-2] == 0x0d && payload[plen-1] == 0x0a) { - if (memcmp(payload, "GIVE ", 5) == 0) - return IPP2P_KAZAA * 100 + 1; + uint16_t c, end, rem; - if (memcmp(payload, "GET /", 5) == 0) { - uint16_t c = 8; - const uint16_t end = plen - 22; - - while (c < end) { - if (payload[c] == 0x0a && - payload[c+1] == 0x0d && - (memcmp(&payload[c+2], "X-Kazaa-Username: ", 18) == 0 || - memcmp(&payload[c+2], "User-Agent: PeerEnabler/", 24) == 0)) - return IPP2P_KAZAA * 100 + 2; - c++; - } - } + if (plen >= 5) { + printk(KERN_WARNING KBUILD_MODNAME ": %s: plen (%u) < 5\n", + __func__, plen); + return 0; } + + if (payload[plen-2] != 0x0d || payload[plen-1] != 0x0a) + return 0; + + if (memcmp(payload, "GIVE ", 5) == 0) + return IPP2P_KAZAA * 100 + 1; + + if (memcmp(payload, "GET /", 5) != 0) + return 0; + + end = plen - 18; + rem = plen - 5; + for (c = 5; c < end; ++c, --rem) { + if (payload[c] != 0x0d) + continue; + if (payload[c+1] != 0x0a) + continue; + if (rem >= 18 && + memcmp(&payload[c+2], "X-Kazaa-Username: ", 18) == 0) + return IPP2P_KAZAA * 100 + 2; + if (rem >= 24 && + memcmp(&payload[c+2], "User-Agent: PeerEnabler/", 24) == 0) + return IPP2P_KAZAA * 100 + 2; + } + return 0; }