#ifdef STATIC_CODECS
extern const BaseApi* cd_ah;
extern const BaseApi* cd_arp;
+extern const BaseApi* cd_capwap;
extern const BaseApi* cd_dstopts;
extern const BaseApi* cd_erspan2;
extern const BaseApi* cd_erspan3;
#ifdef STATIC_CODECS
cd_ah,
cd_arp,
+ cd_capwap,
cd_dstopts,
cd_erspan2,
cd_erspan3,
DECODE_AUTH_HDR_TRUNC,
DECODE_AUTH_HDR_BAD_LEN,
DECODE_TOO_MANY_LAYERS,
- DECODE_INDEX_MAX // = 468
+ DECODE_CAPWAP_TRUNC,
+ DECODE_INDEX_MAX // = 469
};
case icmp::IcmpType::PARAMETERPROB:
/* account for extra 4 bytes in header */
len += 4;
- codec.next_prot_id = IP_EMBEDDED_IN_ICMP4;
+ codec.next_prot_id = PROTO_IP_EMBEDDED_IN_ICMP4;
break;
default:
codec_events::decoder_event(codec, DECODE_ICMPV6_TOO_BIG_BAD_MTU);
len = icmp::ICMP6_HEADER_NORMAL_LEN;
- codec.next_prot_id = IP_EMBEDDED_IN_ICMP6;
+ codec.next_prot_id = PROTO_IP_EMBEDDED_IN_ICMP6;
}
else
{
codec_events::decoder_event(codec, DECODE_ICMPV6_UNREACHABLE_NON_RFC_4443_CODE);
}
len = icmp::ICMP6_HEADER_NORMAL_LEN;
- codec.next_prot_id = IP_EMBEDDED_IN_ICMP6;
+ codec.next_prot_id = PROTO_IP_EMBEDDED_IN_ICMP6;
}
else
{
{ "gtp_ports", Parameter::PT_BIT_LIST, "65535",
"2152 3386", "set GTP ports" },
+ { "capwap_ports", Parameter::PT_BIT_LIST, "65535",
+ "5246 5247", "customize capwap_ports" },
+
{ nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
};
}
}
}
+ else if ( v.is("capwap_ports") )
+ {
+ v.get_bits(*(sc->capwap_ports));
+ }
else
{
return false;
(ScIsGTPPort(src_port)||ScIsGTPPort(dst_port)))
{
if ( !(snort.decode_flags & DECODE_FRAG) )
- codec.next_prot_id = PROTOCOL_GTP;
+ codec.next_prot_id = PROTO_GTP;
}
else if (teredo::is_teredo_port(src_port) ||
teredo::is_teredo_port(dst_port) ||
ScDeepTeredoInspection())
{
- codec.next_prot_id = PROTOCOL_TEREDO;
+ codec.next_prot_id = PROTO_TEREDO;
+ }
+ else if (snort_conf->is_capwap_port(dst_port) ||
+ snort_conf->is_capwap_port(src_port))
+ {
+ codec.next_prot_id = PROTO_CAPWAP;
}
* http://www.geocities.com/billalexander/ethernet.html
*/
if(proto <= ETHERNET_MAX_LEN_ENCAP)
- codec.next_prot_id = ETHERNET_LLC;
+ codec.next_prot_id = PROTO_ETHERNET_LLC;
else
codec.next_prot_id = proto;
add_library( misc_codecs STATIC
cd_default.cc
+ cd_capwap.cc
${PLUGIN_LIST}
)
void GtpCodec::get_protocol_ids(std::vector<uint16_t>& v)
{
- v.push_back(PROTOCOL_GTP);
+ v.push_back(PROTO_GTP);
}
/* Function: DecodeGTP(uint8_t *, uint32_t, Packet *)
void Icmp4IpCodec::get_protocol_ids(std::vector<uint16_t>& v)
-{ v.push_back(IP_EMBEDDED_IN_ICMP4); }
+{ v.push_back(PROTO_IP_EMBEDDED_IN_ICMP4); }
bool Icmp4IpCodec::decode(const RawData& raw, CodecData& codec, DecodeData& snort)
{
} // namespace
void Icmp6IpCodec::get_protocol_ids(std::vector<uint16_t>& v)
-{ v.push_back(IP_EMBEDDED_IN_ICMP6); }
+{ v.push_back(PROTO_IP_EMBEDDED_IN_ICMP6); }
bool Icmp6IpCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
{
#include "log/text_log.h"
#include "protocols/packet_manager.h"
-// yes, macros are necessary. The API and class constructor require different strings.
-//
-// this macros is defined in the module to ensure identical names. However,
-// if you don't want a module, define the name here.
+
#define LLC_NAME "llc"
#define LLC_HELP "support for logical link control"
struct EthLlcOther
{
uint8_t org_code[3];
- uint16_t proto_id;
+ uint8_t proto_id[2];
+
+ uint16_t proto() const
+ { return ntohs(*((uint16_t*)(&proto_id[0]))); }
};
#define ETH_DSAP_SNA 0x08 /* SNA */
void LlcCodec::get_protocol_ids(std::vector<uint16_t>& v)
-{
- v.push_back(ETHERNET_LLC);
-}
+{ v.push_back(PROTO_ETHERNET_LLC); }
bool LlcCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
{
ehllcother->org_code[2] == 0)
{
codec.lyr_len = sizeof(EthLlc) + sizeof(EthLlcOther);
- codec.next_prot_id = ntohs(ehllcother->proto_id);
+ codec.next_prot_id = ehllcother->proto();
}
}
{
const EthLlcOther *other = reinterpret_cast<const EthLlcOther *>(raw_pkt + sizeof(EthLlc));
- const uint16_t proto = ntohs(other->proto_id);
+ const uint16_t proto = other->proto();
TextLog_Print(text_log, " ORG:0x%02X%02X%02X PROTO:0x%04X",
other->org_code[0], other->org_code[1], other->org_code[2],
#include "config.h"
#endif
-//#include "prot_ipv6.h"
-
#include "framework/codec.h"
#include "packet_io/active.h"
#include "snort_types.h"
void TeredoCodec::get_protocol_ids(std::vector<uint16_t>& v)
{
- v.push_back(PROTOCOL_TEREDO);
+ v.push_back(PROTO_TEREDO);
}
bool TeredoCodec::decode(const RawData& raw, CodecData& codec, DecodeData& snort)
void EthCodec::get_protocol_ids(std::vector<uint16_t>&v)
{
- v.push_back(ETHERNET_802_3);
+ v.push_back(PROTO_ETHERNET_802_3);
}
if (next_prot > eth::MIN_ETHERTYPE )
codec.proto_bits |= PROTO_BIT__ETH;
else
- next_prot = ETHERNET_LLC;
+ next_prot = PROTO_ETHERNET_LLC;
codec.next_prot_id = next_prot;
codec.lyr_len = eth::ETH_HEADER_LEN;
#include "main/snort.h"
#include "log/text_log.h"
+#ifndef DLT_IEEE802_11
+#define DLT_IEEE802_11 105
+#endif
+
#define CD_WLAN_NAME "wlan"
#define CD_WLAN_HELP_STR "support for wireless local area network protocol"
#define CD_WLAN_HELP ADD_DLT(CD_WLAN_HELP_STR, DLT_IEEE802_11)
bool decode(const RawData&, CodecData&, DecodeData&) override;
void get_data_link_type(std::vector<int>&) override;
+ void get_protocol_ids(std::vector<uint16_t>&v) override;
void log(TextLog* const, const uint8_t* /*raw_pkt*/,
const Packet* const) override;
};
void WlanCodec::get_data_link_type(std::vector<int>&v)
-{
-#ifdef DLT_IEEE802_11
- v.push_back(DLT_IEEE802_11);
-#endif
-}
+{ v.push_back(DLT_IEEE802_11); }
+
+void WlanCodec::get_protocol_ids(std::vector<uint16_t>&v)
+{ v.push_back(PROTO_ETHERNET_802_11); }
bool WlanCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
{
case WLAN_TYPE_DATA_DATA:
{
codec.lyr_len = IEEE802_11_DATA_HDR_LEN;
- codec.next_prot_id = ETHERNET_LLC;
+ codec.next_prot_id = PROTO_ETHERNET_LLC;
break;
}
#include "filters/detection_filter.h"
#include "detection/fpcreate.h"
#include "ips_options/ips_pcre.h"
+#include "protocols/udp.h"
//-------------------------------------------------------------------------
// private implementation
sc->max_ip6_extensions = 0;
sc->max_ip_layers = 0;
sc->gtp_ports = nullptr;
+ sc->capwap_ports = new PortList;
+ sc->capwap_ports->set(udp::CAPWAP_CONTROL_CHANNEL_PORT);
+ sc->capwap_ports->set(udp::CAPWAP_DATA_CHANNEL_PORT);
/*user_id and group_id should be initialized to -1 by default, because
* chown() use this later, -1 means no change to user_id/group_id*/
if (sc->gtp_ports)
delete sc->gtp_ports;
+ if (sc->capwap_ports)
+ delete sc->capwap_ports;
+
free(sc);
}
uint8_t enable_teredo;
uint8_t enable_esp;
PortList *gtp_ports;
+ PortList *capwap_ports;
uint8_t num_layers;
uint8_t max_ip6_extensions;
// curr_ip is the zero based ip layer
inline bool hit_ip_maxlayers(uint8_t curr_ip) const
{ return max_ip_layers && (curr_ip >= max_ip_layers); }
+
+ inline bool is_capwap_port(uint16_t port) const
+ { return capwap_ports->test(port); }
};
SnortConfig* SnortConfNew(void);
{
const Layer& lyr = p->layers[i];
- if (lyr.prot_id == IP_EMBEDDED_IN_ICMP4)
+ if (lyr.prot_id == PROTO_IP_EMBEDDED_IN_ICMP4)
{
const ip::IP4Hdr* ip4h =
reinterpret_cast<const ip::IP4Hdr*>(lyr.start);
api.set(ip4h);
return true;
}
- else if (lyr.prot_id == IP_EMBEDDED_IN_ICMP6)
+ else if (lyr.prot_id == PROTO_IP_EMBEDDED_IN_ICMP6)
{
const ip::IP6Hdr* ip6h =
reinterpret_cast<const ip::IP6Hdr*>(lyr.start);
p->ptrs.decode_flags |= DECODE_PKT_TRUST;
break;
- case PROTOCOL_TEREDO:
+ case PROTO_TEREDO:
// if we just decoded teredo and the next
// layer fails, we made a mistake. Therefore,
// remove this bit.
*/
constexpr uint16_t FINISHED_DECODE = 0x0100; // Indicates Codecs have succesfully decoded packet
-constexpr uint16_t PROTOCOL_TEREDO = 0x0101;
-constexpr uint16_t PROTOCOL_GTP = 0x0102;
-constexpr uint16_t IP_EMBEDDED_IN_ICMP4 = 0x0103;
-constexpr uint16_t IP_EMBEDDED_IN_ICMP6 = 0x0104;
-constexpr uint16_t ETHERNET_802_3 = 0x0105; // CAPWAP sends data back to eth layer
-constexpr uint16_t ETHERNET_LLC = 0x0106;
+constexpr uint16_t PROTO_TEREDO = 0x0101;
+constexpr uint16_t PROTO_GTP = 0x0102;
+constexpr uint16_t PROTO_IP_EMBEDDED_IN_ICMP4 = 0x0103;
+constexpr uint16_t PROTO_IP_EMBEDDED_IN_ICMP6 = 0x0104;
+constexpr uint16_t PROTO_ETHERNET_802_3 = 0x0105;
+constexpr uint16_t PROTO_ETHERNET_802_11 = 0x0106;
+constexpr uint16_t PROTO_ETHERNET_LLC = 0x0107;
+constexpr uint16_t PROTO_CAPWAP = 0x0108;
constexpr uint8_t UDP_HEADER_LEN = 8;
+constexpr uint16_t CAPWAP_CONTROL_CHANNEL_PORT = 5246;
+constexpr uint16_t CAPWAP_DATA_CHANNEL_PORT = 5247;
+
struct UDPHdr
{
uint16_t uh_sport;