Index: snort/ChangeLog.snort-wireless diff -u /dev/null snort/ChangeLog.snort-wireless:1.2 --- /dev/null Mon Jun 13 11:20:13 2005 +++ snort/ChangeLog.snort-wireless Sun Apr 24 19:03:34 2005 @@ -0,0 +1,63 @@ +2003-08-25 Andrew Lockhart + + * src/decode.c (DecodeWifiHdr): + - Changed references to p->pkt to pkt so that the contents of + 802.11 frames with Prism headers are decoded correctly. + +2003-08-25 Andrew Lockhart + + * rules/wifi.rules: + - Changed example addr4 plugin rule to work with fixed plugin. + + * src/detection-plugins/sp_wifi_addr4.c (WifiAddr4ParseMAC): + - Fixed MAC address parsing to cope with snort's option parsing + (was XX:XX:XX:XX:XX:XX, now 0xXXXXXXXXXXXX) + +2003-08-24 Andrew Lockhart + + * rules/wifi.rules: + - Changed example bssid plugin rule to work with fixed plugin. + + * src/detection-plugins/sp_wifi_bssid.c (WifiBssidParseBSSID): + - Fixed MAC address parsing to cope with snort's option parsing + (was XX:XX:XX:XX:XX:XX, now 0xXXXXXXXXXXXX) + +2003-08-23 Andrew Lockhart + + * src/log.c (Print2ndHeader): + - Added case for DLT_PRISM_HEADER. + +2003-08-21 Andrew Lockhart + + * src/decode.c: + - Added DecodePrismHdr() + - Moved bulk of DecodeIEEE80211Pkt() to + DecodeWifiHdr() to prevent duplicate code + + * src/decode.h: + - Added PrismHdr structure + - Added prism_val structure + + * src/snort.c (SetPktProcessor): + - Added case for DLT_PRISM_HEADER + +2003-08-14 Andrew Lockhart + + * rules/wifi.rules: + - Fixed typo in STYPE_ACK sample rule. + + * src/detection-plugins/sp_wifi_stype.c: + - Fixed typo in disassociation subtype string. + - Fixed typo in power-save poll subtype string. + - Removed redundant error check in WifiStypeRuleParseFunction() + that caused an off-by-one error. + + +2003-07-27 Andrew Lockhart + * Added ssid plugin + +2003-07-25 Andrew Lockhart + + * Added seqnum plugin + * Added fragnum plugin + * Added addr4 plugin Index: snort/configure.in diff -u snort/configure.in:1.1.1.16 snort/configure.in:1.18.2.1 --- snort/configure.in:1.1.1.16 Mon Apr 25 03:21:16 2005 +++ snort/configure.in Mon Jun 13 02:31:09 2005 @@ -4,7 +4,7 @@ AM_CONFIG_HEADER(config.h) # When changing the snort version, please also update the VERSION # definition in "src/win32/WIN32-Includes/config.h" -AM_INIT_AUTOMAKE(snort,2.3.3) +AM_INIT_AUTOMAKE(snort-wireless,2.3.3-alpha03) # Since we get -O2 from configure defaults, which doesn't work in 64bit # mode, let's make some changes here before calling _CC macros. Index: snort/doc/Makefile.am diff -u snort/doc/Makefile.am:1.1.1.10 snort/doc/Makefile.am:1.10 --- snort/doc/Makefile.am:1.1.1.10 Sun Apr 24 22:07:01 2005 +++ snort/doc/Makefile.am Sun Apr 24 22:56:30 2005 @@ -22,7 +22,8 @@ README.INLINE \ README.sfportscan \ snort_schema_v106.pdf \ -README.wireless PROBLEMS RULES.todo WISHLIST faq.pdf faq.tex +README.wireless PROBLEMS RULES.todo WISHLIST faq.pdf faq.tex \ +README.snort-wireless DISTCLEANFILES= snort_manual.log snort_manual.toc snort_manual.aux faq.pdf faq.tex snort_manual.pdf Index: snort/doc/README.snort-wireless diff -u /dev/null snort/doc/README.snort-wireless:1.1 --- /dev/null Mon Jun 13 11:20:13 2005 +++ snort/doc/README.snort-wireless Thu Mar 10 17:34:35 2005 @@ -0,0 +1,74 @@ +Snort-Wireless +============== + +Copyright (c) 2003 Andrew Lockhart + +Any feedback, bug reports, feature requests, etc. are welcome at +andrew@snort-wireless.org. If you'd like to help in any way, feel free to +contact me. I'll try to respond ASAP. + +"wifi" Protocol Rules +===================== +Snort at present does not contain direct support for rule based detection of +anything below the IP layer. It is possible in Snort 2.0.x to match byte +patterns in a packet, but it is not very straightforward and is very +time-consuming to write detection rules this way. + +Rules for detecting particular 802.11 frames are specified +using the following syntax: + + wifi -> () + +The 802.11 plugins are in src/detection-plugins and their filenames begin +with sp_wifi_. Each plugin should have documentation for it in the comments +at the top of its source file. Additionally, rules/wifi.rules contains example +rules for every plugin contained in the distribution. + +-Bugs- +* Only the alert and log actions have been tested +* Only the first matching rule triggers an alert +* Alerts logged to a database do not show up in ACID - this is because they + lack in IP header + +RogueAP Preprocessor +The RogueAP preprocessor detects both rogue APs and AdHoc networks. To +configure it, you'll need to first specify your APs BSSIDs and channels that +they operate on in your snort.conf file using the ACCESS_POINTS and CHANNELS +variables. + +# Single AP +var ACCESS_POINTS XX:XX:XX:XX:XX:XX +# Multiple APs +var ACCESS_POINTS [XX:XX:XX:XX:XX:XX, YY:YY:YY:YY:YY:YY, ....] +# Single channel +var CHANNELS X +# Multiple channels +var CHANNELS [X, Y, ...] + +The preprocessor is activated by specifying the following in your snort.conf: + +preprocessor rogue_ap: $ACCESS_POINTS, $CHANNELS, scan_flag [0 | 1], \ + scan_timeout [num], expire_timeout [num] + + +* scan_flag - toggles scanning of multiple channels *NOT IMPLEMENTED* +* scan_timeout - time in seconds between channel scans *NOT IMPLEMENTED* +* expire_timeout - time in seconds before a BSSID is removed from the rogue + list + +AntiStumbler Preprocessor + +The AntiStumbler preprocessor attempts to detect Netstumbler like traffic. It +does this by keeping track of probe request frames sent with NULL SSID fields. +The preprocessor is activated by specifying the following in your snort.conf: + +preprocessor antistumbler: probe_reqs [num], probe_period [num], \ + expire_timeout [num] + + +* probe_reqs - number of probe requests that triggers an alert +* probe_period - time period in seconds that NULL SSID probe request count is + maintained +* expire_timeout - time in seconds before a STA is removed from the stumbler + list + Index: snort/etc/snort.conf diff -u snort/etc/snort.conf:1.1.1.9 snort/etc/snort.conf:1.10 --- snort/etc/snort.conf:1.1.1.9 Mon Apr 25 03:25:02 2005 +++ snort/etc/snort.conf Mon Apr 25 13:05:05 2005 @@ -46,6 +46,22 @@ # Set up the external network addresses as well. A good start may be "any" var EXTERNAL_NET any +# Configure your wireless AP lists. This allows snort to look for attacks +# against your wireless network, such as rogue access points or adhoc wireless +# networks. Also specify what channels your access points are setup on. +# +# Ex: +# +# var ACCESS_POINTS XX:XX:XX:XX:XX:XX +# var CHANNELS X +# OR +# +# var ACCESS_POINTS [XX:XX:XX:XX:XX:XX, YY:YY:YY:YY:YY:YY, ....] +# var CHANNELS [X, Y, ....] + +var ACCESS_POINTS FF:FF:FF:FF:FF:FF +var CHANNELS 11 + # Configure your server lists. This allows snort to only look for attacks to # systems that have a service up. Why look for HTTP attacks if you are not # running a web server? This allows quick filtering based on IP addresses @@ -501,6 +517,31 @@ preprocessor xlink2state: ports { 25 691 } +# RogueAP +#--------------------------------------------- +# RogueAP detects rogue APs and AdHoc networks +# +# Arguments: +# +# scan_flag [0 | 1] => toggles scanning of multiple channels *NOT IMPLEMENTED* +# scan_timeout [num] => time in seconds between channel scans *NOT IMPLEMENTED* +# expire_timeout [num] => time in seconds before a BSSID is removed from the rogue list +# +preprocessor rogue_ap: $ACCESS_POINTS, $CHANNELS, scan_flag 1, scan_timeout 1800, expire_timeout 3600 + +# AntiStumbler +#--------------------------------------------- +# AntiStumbler detects possible Netstumbler activity +# +# Arguments: +# +# probe_reqs [num] => number of probe requests that triggers an alert +# probe_period [num] => time period in seconds that NULL SSID probe requests are counted +# expire_timeout [num] => time in seconds before a STA is removed from the stumbler list +# + +preprocessor antistumbler: probe_reqs 90, probe_period 30, expire_timeout 3600 + #################################################################### # Step #3: Configure output plugins # @@ -705,6 +746,7 @@ # include $RULE_PATH/multimedia.rules # include $RULE_PATH/p2p.rules include $RULE_PATH/experimental.rules +include $RULE_PATH/wifi.rules # Include any thresholding or suppression commands. See threshold.conf in the # /etc directory for details. Commands don't necessarily need to be Index: snort/rules/Makefile.am diff -u snort/rules/Makefile.am:1.1.1.3 snort/rules/Makefile.am:1.3 --- snort/rules/Makefile.am:1.1.1.3 Thu Mar 10 13:13:45 2005 +++ snort/rules/Makefile.am Fri Mar 11 10:54:28 2005 @@ -9,4 +9,5 @@ porn.rules rpc.rules rservices.rules scan.rules shellcode.rules smtp.rules \ snmp.rules sql.rules telnet.rules tftp.rules virus.rules web-attacks.rules \ web-cgi.rules web-client.rules web-coldfusion.rules web-frontpage.rules \ -web-iis.rules web-misc.rules web-php.rules x11.rules pop2.rules +web-iis.rules web-misc.rules web-php.rules x11.rules pop2.rules \ +wifi.rules Index: snort/rules/wifi.rules diff -u /dev/null snort/rules/wifi.rules:1.7 --- /dev/null Mon Jun 13 11:20:16 2005 +++ snort/rules/wifi.rules Fri Mar 11 10:54:28 2005 @@ -0,0 +1,74 @@ +# these are just for testing right now + +# *NOTE* MAC addresses can be substituted for "any" + + +# Frame types +# ! may proceed any type argument to perform a logical NOT operation + +alert wifi any -> any (msg:"Mangement Frame"; type:TYPE_MANAGEMENT;) +alert wifi any -> any (msg:"Control Frame"; type:TYPE_CONTROL;) +alert wifi any -> any (msg:"Data Frame"; type:TYPE_DATA;) + + +# Frame subtypes (These implicitly check the frame's type) +# ! may proceed any stype argument to perform a logical NOT operation + +#alert wifi any -> any (msg:"Association Request"; stype:STYPE_ASSOCREQ;) +#alert wifi any -> any (msg:"Association Response"; stype:STYPE_ASSOCRESP;) +#alert wifi any -> any (msg:"Reassociation Request"; stype:STYPE_REASSOC_REQ;) +#alert wifi any -> any (msg:"Reassociation Response"; stype:STYPE_REASSOC_RESP;) +#alert wifi any -> any (msg:"Probe Request"; stype:STYPE_PROBEREQ;) +#alert wifi any -> any (msg:"Probe Response"; stype:STYPE_PROBERESP;) +#alert wifi any -> any (msg:"Beacon"; stype:STYPE_BEACON;) +#alert wifi any -> any (msg:"ATIM"; stype:STYPE_ATIM;) +#alert wifi any -> any (msg:"Disassociation"; stype:STYPE_DISASSOC;) +#alert wifi any -> any (msg:"Authentication"; stype:STYPE_AUTH;) +#alert wifi any -> any (msg:"Deauthentication"; stype:STYPE_DEAUTH;) + +#alert wifi any -> any (msg:"Power-Save Poll"; stype:STYPE_PSPOLL;) +#alert wifi any -> any (msg:"RTS"; stype:STYPE_RTS;) +#alert wifi any -> any (msg:"CTS"; stype:STYPE_CTS;) +#alert wifi any -> any (msg:"Ack"; stype:STYPE_ACK;) +#alert wifi any -> any (msg:"CF-End"; stype:STYPE_CFEND;) +#alert wifi any -> any (msg:"CF-End+CF-Ack"; stype:STYPE_CFEND_CFACK;) + +#alert wifi any -> any (msg:"Data"; stype:STYPE_DATA;) +#alert wifi any -> any (msg:"CF-Ack"; stype:STYPE_CFACK;) +#alert wifi any -> any (msg:"CF-Poll"; stype:STYPE_CFPOLL;) +#alert wifi any -> any (msg:"CF-Ack+CF-Poll"; stype:STYPE_CFACK_CFPOLL;) +#alert wifi any -> any (msg:"NULL Function"; stype:STYPE_NULLFUNC;) +#alert wifi any -> any (msg:"CF-Ack+NULL Function"; stype:STYPE_CFACK_NULLFUNC;) +#alert wifi any -> any (msg:"CF-Poll+NULL Function"; stype:STYPE_CFPOLL_NULLFUNC;) +#alert wifi any -> any (msg:"CF-Ack+CF-Poll-NULL Function"; stype:STYPE_CFACK_CFPOLL_NULLFUNC;) + +# Check for a match of the entire frame control field against a hex or decimal value +# ! may proceed the argument to perform a logical NOT operation +#alert wifi any -> any (msg:"WEP encrypted Data frame with from_ds set"; frame_control:0x4208;) +#alert wifi any -> any (msg:"WEP encrypted Data frame with from_ds set"; frame_control:16904;) + + +# Frame control flags +# ON, OFF, TRUE, or FALSE may be used. '!' may proceed any of these. + +#alert wifi any -> any (msg:"from_ds flag set"; from_ds:TRUE;) +#alert wifi any -> any (msg:"to_ds flag set"; to_ds:ON;) +#alert wifi any -> any (msg:"more_frags flag set"; more_frags:!FALSE;) +#alert wifi any -> any (msg:"retry flag set"; retry:!OFF;) +#alert wifi any -> any (msg:"pwr_mgmt flag not set"; pwr_mgmt:FALSE;) +#alert wifi any -> any (msg:"more_data flag not set"; more_data:OFF;) +#alert wifi any -> any (msg:"wep flag set"; wep:TRUE;) +#alert wifi any -> any (msg:"order flag set"; order:TRUE;) + + +# These plugins will detect on frames that contain the respective field +# '!' may proceed any of these plugin arguments to perform a logical NOT operation + +#alert wifi any -> any (msg:"Duration/ID is 0xFF"; duration_id:0xFF;) +#alert wifi any -> any (msg:"BSSID is not 00\:DE\:AD\:C0\:DE\:00"; bssid:!0x00DEADC0DE00;) +#alert wifi any -> any (msg:"Sequence Number is 2345"; seq_num:2345;) +#alert wifi any -> any (msg:"Sequence Number is 0xFF"; seq_num:0x00FF;) +#alert wifi any -> any (msg:"Fragment Number is 12"; frag_num:12;) +#alert wifi any -> any (msg:"Fragment Number is 15"; frag_num:0xF;) +#alert wifi any -> any (msg:"Address 4 Field is D1\:ED\:1E\:D1\:ED\:1E"; addr4:0xD1ED1ED1ED1E;) +#alert wifi any -> any (msg:"SSID is linksys"; ssid:linksys;) Index: snort/src/decode.c diff -u snort/src/decode.c:1.1.1.8 snort/src/decode.c:1.12 --- snort/src/decode.c:1.1.1.8 Sun Apr 24 22:10:55 2005 +++ snort/src/decode.c Sun Apr 24 22:56:30 2005 @@ -149,10 +149,9 @@ /* - * Function: DecodeIEEE80211Pkt(Packet *, char *, struct pcap_pkthdr*, - * u_int8_t*) + * Function: DecodeWifiHdr(Packet *, char *, struct pcap_pkthdr *, u_int8_t *) * - * Purpose: Decode those fun loving wireless LAN packets, one at a time! + * Purpose: Decodes unencapsulated portion of 802.11 frame headers * * Arguments: p => pointer to the decoded packet struct * user => Utility pointer (unused) @@ -161,40 +160,34 @@ * * Returns: void function */ -void DecodeIEEE80211Pkt(Packet * p, struct pcap_pkthdr * pkthdr, - u_int8_t * pkt) -{ +void DecodeWifiHdr(Packet *p, struct pcap_pkthdr * pkthdr, u_int8_t *pkt){ + u_int32_t pkt_len; /* suprisingly, the length of the packet */ u_int32_t cap_len; /* caplen value */ - - bzero((char *) p, sizeof(Packet)); - - p->pkth = pkthdr; - p->pkt = pkt; - + /* set the lengths we need */ pkt_len = pkthdr->len; /* total packet length */ cap_len = pkthdr->caplen; /* captured packet length */ + + if(snaplen < pkthdr->len) + pkt_len = cap_len; - if(snaplen < pkt_len) - pkt_len = cap_len; - - DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); - DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n", - (unsigned long)cap_len, (unsigned long)pkt_len);); - - /* do a little validation */ - if(p->pkth->caplen < MINIMAL_IEEE80211_HEADER_LEN) - { - if(pv.verbose_flag) - { - ErrorMessage("Captured data length < IEEE 802.11 header length! (%d bytes)\n", p->pkth->caplen); - } - return; - } /* lay the wireless structure over the packet data */ p->wifih = (WifiHdr *) pkt; + +#if BYTE_ORDER == BIG_ENDIAN + /* Swap bytes of duration_id on big endian archs */ + p->wifih->duration_id = (p->wifih->duration_id << 8) | + (p->wifih->duration_id >> 8); + + /* I'm not sure if this is peculiar to OS X or is required on all + big endian archs, since this involves a rotate rather than a byte swap */ + + p->wifih->seq_control = (p->wifih->seq_control << 4) | + (p->wifih->seq_control >> 12); +#endif + DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "%X %X\n", *p->wifih->addr1, *p->wifih->addr2);); @@ -312,7 +305,7 @@ switch(ntohs(p->ehllcother->proto_id)) { case ETHERNET_TYPE_IP: - DecodeIP(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) + + DecodeIP(pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) + sizeof(EthLlcOther), pkt_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) - sizeof(EthLlcOther), p); @@ -320,19 +313,19 @@ case ETHERNET_TYPE_ARP: case ETHERNET_TYPE_REVARP: - DecodeARP(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) + + DecodeARP(pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) + sizeof(EthLlcOther), pkt_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) - sizeof(EthLlcOther), p); return; case ETHERNET_TYPE_EAPOL: - DecodeEapol(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) + + DecodeEapol(pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) + sizeof(EthLlcOther), pkt_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) - sizeof(EthLlcOther), p); return; case ETHERNET_TYPE_8021Q: - DecodeVlan(p->pkt + IEEE802_11_DATA_HDR_LEN , + DecodeVlan(pkt + IEEE802_11_DATA_HDR_LEN , cap_len - IEEE802_11_DATA_HDR_LEN , p); return; @@ -349,6 +342,116 @@ return; } + + + + +/* + * Function: DecodeIEEE80211Pkt(Packet *, char *, struct pcap_pkthdr*, + * u_int8_t*) + * + * Purpose: Decode those fun loving (unencapsulated) wireless LAN packets, one at a time! + * + * Arguments: p => pointer to the decoded packet struct + * user => Utility pointer (unused) + * pkthdr => ptr to the packet header + * pkt => pointer to the real live packet data + * + * Returns: void function + */ + +void DecodeIEEE80211Pkt(Packet * p, struct pcap_pkthdr * pkthdr, + u_int8_t * pkt) +{ + u_int32_t pkt_len; /* suprisingly, the length of the packet */ + u_int32_t cap_len; /* caplen value */ + + bzero((char *) p, sizeof(Packet)); + + p->pkth = pkthdr; + p->pkt = pkt; + + /* set the lengths we need */ + pkt_len = pkthdr->len; /* total packet length */ + cap_len = pkthdr->caplen; /* captured packet length */ + + if(snaplen < pkt_len) + pkt_len = cap_len; + + DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); + DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n", + (unsigned long)cap_len, (unsigned long)pkt_len);); + + /* do a little validation */ + if(p->pkth->caplen < MINIMAL_IEEE80211_HEADER_LEN) + { + if(pv.verbose_flag) + { + ErrorMessage("Captured data length < IEEE 802.11 header length! (%d bytes)\n", p->pkth->caplen); + } + return; + } + + /* decode the actual 802.11 frame */ + DecodeWifiHdr(p, pkthdr, pkt); +} + + + + + +/* + * Function: DecodePrismHdr(Packet *, char *, struct pcap_pkthdr *, u_int8_t *) + * + * Purpose: Decode PRISM header encapsulated 802.11 frames. + * + * Arguments: p => pointer to the decoded packet struct + * user => Utility pointer (unused) + * pkthdr => ptr to the packet header + * pkt => pointer to the real live packet data + * + * Returns: void function + */ + +void DecodePrismHdr(Packet *p, struct pcap_pkthdr *pkthdr, u_int8_t *pkt){ + + u_int32_t pkt_len; /* suprisingly, the length of the packet */ + u_int32_t cap_len; /* caplen value */ + + bzero((char *) p, sizeof(Packet)); + + p->pkth = pkthdr; + p->pkt = pkt; + + /* set the lengths we need */ + pkt_len = pkthdr->len; /* total packet length */ + cap_len = pkthdr->caplen; /* captured packet length */ + + + if(snaplen < pkt_len) + pkt_len = cap_len; + + DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); + DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n", + (unsigned long)cap_len, (unsigned long)pkt_len);); + + /* do a little validation */ + if(p->pkth->caplen < (sizeof(PrismHdr) + MINIMAL_IEEE80211_HEADER_LEN)) + { + if(pv.verbose_flag) + { + ErrorMessage("Captured data length < IEEE 802.11 header length! (%d bytes)\n", p->pkth->caplen); + } + return; + } + + /* lay the prism structure over the packet data */ + p->prismh = (PrismHdr *)pkt; + + /* decode the encapsulated 802.11 frame */ + DecodeWifiHdr(p, pkthdr, pkt + sizeof(PrismHdr)); +} + void DecodeVlan(u_int8_t * pkt, const u_int32_t len, Packet * p) Index: snort/src/decode.h diff -u snort/src/decode.h:1.1.1.8 snort/src/decode.h:1.11 --- snort/src/decode.h:1.1.1.8 Sun Apr 24 22:10:56 2005 +++ snort/src/decode.h Sun Apr 24 22:56:30 2005 @@ -776,15 +776,77 @@ */ typedef struct _WifiHdr { + union{ u_int16_t frame_control; + struct { + + /* Compensate for endianess/libpcap and maybe OSX/libpcap weirdness - + you'd think a straight byte swap would work */ + +#if BYTE_ORDER == LITTLE_ENDIAN + u_int16_t version:2; + u_int16_t type:2; + u_int16_t stype:4; +#else + u_int16_t stype:4; + u_int16_t type:2; + u_int16_t version:2; +#endif + u_int16_t to_ds:1; + u_int16_t from_ds:1; + u_int16_t more_frags:1; + u_int16_t retry:1; + u_int16_t pwr_mgmt:1; + u_int16_t more_data:1; + u_int16_t wep:1; + u_int16_t order:1; + }; + }; u_int16_t duration_id; u_int8_t addr1[6]; u_int8_t addr2[6]; u_int8_t addr3[6]; - u_int16_t seq_control; + + union { + u_int16_t seq_control; + struct { + u_int16_t fragnum:4; + u_int16_t seqnum:12; + }; + }; u_int8_t addr4[6]; } WifiHdr; +/* + * PRISM Header (Sometimes encapsulates IEEE 802.11 Headers) + * + * (Somewhat borrowed from Tim Newsham's PRISM decoder for ethereal) + */ + +typedef struct _prism_val { + u_int32_t did; + u_int16_t status; + u_int16_t len; + u_int32_t data; +} prism_val; + +typedef struct _PrismHdr { + + u_int32_t msg_code; + u_int32_t msg_len; + char dev_name[16]; + prism_val host_time; + prism_val mac_time; + prism_val channel; + prism_val rssi; + prism_val sq; + prism_val signal; + prism_val noise; + prism_val rate; + prism_val is_tx; + prism_val frame_len; + +} PrismHdr; /* Can't add any fields not in the real header here because of how the decoder uses structure overlaying */ @@ -1070,7 +1132,7 @@ EthLlcOther *ehllcother; WifiHdr *wifih; /* wireless LAN header */ - + PrismHdr *prismh; /* PRISM header */ EtherARP *ah; EtherEapol *eplh; /* 802.1x EAPOL header */ @@ -1167,6 +1229,7 @@ void DecodeLinuxSLLPkt(Packet *, struct pcap_pkthdr *, u_int8_t *); void DecodeEthPkt(Packet *, struct pcap_pkthdr *, u_int8_t *); void DecodeIEEE80211Pkt(Packet *, struct pcap_pkthdr *, u_int8_t *); +void DecodePrismHdr(Packet *, struct pcap_pkthdr *, u_int8_t *); void DecodeVlan(u_int8_t *, const u_int32_t, Packet *); void DecodePppPkt(Packet *, struct pcap_pkthdr *, u_int8_t *); void DecodePppSerialPkt(Packet *, struct pcap_pkthdr *, u_int8_t *); Index: snort/src/detect.c diff -u snort/src/detect.c:1.1.1.8 snort/src/detect.c:1.9 --- snort/src/detect.c:1.1.1.8 Sun Apr 24 22:10:58 2005 +++ snort/src/detect.c Sun Apr 24 22:56:30 2005 @@ -438,7 +438,7 @@ rule = RuleLists; - if(p && p->iph == NULL) + if(p && p->iph == NULL && p->wifih == NULL) return 0; /* @@ -634,6 +634,7 @@ { RuleTreeNode *rtn_idx; IpAddrSet *idx; /* indexing pointer */ + MacAddrSet *idx2; int i; #ifdef DEBUG OptTreeNode *otn_idx; @@ -651,6 +652,60 @@ /* walk thru the RTN list */ while(rtn_idx != NULL) { + if(rtn_idx->is_wifi){ + DEBUG_WRAP( + DebugMessage(DEBUG_RULES, "Rule type: %d\n", rtn_idx->type); + DebugMessage(DEBUG_RULES, "SRC MAC List:\n"); + ); + + idx2 = rtn_idx->smac; + i = 0; + while(idx2 != NULL) + { + DEBUG_WRAP(DebugMessage(DEBUG_RULES, + "[%d] %.2X:%.2X:%.2X:%.2X:%.2X:%.2X ", i++, + idx2->mac_addr[0], idx2->mac_addr[1], idx2->mac_addr[2], + idx2->mac_addr[3], idx2->mac_addr[4], idx2->mac_addr[5])); + + if(idx2->addr_flags & EXCEPT_MAC) + { + DEBUG_WRAP(DebugMessage(DEBUG_RULES, + " (EXCEPTION_FLAG Active)\n");); + } + else + { + DEBUG_WRAP(DebugMessage(DEBUG_RULES, "\n");); + } + idx2 = idx2->next; + } + + DEBUG_WRAP(DebugMessage(DEBUG_RULES, "DST MAC List:\n");); + + idx2 = rtn_idx->dmac; + i = 0; + while(idx2 != NULL) + { + DEBUG_WRAP(DebugMessage(DEBUG_RULES, + "[%d] %.2X:%.2X:%.2X:%.2X:%.2X:%.2X ", i++, + idx2->mac_addr[0], idx2->mac_addr[1], idx2->mac_addr[2], + idx2->mac_addr[3], idx2->mac_addr[4], idx2->mac_addr[5])); + + if(idx2->addr_flags & EXCEPT_MAC) + { + DEBUG_WRAP(DebugMessage(DEBUG_RULES, + " (EXCEPTION_FLAG Active)\n");); + } + else + { + DEBUG_WRAP(DebugMessage(DEBUG_RULES, "\n");); + } + idx2 = idx2->next; + } + + + + } + else{ DEBUG_WRAP( DebugMessage(DEBUG_RULES, "Rule type: %d\n", rtn_idx->type); DebugMessage(DEBUG_RULES, "SRC IP List:\n"); @@ -660,7 +715,7 @@ while(idx != NULL) { DEBUG_WRAP(DebugMessage(DEBUG_RULES, - "[%d] 0x%.8lX / 0x%.8lX", + "[%d] 0x%.8lX / 0x%.8lX ", i++, (u_long) idx->ip_addr, (u_long) idx->netmask);); @@ -683,7 +738,7 @@ while(idx != NULL) { DEBUG_WRAP(DebugMessage(DEBUG_RULES, - "[%d] 0x%.8lX / 0x%.8lX", + "[%d] 0x%.8lX / 0x%.8lX ", i++,(u_long) idx->ip_addr, (u_long) idx->netmask);); if(idx->addr_flags & EXCEPT_IP) @@ -698,7 +753,25 @@ idx = idx->next; } + } #ifdef DEBUG + if(rtn_idx->is_wifi){ + DebugMessage(DEBUG_RULES, "FLags: "); + if(rtn_idx->flags & EXCEPT_SRC_MAC) + DebugMessage(DEBUG_RULES, "EXCEPT_SRC_MAC "); + if(rtn_idx->flags & EXCEPT_DST_MAC) + DebugMessage(DEBUG_RULES, "EXCEPT_DST_MAC "); + if(rtn_idx->flags & EXCEPT_BSSID_MAC) + DebugMessage(DEBUG_RULES, "EXCEPT_BSSID_MAC "); + if(rtn_idx->flags & ANY_SRC_MAC) + DebugMessage(DEBUG_RULES, "ANY_SRC_MAC "); + if(rtn_idx->flags & ANY_DST_MAC) + DebugMessage(DEBUG_RULES, "ANY_DST_MAC "); + if(rtn_idx->flags & ANY_BSSID_MAC) + DebugMessage(DEBUG_RULES, "ANY_BSSID_MAC "); + DebugMessage(DEBUG_RULES, "\n"); + } + else{ DebugMessage(DEBUG_RULES, "SRC PORT: %d - %d \n", rtn_idx->lsp, rtn_idx->hsp); DebugMessage(DEBUG_RULES, "DST PORT: %d - %d \n", rtn_idx->ldp, @@ -719,6 +792,7 @@ DebugMessage(DEBUG_RULES, "EXCEPT_DST_PORT "); DebugMessage(DEBUG_RULES, "\n"); + } otn_idx = rtn_idx->down; DEBUG_WRAP( @@ -888,6 +962,134 @@ return 1; } + + +int CheckSrcMAC(Packet *p, struct _RuleTreeNode *rtn_idx, RuleFpList *fp_list){ + + MacAddrSet *idx; + + DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"CheckSrcMACEqual: ");); + +#warning "Make sure frames src and dest addresses correspond correctly" + + if(!(rtn_idx->flags & EXCEPT_SRC_MAC)){ + /* do the check */ + for(idx = rtn_idx->smac; idx != NULL; idx=idx->next) + { + +/* if( ((idx->ip_addr == (p->iph->ip_src.s_addr & idx->netmask)) */ +/* ^ (idx->addr_flags & EXCEPT_IP)) ) */ + if(!memcmp(idx->mac_addr, p->wifih->addr2, 6) ^ (idx->addr_flags & EXCEPT_MAC)) + { +#ifdef DEBUG + if(idx->addr_flags & EXCEPT_MAC) { + DebugMessage(DEBUG_DETECT, " SMAC exception match\n"); + } + else + { + DebugMessage(DEBUG_DETECT, " SMAC match\n"); + } + +/* DebugMessage(DEBUG_DETECT, "Rule: 0x%X Packet: 0x%X\n", */ +/* idx->ip_addr, (p->iph->ip_src.s_addr & idx->netmask)); */ +#endif /* DEBUG */ + + /* the packet matches this test, proceed to the next test */ + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next); + } + } + } + else + { + /* global exception flag is up, we can't match on *any* + * of the source addresses + */ + DEBUG_WRAP(DebugMessage(DEBUG_DETECT," global exception flag, \n");); + + /* do the check */ + for(idx=rtn_idx->smac; idx != NULL; idx=idx->next) + { + if(!memcmp(idx->mac_addr, p->wifih->addr2, 6) ^ (idx->addr_flags & EXCEPT_MAC)) + { + DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"address matched, failing on SMAC\n");); + /* got address match on globally negated rule, fail */ + return 0; + } + } + DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"no matches on SMAC, passed\n");); + + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next); + } + + DEBUG_WRAP(DebugMessage(DEBUG_DETECT," Mismatch on SMAC\n");); + + /* return 0 on a failed test */ + return 0; +} + +int CheckDstMAC(Packet *p, struct _RuleTreeNode *rtn_idx, RuleFpList *fp_list){ + MacAddrSet *idx; /* ip address indexer */ + + DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "CheckDstMACEqual: ");) + + /* check for global exception flag */ + if(!(rtn_idx->flags & EXCEPT_DST_MAC)) + { + /* do the check */ + for(idx=rtn_idx->dmac; idx != NULL; idx=idx->next) + { + /* if( ((idx->ip_addr == (p->iph->ip_dst.s_addr & idx->netmask)) */ +/* ^ (idx->addr_flags & EXCEPT_IP)) ) */ + if(!memcmp(idx->mac_addr, p->wifih->addr1, 6) ^ (idx->addr_flags & EXCEPT_MAC)) + { +#ifdef DEBUG + if(idx->addr_flags & EXCEPT_MAC) + { + DebugMessage(DEBUG_DETECT, " DMAC exception match\n"); + } + else + { + DebugMessage(DEBUG_DETECT, " DMAC match\n"); + } + +/* DebugMessage(DEBUG_DETECT, "Rule: 0x%X Packet: 0x%X\n", */ +/* idx->ip_addr, (p->iph->ip_src.s_addr & idx->netmask)); */ +#endif /* DEBUG */ + /* the packet matches this test, proceed to the next test */ + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next); + } + } + } + else + { + /* global exception flag is up, we can't match on *any* + * of the source addresses + */ + DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " global exception flag, \n");); + + /* do the check */ + for(idx=rtn_idx->dip; idx != NULL; idx=idx->next) + { +/* if( ((idx->ip_addr == (p->iph->ip_dst.s_addr & idx->netmask)) */ +/* ^ (idx->addr_flags & EXCEPT_IP)) ) */ + if(!memcmp(idx->mac_addr, p->wifih->addr1, 6) ^ (idx->addr_flags & EXCEPT_MAC)) + { + DEBUG_WRAP(DebugMessage(DEBUG_DETECT, + "address matched, failing on DMAC\n");); + /* got address match on globally negated rule, fail */ + return 0; + } + } + DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "no matches on DMAC, passed\n");); + + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next); + } + + DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Mismatch on DMAC\n");); + /* return 0 on a failed test */ + return 0; +} + /**************************************************************************** Index: snort/src/detect.h diff -u snort/src/detect.h:1.1.1.5 snort/src/detect.h:1.6 --- snort/src/detect.h:1.1.1.5 Sun Apr 24 22:10:58 2005 +++ snort/src/detect.h Sun Apr 24 22:56:30 2005 @@ -64,6 +64,10 @@ /* detection modules */ int CheckBidirectional(Packet *, struct _RuleTreeNode *, RuleFpList *); + +int CheckSrcMAC(Packet *, struct _RuleTreeNode *, RuleFpList *); +int CheckDstMAC(Packet *, struct _RuleTreeNode *, RuleFpList *); + int CheckSrcIP(Packet *, struct _RuleTreeNode *, RuleFpList *); int CheckDstIP(Packet *, struct _RuleTreeNode *, RuleFpList *); int CheckSrcIPNotEq(Packet *, struct _RuleTreeNode *, RuleFpList *); Index: snort/src/fpcreate.c diff -u snort/src/fpcreate.c:1.1.1.6 snort/src/fpcreate.c:1.7 --- snort/src/fpcreate.c:1.1.1.6 Sun Apr 24 00:25:00 2005 +++ snort/src/fpcreate.c Sun Apr 24 00:50:15 2005 @@ -71,6 +71,8 @@ static PORT_RULE_MAP *prmIpRTNX = NULL; static PORT_RULE_MAP *prmIcmpRTNX= NULL; +static PORT_RULE_MAP *prmWifiRTNX = NULL; + static FPDETECT fpDetect; /* @@ -105,6 +107,12 @@ } +int prmFindRuleGroupWifi(PORT_GROUP **wifi_group, PORT_GROUP **gen){ + PORT_GROUP *src; + return prmFindRuleGroup(prmWifiRTNX, -1, -1, &src, wifi_group, gen); +} + + /* ** These Otnhas* functions check the otns for different contents. This ** helps us decide later what group (uri, content) the otn will go to. @@ -692,6 +700,8 @@ RuleTreeNode *rtn; int sport; int dport; + u_int8_t *smac; + u_int8_t *dmac; OptTreeNode * otn; int iBiDirectional = 0; @@ -715,6 +725,10 @@ if(prmIcmpRTNX == NULL) return 1; + prmWifiRTNX = prmNewMap(); + if(prmWifiRTNX == NULL) + return 1; + for (rule=RuleLists; rule; rule=rule->next) { if(!rule->RuleList) @@ -1077,17 +1091,75 @@ } } } + if(rule->RuleList->WifiList){ /* treat a Wifi rule like an IP one without ports */ + + for(rtn = rule->RuleList->WifiList; rtn != NULL; rtn = rtn->right) + { + /* Walk OTN list -Add as Content, or NoContent */ + for( otn=rtn->down; otn; otn=otn->next ) + { + + otnx = malloc( sizeof(OTNX) ); + MEMASSERT(otnx,"otnx-WIFI"); + + otnx->otn = otn; + otnx->rtn = rtn; + +/* IpProto = */ +/* (IpProtoData *)otn->ds_list[PLUGIN_IP_PROTO_CHECK] ; */ + +/* if( IpProto ) */ +/* { */ +/* protocol = IpProto->protocol; */ +/* if( IpProto->comparison_flag == GREATER_THAN ) */ +/* protocol=-1; */ + +/* if( IpProto->comparison_flag == LESS_THAN ) */ +/* protocol=-1; */ + +/* if( IpProto->not_flag ) */ +/* protocol=-1; */ +/* } */ +/* else */ +/* { */ +/* protocol = -1; */ +/* } */ + + if( OtnHasContent( otn ) ) + { + if(fpDetect.debug) + { + printf("WIFI Content-Rule %s\n", otn->sigInfo.message); + } + prmAddRule(prmWifiRTNX, -1, -1, otnx); + + } + else + { + if(fpDetect.debug) + { + printf("WIFI NoContent-Rule %s\n", otn->sigInfo.message); + } + prmAddRuleNC(prmWifiRTNX, -1, -1, otnx); + + } + } + } + + } } prmCompileGroups(prmTcpRTNX); prmCompileGroups(prmUdpRTNX); prmCompileGroups(prmIcmpRTNX); prmCompileGroups(prmIpRTNX); + prmCompileGroups(prmWifiRTNX); BuildMultiPatternGroups(prmTcpRTNX); BuildMultiPatternGroups(prmUdpRTNX); BuildMultiPatternGroups(prmIcmpRTNX); BuildMultiPatternGroups(prmIpRTNX); + BuildMultiPatternGroups(prmWifiRTNX); if(fpDetect.debug) { @@ -1102,6 +1174,9 @@ printf("\n** IP Rule Group Stats -- "); prmShowStats(prmIpRTNX); + + printf("\n** WIFI Rule Group Stats -- "); + prmShowStats(prmWifiRTNX); } return 0; @@ -1124,6 +1199,7 @@ printf("\n** UDP Event Stats -- "); prmShowEventStats(prmUdpRTNX); printf("\n** ICMP Event Stats -- "); prmShowEventStats(prmIcmpRTNX); printf("\n** IP Event Stats -- "); prmShowEventStats(prmIpRTNX); + printf("\n** WIFI Event Stats -- "); prmShowEventStats(prmWifiRTNX); return 0; } Index: snort/src/fpdetect.c diff -u snort/src/fpdetect.c:1.1.1.10 snort/src/fpdetect.c:1.12 --- snort/src/fpdetect.c:1.1.1.10 Sun Apr 24 22:11:01 2005 +++ snort/src/fpdetect.c Sun Apr 24 22:56:30 2005 @@ -135,6 +135,10 @@ static INLINE int fpEvalHeaderIcmp(Packet *p); static INLINE int fpEvalHeaderTcp(Packet *p); static INLINE int fpEvalHeaderUdp(Packet *p); + + +static INLINE int fpEvalHeaderWifi(Packet *p); + static INLINE int fpEvalHeaderSW(PORT_GROUP *port_group, Packet *p, int check_ports); static int otnx_match (void* id, int index, void * data ); @@ -1359,6 +1363,31 @@ return fpFinalSelectEvent(&omd, p); } + +static INLINE int fpEvalHeaderWifi(Packet *p){ + + PORT_GROUP *gen, *wifi_group; + int retval; + + retval = prmFindRuleGroupWifi(&wifi_group, &gen); + + switch(retval) + { + case 4: + if(fpEvalHeader(gen, p, 0)) + { + return 1; + } + break; + default: + break; + } + + return 0; +} + + + /* ** ** NAME @@ -1386,7 +1415,19 @@ */ int fpEvalPacket(Packet *p) { - int ip_proto = p->iph->ip_proto; + int ip_proto; + + + /* check both the ip and wifi headers if they exist */ + + if(p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_DETECT, + "Detecting on WifiList\n");); + fpEvalHeaderWifi(p); + } + + if(p->iph){ + ip_proto = p->iph->ip_proto; switch(ip_proto) { @@ -1434,5 +1475,9 @@ ** No Match on TCP/UDP, Do IP */ return fpEvalHeaderIp(p, ip_proto); + } + + return 0; } + Index: snort/src/generators.h diff -u snort/src/generators.h:1.1.1.5 snort/src/generators.h:1.6 --- snort/src/generators.h:1.1.1.5 Mon Apr 25 03:26:00 2005 +++ snort/src/generators.h Mon Apr 25 13:05:05 2005 @@ -170,6 +170,12 @@ #define GENERATOR_SPP_CONV 118 #define CONV_BAD_IP_PROTOCOL 1 +#define GENERATOR_SPP_ROGUE_AP 200 +#define ROGUE_AP_DETECTED 1 + +#define GENERATOR_SPP_ANTISTUMBLER 201 +#define STUMBLER_DETECTED 1 + /* ** HttpInspect Generator IDs ** Index: snort/src/log.c diff -u snort/src/log.c:1.1.1.5 snort/src/log.c:1.6 --- snort/src/log.c:1.1.1.5 Sun Apr 24 22:11:04 2005 +++ snort/src/log.c Sun Apr 24 22:56:30 2005 @@ -548,6 +548,13 @@ PrintWifiHeader(fp, p); break; #endif + +#ifdef DLT_PRISM_HEADER + case DLT_PRISM_HEADER: + if(p && p->wifih) + PrintWifiHeader(fp, p); + break; +#endif case DLT_IEEE802: /* Token Ring */ if(p && p->trh) PrintTrHeader(fp, p); Index: snort/src/parser.c diff -u snort/src/parser.c:1.1.1.14 snort/src/parser.c:1.15 --- snort/src/parser.c:1.1.1.14 Mon Apr 25 03:26:08 2005 +++ snort/src/parser.c Mon Apr 25 13:05:05 2005 @@ -60,6 +60,9 @@ #include "event_queue.h" #include "asn1.h" + + + ListHead Alert; /* Alert Block Header */ ListHead Log; /* Log Block Header */ ListHead Pass; /* Pass Block Header */ @@ -117,6 +120,7 @@ RuleTreeNode *GetDynamicRTN(int, RuleTreeNode *); OptTreeNode *GetDynamicOTN(int, RuleTreeNode *); void AddrToFunc(RuleTreeNode *, int); +void MacAddrToFunc(RuleTreeNode *, int); void PortToFunc(RuleTreeNode *, int, int, int); void SetupRTNFuncList(RuleTreeNode *); @@ -421,6 +425,7 @@ while(rule != NULL) { + DumpChain(rule->RuleList->WifiList, rule->name, "WIFI Chains"); DumpChain(rule->RuleList->IpList, rule->name, "IP Chains"); DumpChain(rule->RuleList->TcpList, rule->name, "TCP Chains"); DumpChain(rule->RuleList->UdpList, rule->name, "UDP Chains"); @@ -445,6 +450,7 @@ while(rule != NULL) { + IntegrityCheck(rule->RuleList->WifiList, rule->name, "WIFI Chains"); IntegrityCheck(rule->RuleList->IpList, rule->name, "IP Chains"); IntegrityCheck(rule->RuleList->TcpList, rule->name, "TCP Chains"); IntegrityCheck(rule->RuleList->UdpList, rule->name, "UDP Chains"); @@ -690,7 +696,38 @@ } else {*/ + + if(protocol == DLT_IEEE802_11){ + proto_node.is_wifi = 1; + proto_node.sip = NULL; + proto_node.dip = NULL; + ProcessMAC(toks[2], &proto_node, SRC); /* get src mac */ + /* New in version 1.3: support for bidirectional rules */ + /* + * this checks the rule "direction" token and sets the bidirectional flag + * if the token = '<>' + */ + if(!strncmp("<>", toks[3], 2)) + { + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Bidirectional rule!\n");); + proto_node.flags |= BIDIRECTIONAL; + } + + /* changed version 1.8.4 + * Die when someone has tried to define a rule character other than + -> or <> + */ + if(!strcmp("->", toks[3]) && !strcmp("<>", toks[3])) + { + FatalError("%s(%d): Illegal direction specifier: %s", toks[3]); + } + ProcessMAC(toks[4], &proto_node, DST); /* get dst mac */ + + } + else{ + proto_node.is_wifi = 0; ProcessIP(toks[2], &proto_node, SRC); + /*}*/ /* check to make sure that the user entered port numbers */ @@ -766,6 +803,8 @@ if(proto_node.not_dp_flag) proto_node.flags |= EXCEPT_DST_PORT; + } + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"proto_node.flags = 0x%X\n", proto_node.flags);); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Processing Head Node....\n");); @@ -881,6 +920,10 @@ rtn_idx = list->IpList; break; + case DLT_IEEE802_11: + rtn_idx = list->WifiList; + break; + default: rtn_idx = NULL; break; @@ -926,6 +969,12 @@ rtn_tmp = list->IpList; break; + case DLT_IEEE802_11: + list->WifiList = (RuleTreeNode *) calloc(sizeof(RuleTreeNode), sizeof(char)); + rtn_tmp = list->WifiList; + break; + + } /* copy the prototype header data into the new node */ @@ -1200,6 +1249,12 @@ } else { + if(rtn->is_wifi){ + MacAddrToFunc(rtn, SRC); + MacAddrToFunc(rtn, DST); + + } + else{ /* Attach the proper port checking function to the function list */ /* * the in-line "if's" check to see if the "any" or "not" flags have @@ -1219,7 +1274,7 @@ /* last verse, same as the first (but for dest IP) ;) */ AddrToFunc(rtn, DST); } - + } DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"RuleListEnd\n");); /* tack the end (success) function to the list */ @@ -1276,6 +1331,36 @@ +void MacAddrToFunc(RuleTreeNode *rtn, int mode){ + /* + * if IP and mask are both 0, this is a "any" IP and we don't need to + * check it + */ + switch(mode) + { + case SRC: + if((rtn->flags & ANY_SRC_MAC) == 0) + { + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"CheckSrcMAC -> ");); + AddRuleFuncToList(CheckSrcMAC, rtn); + } + + break; + + case DST: + if((rtn->flags & ANY_DST_MAC) == 0) + { + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"CheckDstMAC -> ");); + AddRuleFuncToList(CheckDstMAC, rtn); + } + + break; + } +} + + + + /**************************************************************************** * * Function: PortToFunc(RuleTreeNode *, int, int, int) @@ -2019,6 +2104,13 @@ if(!strcasecmp(proto_str, "arp")) return ETHERNET_TYPE_ARP; + if(!strcasecmp(proto_str, "wifi")){ +#ifdef DEBUG + fprintf(stderr, "WhichProto() returning: DLT_IEEE802_11\n"); +#endif + return DLT_IEEE802_11; +#warning "need to make a REAL protocol #define for wifi" + } /* * if we've gotten here, we have a protocol string we din't recognize and * should exit @@ -2151,6 +2243,7 @@ + IpAddrSet *AllocAddrNode(RuleTreeNode *rtn, int mode) { IpAddrSet *idx; /* indexing pointer */ @@ -2216,6 +2309,217 @@ return NULL; } + +MacAddrSet *AllocMacAddrNode(RuleTreeNode *rtn, int mode){ + MacAddrSet *idx; + + switch(mode) + { + case SRC: + if(rtn->smac == NULL){ + rtn->smac = (MacAddrSet *)calloc(sizeof(MacAddrSet), sizeof(char)); + if(rtn->smac == NULL){ + FatalError(" Unable to allocate node for MAC list\n"); + } + return rtn->smac; + } + else{ + idx = rtn->smac; + + while(idx->next != NULL){ + idx = idx->next; + } + + idx->next = (MacAddrSet *)calloc(sizeof(MacAddrSet), sizeof(char)); + if(idx->next == NULL){ + FatalError(" Unable to allocate node for MAC list\n"); + } + return idx->next; + } + break; + + case DST: + if(rtn->dmac == NULL){ + + rtn->dmac = (MacAddrSet *)calloc(sizeof(MacAddrSet), sizeof(char)); + if(rtn->dmac == NULL){ + FatalError(" Unable to allocate node for MAC list\n"); + } + return rtn->dmac; + } + else{ + idx = rtn->dmac; + + while(idx->next != NULL){ + idx = idx->next; + } + + idx->next = (MacAddrSet *)calloc(sizeof(MacAddrSet), sizeof(char)); + if(idx->next == NULL){ + FatalError(" Unable to allocate node for MAC list\n"); + } + return idx->next; + } + break; + } + return NULL; +} + + + + +int ProcessMAC(char *addr, RuleTreeNode *rtn, int mode){ + + char **toks = NULL; + int num_toks; + int i; + MacAddrSet *tmp_addr; + char *tmp; + char *enbracket; + + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Got MAC address string: %s\n", + addr);); + + if(*addr == '!') + { + switch(mode) + { + case SRC: + rtn->flags |= EXCEPT_SRC_MAC; + break; + + case DST: + rtn->flags |= EXCEPT_DST_MAC; + break; + } + + addr++; + } + + if(*addr == '$') + { + if((tmp = VarGet(addr + 1)) == NULL) + { + FatalError("%s(%d) => Undefined variable %s\n", file_name, + file_line, addr); + } + } + else + { + tmp = addr; + } + + /* check to see if the first char is a + * bracket, which signifies a list + */ + if(*tmp == '[') + { + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Found MAC list!\n");); + + /* *(tmp+strlen(tmp)) = ' ';*/ + enbracket = strrchr(tmp, (int)']'); /* null out the en-bracket */ + if(enbracket) *enbracket = '\x0'; + + toks = mSplit(tmp+1, ",", 128, &num_toks, 0); + + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"mSplit got %d tokens...\n", + num_toks);); + + for(i=0; i< num_toks; i++) + { + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"adding %s to MAC " + "address list\n", toks[i]);); + tmp = toks[i]; + while (isspace((int)*tmp)||*tmp=='[') tmp++; + enbracket = strrchr(tmp, (int)']'); /* null out the en-bracket */ + if(enbracket) *enbracket = '\x0'; + + if (strlen(tmp) == 0) + continue; + + tmp_addr = AllocMacAddrNode(rtn, mode); + if(ParseMAC(tmp, tmp_addr)) + { + switch(mode) + { + case SRC: + rtn->flags |= ANY_SRC_MAC; + break; + + case DST: + rtn->flags |= ANY_DST_MAC; + break; + } + } + } + + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Freeing %d tokens...\n", + num_toks);); + + for(i=0;iflags |= ANY_SRC_MAC; + break; + + case DST: + rtn->flags |= ANY_DST_MAC; + break; + } + } + } + + return 0; +} + + +int ParseMAC(char *paddr, MacAddrSet *address_data){ + int i = 0; + char *str, *next, *addr; + + addr = paddr; + if(*addr == '!'){ + address_data->addr_flags |= EXCEPT_MAC; + addr++; + } + + if(!strcasecmp(addr, "any")){ + memset(address_data, 0x00, sizeof(MacAddrSet)); + return 1; + } + + str = paddr; + next = str; + + while(*next){ + if((address_data->mac_addr[i] = strtol(str, &next, 16)) > 255){ + FatalError("%s(%d) => Unrecognized MAC address %s\n", file_name, file_line, addr); + } + if(str != next && i < 6){ + str = next + 1; + i++; + } + else + FatalError("%s(%d) => Unrecognized MAC address %s\n", file_name, file_line, addr); + } + return 0; +} + + + + /**************************************************************************** * * Function: ParsePort(char *, u_short *) @@ -2636,6 +2940,9 @@ rtn->type = rule->type; rtn->sip = rule->sip; rtn->dip = rule->dip; + rtn->is_wifi = rule->is_wifi; + rtn->smac = rule->smac; + rtn->dmac = rule->dmac; rtn->hsp = rule->hsp; rtn->lsp = rule->lsp; rtn->hdp = rule->hdp; Index: snort/src/plugbase.c diff -u snort/src/plugbase.c:1.1.1.8 snort/src/plugbase.c:1.14 --- snort/src/plugbase.c:1.1.1.8 Mon Apr 25 03:26:10 2005 +++ snort/src/plugbase.c Mon Apr 25 13:05:05 2005 @@ -62,6 +62,8 @@ #include "preprocessors/spp_flow.h" #include "preprocessors/spp_sfportscan.h" #include "preprocessors/spp_xlink2state.h" +#include "preprocessors/spp_rogue_ap.h" +#include "preprocessors/spp_antistumbler.h" /* built-in detection plugins */ #include "detection-plugins/sp_pattern_match.h" @@ -97,6 +99,24 @@ #endif +#include "detection-plugins/sp_wifi_type.h" +#include "detection-plugins/sp_wifi_stype.h" +#include "detection-plugins/sp_wifi_to_ds.h" +#include "detection-plugins/sp_wifi_from_ds.h" +#include "detection-plugins/sp_wifi_more_frags.h" +#include "detection-plugins/sp_wifi_retry.h" +#include "detection-plugins/sp_wifi_pwr_mgmt.h" +#include "detection-plugins/sp_wifi_more_data.h" +#include "detection-plugins/sp_wifi_wep.h" +#include "detection-plugins/sp_wifi_order.h" +#include "detection-plugins/sp_wifi_frame_control.h" +#include "detection-plugins/sp_wifi_duration_id.h" +#include "detection-plugins/sp_wifi_bssid.h" +#include "detection-plugins/sp_wifi_seqnum.h" +#include "detection-plugins/sp_wifi_fragnum.h" +#include "detection-plugins/sp_wifi_addr4.h" +#include "detection-plugins/sp_wifi_ssid.h" + /* built-in output plugins */ #include "output-plugins/spo_alert_syslog.h" #include "output-plugins/spo_log_tcpdump.h" @@ -161,6 +181,24 @@ SetupReact(); SetupRespond(); #endif + + SetupWifiType(); + SetupWifiStype(); + SetupWifiToDs(); + SetupWifiFromDs(); + SetupWifiMoreFrags(); + SetupWifiRetry(); + SetupWifiPwrMgmt(); + SetupWifiMoreData(); + SetupWifiWep(); + SetupWifiOrder(); + SetupWifiFrameControl(); + SetupWifiDurationId(); + SetupWifiBssid(); + SetupWifiSeqNum(); + SetupWifiFragNum(); + SetupWifiAddr4(); + SetupWifiSsid(); } /**************************************************************************** @@ -412,6 +450,8 @@ SetupFlow(); SetupPsng(); SetupXLINK2STATE(); + SetupRogueAp(); + SetupAntiStumbler(); } /**************************************************************************** @@ -843,6 +883,16 @@ /************************** Miscellaneous Functions **************************/ + +int PacketIsWIFI(Packet *p) +{ + if(p->wifih != NULL) + return 1; + + return 0; +} + + int PacketIsIP(Packet * p) { Index: snort/src/plugbase.h diff -u snort/src/plugbase.h:1.1.1.6 snort/src/plugbase.h:1.7 --- snort/src/plugbase.h:1.1.1.6 Sun Apr 24 22:11:13 2005 +++ snort/src/plugbase.h Sun Apr 24 22:56:31 2005 @@ -163,6 +163,7 @@ } PluginSignalFuncNode; +int PacketIsWIFI(Packet *); int PacketIsIP(Packet *); int PacketIsTCP(Packet *); int PacketIsUDP(Packet *); Index: snort/src/plugin_enum.h diff -u snort/src/plugin_enum.h:1.1.1.2 snort/src/plugin_enum.h:1.8 --- snort/src/plugin_enum.h:1.1.1.2 Thu Mar 10 13:13:47 2005 +++ snort/src/plugin_enum.h Fri Mar 11 10:54:29 2005 @@ -34,4 +34,21 @@ PLUGIN_TTL_CHECK, PLUGIN_BYTE_TEST, PLUGIN_PCRE, + PLUGIN_WIFI_TYPE_CHECK, + PLUGIN_WIFI_STYPE_CHECK, + PLUGIN_WIFI_TO_DS_CHECK, + PLUGIN_WIFI_FROM_DS_CHECK, + PLUGIN_WIFI_MORE_FRAGS_CHECK, + PLUGIN_WIFI_RETRY_CHECK, + PLUGIN_WIFI_PWR_MGMT_CHECK, + PLUGIN_WIFI_MORE_DATA_CHECK, + PLUGIN_WIFI_WEP_CHECK, + PLUGIN_WIFI_ORDER_CHECK, + PLUGIN_WIFI_FRAME_CONTROL_CHECK, + PLUGIN_WIFI_DURATION_ID_CHECK, + PLUGIN_WIFI_BSSID_CHECK, + PLUGIN_WIFI_SEQNUM_CHECK, + PLUGIN_WIFI_FRAGNUM_CHECK, + PLUGIN_WIFI_ADDR4_CHECK, + PLUGIN_WIFI_SSID_CHECK }; Index: snort/src/rules.h diff -u snort/src/rules.h:1.1.1.6 snort/src/rules.h:1.7 --- snort/src/rules.h:1.1.1.6 Sun Apr 24 22:11:14 2005 +++ snort/src/rules.h Sun Apr 24 22:56:31 2005 @@ -70,6 +70,15 @@ #define EXCEPT_IP 0x01 +#define EXCEPT_SRC_MAC 0x01 +#define EXCEPT_DST_MAC 0x02 +#define EXCEPT_BSSID_MAC 0x04 +#define ANY_SRC_MAC 0x08 +#define ANY_DST_MAC 0x10 +#define ANY_BSSID_MAC 0x20 + +#define EXCEPT_MAC 0x01 + #define R_FIN 0x01 #define R_SYN 0x02 #define R_RST 0x04 @@ -233,6 +242,15 @@ } IpAddrSet; #endif /* RELOCATED to parser/IpAddrSet.h */ + +/* #warning "Move _MacAddrSet to parser/MacAddrSet.h at some point" */ +typedef struct _MacAddrSet{ + u_int8_t mac_addr[6]; + u_int8_t addr_flags; + + struct _MacAddrSet *next; +} MacAddrSet; + typedef struct _RuleTreeNode { RuleFpList *rule_func; /* match functions.. (Bidirectional etc.. ) */ @@ -240,10 +258,14 @@ int head_node_number; int type; + int is_wifi; IpAddrSet *sip; IpAddrSet *dip; + MacAddrSet *smac; + MacAddrSet *dmac; + int not_sp_flag; /* not source port flag */ u_short hsp; /* hi src port */ @@ -278,6 +300,7 @@ RuleTreeNode *TcpList; RuleTreeNode *UdpList; RuleTreeNode *IcmpList; + RuleTreeNode *WifiList; struct _OutputFuncNode *LogList; struct _OutputFuncNode *AlertList; struct _RuleListNode *ruleListNode; Index: snort/src/snort.c diff -u snort/src/snort.c:1.1.1.9 snort/src/snort.c:1.9 --- snort/src/snort.c:1.1.1.9 Sun Apr 24 22:11:18 2005 +++ snort/src/snort.c Sun Apr 24 22:56:31 2005 @@ -1504,6 +1504,19 @@ grinder = DecodeIEEE80211Pkt; break; #endif + +#ifdef DLT_PRISM_HEADER + case DLT_PRISM_HEADER: + if(!pv.readmode_flag){ + if(!pv.quiet_flag) + LogMessage("Decoding IEEE 802.11 with PRISM headers on interface %s\n", + PRINT_INTERFACE(pv.interface)); + } + + grinder = DecodePrismHdr; + break; +#endif + case 13: case DLT_IEEE802: /* Token Ring */ if(!pv.readmode_flag) Index: snort/src/detection-plugins/Makefile.am diff -u snort/src/detection-plugins/Makefile.am:1.1.1.4 snort/src/detection-plugins/Makefile.am:1.12 --- snort/src/detection-plugins/Makefile.am:1.1.1.4 Sun Apr 24 00:25:25 2005 +++ snort/src/detection-plugins/Makefile.am Sun Apr 24 01:20:39 2005 @@ -15,7 +15,25 @@ sp_tcp_flag_check.h sp_tcp_flag_check.c sp_tcp_seq_check.c sp_tcp_seq_check.h \ sp_tcp_win_check.c sp_tcp_win_check.h sp_ttl_check.c sp_ttl_check.h \ sp_clientserver.c sp_clientserver.h sp_byte_check.c sp_byte_check.h \ -sp_byte_jump.c sp_byte_jump.h sp_pcre.c sp_pcre.h sp_isdataat.c sp_isdataat.h \ -sp_flowbits.c sp_flowbits.h sp_asn1.c sp_asn1.h +sp_byte_jump.c sp_byte_jump.h sp_pcre.c sp_pcre.h sp_isdataat.c sp_isdataat.h \ +sp_flowbits.c sp_flowbits.h sp_asn1.c sp_asn1.h \ +sp_wifi_type.c sp_wifi_type.h \ +sp_wifi_stype.c sp_wifi_stype.h \ +sp_wifi_to_ds.c sp_wifi_to_ds.h \ +sp_wifi_from_ds.c sp_wifi_from_ds.h \ +sp_wifi_more_frags.c sp_wifi_more_frags.h \ +sp_wifi_retry.c sp_wifi_retry.h \ +sp_wifi_pwr_mgmt.c sp_wifi_pwr_mgmt.h \ +sp_wifi_more_data.c sp_wifi_more_data.h \ +sp_wifi_wep.c sp_wifi_wep.h \ +sp_wifi_order.c sp_wifi_order.h \ +sp_wifi_frame_control.c sp_wifi_frame_control.h \ +sp_wifi_duration_id.c sp_wifi_duration_id.h \ +sp_wifi_bssid.c sp_wifi_bssid.h \ +sp_wifi_seqnum.c sp_wifi_seqnum.h \ +sp_wifi_fragnum.c sp_wifi_fragnum.h \ +sp_wifi_addr4.c sp_wifi_addr4.h \ +sp_wifi_ssid.c sp_wifi_ssid.h \ +wifi_datatypes.h INCLUDES = @INCLUDES@ Index: snort/src/detection-plugins/sp_wifi_addr4.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_addr4.c:1.3 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_addr4.c Mon Aug 25 21:37:21 2003 @@ -0,0 +1,248 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_addr4.c,v 1.3 2003/08/26 01:37:21 andrew Exp $ */ + +/* sp_wifi_addr4 + * + * Purpose: + * + * Tests 802.11 frames 4th address field. + * + * Arguments: + * + * {{ '!' | {} } } + * + * Effect: + * + * Success on address field match, failure otherwise. + * + */ + +#include +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + +#include "wifi_datatypes.h" + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiAddr4Data +{ + u_int8_t addr4[6]; + u_int8_t not_flag; +} WifiAddr4Data; + +void WifiAddr4Init(char *, OptTreeNode *, int); +void WifiAddr4RuleParseFunction(char *, OptTreeNode *); +int WifiAddr4DetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiAddr4() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiAddr4() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("addr4", WifiAddr4Init); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiAddr4 Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiAddr4Init(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiAddr4Init(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_ADDR4_CHECK] = (WifiAddr4Data *) calloc(sizeof(WifiAddr4Data), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiAddr4RuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiAddr4DetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiAddr4RuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiAddr4RuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiAddr4Data *ds_ptr; /* data struct pointer */ + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_ADDR4_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + ds_ptr->not_flag = 1; + data++; + } + + /* set the final option arguments here */ + + if(WifiAddr4ParseMAC(ds_ptr->addr4, data) < 0) + FatalError("%s (%d) => Error parsing MAC address \"%s\"\n", file_name, file_line, data); +} + + + +/* + * Function: WifiAddr4ParseMAC(u_int8_t *, char *) + * + * Purpose: Parses BSSIDs from a character string and stores them + * in a byte array. + * + * Arguments: bssid => pointer to byte array to store parsed BSSID in + * mac_str => character string containing BSSID + * + * Returns: 0 on success, -1 on error + * + */ + +int WifiAddr4ParseMAC(u_int8_t *bssid, char *mac_str){ + + u_int64_t mac; + + if(strlen(mac_str) != 14) + return -1; + + mac = strtoll(mac_str, NULL, 16); + if(mac < 0 || mac > 0xffffffffffff) + return -1; + + bssid[0] = mac >> 40 & 0x00ff; + bssid[1] = mac >> 32 & 0x00ff; + bssid[2] = mac >> 24 & 0x00ff; + bssid[3] = mac >> 16 & 0x00ff; + bssid[4] = mac >> 8 & 0x00ff; + bssid[5] = mac & 0x00ff; + + return 0; +} + + + +/**************************************************************************** + * + * Function: WifiAddr4DetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiAddr4DetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiAddr4Data *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_ADDR4_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + if(p->wifih->type != TYPE_DATA || p->wifih->to_ds != 1 || p->wifih->from_ds != 1){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Frame does not contain addr4 field\n");); + return 0; + } + + /* your detection function tests go here */ + if((plugin_data->not_flag && (memcmp(p->wifih->addr3, plugin_data->addr4, 6) != 0)) || + (!plugin_data->not_flag && (memcmp(p->wifih->addr3, plugin_data->addr4, 6) == 0))) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} + + + Index: snort/src/detection-plugins/sp_wifi_addr4.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_addr4.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_addr4.h Fri Jul 25 18:59:09 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_addr4.h,v 1.1 2003/07/25 22:59:09 andrew Exp $ */ + +#ifndef __SP_WIFI_ADDR4_H__ +#define __SP_WIFI_ADDR4_H__ + +void SetupWifiAddr4(); + +#endif /* __SP_WIFI_ADDR4_H__ */ Index: snort/src/detection-plugins/sp_wifi_bssid.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_bssid.c:1.6 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_bssid.c Sun Aug 24 02:45:32 2003 @@ -0,0 +1,290 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_bssid.c,v 1.6 2003/08/24 06:45:32 andrew Exp $ */ + +/* sp_wifi_bssid + * + * Purpose: + * + * Tests 802.11 frames BSSID. + * + * Arguments: + * + * {{ '!' | {} } } + * + * Effect: + * + * Success on BSSID match, failure otherwise. + * + */ + +#include +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + +#include "wifi_datatypes.h" + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiBssidData +{ + u_int8_t bssid[6]; + u_int8_t not_flag; +} WifiBssidData; + +void WifiBssidInit(char *, OptTreeNode *, int); +void WifiBssidRuleParseFunction(char *, OptTreeNode *); +int WifiBssidDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiBssid() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiBssid() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("bssid", WifiBssidInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiBssid Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiBssidInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiBssidInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_BSSID_CHECK] = (WifiBssidData *) calloc(sizeof(WifiBssidData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiBssidRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiBssidDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiBssidRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiBssidRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiBssidData *ds_ptr; /* data struct pointer */ + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_BSSID_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + ds_ptr->not_flag = 1; + data++; + } + + /* set the final option arguments here */ + + if(WifiBssidParseBSSID(ds_ptr->bssid, data) < 0) + FatalError("%s (%d) => Error parsing BSSID \"%s\"\n", file_name, file_line, data); +} + + + +/* + * Function: WifiBssidParseBSSID(u_int8_t *, char *) + * + * Purpose: Parses BSSIDs from a character string and stores them + * in a byte array. + * + * Arguments: bssid => pointer to byte array to store parsed BSSID in + * mac_str => character string containing BSSID + * + * Returns: 0 on success, -1 on error + * + */ + +int WifiBssidParseBSSID(u_int8_t *bssid, char *mac_str){ + + u_int64_t mac; + + if(strlen(mac_str) != 14) + return -1; + + mac = strtoll(mac_str, NULL, 16); + if(mac < 0 || mac > 0xffffffffffff) + return -1; + + bssid[0] = mac >> 40 & 0x00ff; + bssid[1] = mac >> 32 & 0x00ff; + bssid[2] = mac >> 24 & 0x00ff; + bssid[3] = mac >> 16 & 0x00ff; + bssid[4] = mac >> 8 & 0x00ff; + bssid[5] = mac & 0x00ff; + + return 0; +} + + + +/**************************************************************************** + * + * Function: WifiBssidDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiBssidDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiBssidData *plugin_data; + u_int8_t *bssid; + plugin_data = otn->ds_list[PLUGIN_WIFI_BSSID_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + switch(p->wifih->type){ /* point bssid to the correct field in the frame */ + + case TYPE_MANAGEMENT: + bssid = p->wifih->addr3; + break; + + case TYPE_CONTROL: + if(p->wifih->stype == STYPE_RTS || p->wifih->stype == STYPE_CTS || p->wifih->stype == STYPE_ACK){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Received Control frame subtype that does not contain BSSID\n");); + return 0; + } + else if(p->wifih->stype == STYPE_PS) + bssid = p->wifih->addr1; + else if(p->wifih->stype == STYPE_CFEND) + bssid = p->wifih->addr2; + else if(p->wifih->stype == STYPE_CFEND_CFACK) + bssid = p->wifih->addr2; + else{ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Received Control frame with unknown/invalid subtype\n");); + return 0; + } + break; + + case TYPE_DATA: + if(p->wifih->to_ds){ + if(p->wifih->from_ds){ /* to_ds == 1 && from_ds == 1 */ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Received Data frame subtype that does not contain BSSID\n");); + return 0; + } + else /* to_ds == 1 && from_ds == 0 */ + bssid = p->wifih->addr1; + } + else{ + if(p->wifih->from_ds) /* to_ds == 0 && from_ds == 1 */ + bssid = p->wifih->addr2; + else /* to_ds == 0 && from_ds == 0 */ + bssid = p->wifih->addr3; + } + break; + + default: + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Received frame with unknown/invalid type\n");); + return 0; + } + + + /* your detection function tests go here */ + if((plugin_data->not_flag && (memcmp(bssid, plugin_data->bssid, 6) != 0)) || + (!plugin_data->not_flag && (memcmp(bssid, plugin_data->bssid, 6) == 0))) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} + + + Index: snort/src/detection-plugins/sp_wifi_bssid.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_bssid.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_bssid.h Thu Jul 24 02:20:23 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_bssid.h,v 1.1 2003/07/24 06:20:23 andrew Exp $ */ + +#ifndef __SP_WIFI_BSSID_H__ +#define __SP_WIFI_BSSID_H__ + +void SetupWifiBssid(); + +#endif /* __SP_WIFI_BSSID_H__ */ Index: snort/src/detection-plugins/sp_wifi_duration_id.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_duration_id.c:1.3 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_duration_id.c Sat Jul 26 21:29:22 2003 @@ -0,0 +1,220 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_duration_id.c,v 1.3 2003/07/27 01:29:22 andrew Exp $ */ + +/* sp_wifi_duration_id + * + * Purpose: + * + * Tests 802.11 frames duration_id field. + * + * Arguments: + * + * {{ '!' | {} } { 0 <= n <= 65535 } } + * + * Effect: + * + * Success on duration_id field match, failure otherwise. + * + */ + +#include +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + +#include "wifi_datatypes.h" + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiDurationIdData +{ + u_int16_t duration_id; + u_int8_t not_flag; +} WifiDurationIdData; + +void WifiDurationIdInit(char *, OptTreeNode *, int); +void WifiDurationIdRuleParseFunction(char *, OptTreeNode *); +int WifiDurationIdDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiDurationId() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiDurationId() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("duration_id", WifiDurationIdInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiDurationId Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiDurationIdInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiDurationIdInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_DURATION_ID_CHECK] = (WifiDurationIdData *) calloc(sizeof(WifiDurationIdData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiDurationIdRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiDurationIdDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiDurationIdRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiDurationIdRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiDurationIdData *ds_ptr; /* data struct pointer */ + unsigned long val = 1 << 16; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_DURATION_ID_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + ds_ptr->not_flag = 1; + data++; + } + + /* set the final option arguments here */ + + if(*data){ + if(strncmp(data, "0x", 2) == 0) + val = strtoul(data, NULL, 16); /* use strtoul so people don't have to do + sign-extended 2's complement hex*/ + else + val = strtol(data, NULL, 10); + } + + if(val < 0 || val > 65535) + FatalError("%s(%d) => duration_id value out of range \"%s\"\n", + file_name, file_line, data); + + ds_ptr->duration_id = val; +} + + +/**************************************************************************** + * + * Function: WifiDurationIdDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiDurationIdDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiDurationIdData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_DURATION_ID_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + if(p->wifih->type == TYPE_CONTROL && p->wifih->stype == STYPE_PS){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "duration_id field not present\n");); + return 0; + } + + /* your detection function tests go here */ + if((plugin_data->not_flag && (p->wifih->duration_id != plugin_data->duration_id)) || + (!plugin_data->not_flag && (p->wifih->duration_id == plugin_data->duration_id))) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_duration_id.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_duration_id.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_duration_id.h Thu Jul 24 02:20:23 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_duration_id.h,v 1.1 2003/07/24 06:20:23 andrew Exp $ */ + +#ifndef __SP_WIFI_DURATION_ID_H__ +#define __SP_WIFI_DURATION_ID_H__ + +void SetupWifiDurationId(); + +#endif /* __SP_WIFI_DURATION_ID_H__ */ Index: snort/src/detection-plugins/sp_wifi_fragnum.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_fragnum.c:1.3 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_fragnum.c Sat Jul 26 21:32:50 2003 @@ -0,0 +1,222 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_fragnum.c,v 1.3 2003/07/27 01:32:50 andrew Exp $ */ + +/* sp_wifi_fragnum + * + * Purpose: + * + * Tests 802.11 frames fragnum control field. + * + * Arguments: + * + * {{ '!' | {} } { 0 <= n <= 15 } } + * + * n may be specified in either hex or decimal + * + * Effect: + * + * Success on fragnum control field match, failure otherwise. + * + */ + +#include +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + +#include "wifi_datatypes.h" + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiFragNumData +{ + u_int16_t fragnum; + u_int8_t not_flag; +} WifiFragNumData; + +void WifiFragNumInit(char *, OptTreeNode *, int); +void WifiFragNumRuleParseFunction(char *, OptTreeNode *); +int WifiFragNumDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiFragNum() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiFragNum() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("fragnum", WifiFragNumInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiFragNum Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiFragNumInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiFragNumInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_FRAGNUM_CHECK] = (WifiFragNumData *) calloc(sizeof(WifiFragNumData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiFragNumRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiFragNumDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiFragNumRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiFragNumRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiFragNumData *ds_ptr; /* data struct pointer */ + unsigned long val = 1 << 4; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_FRAGNUM_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + ds_ptr->not_flag = 1; + data++; + } + + /* set the final option arguments here */ + + if(*data){ + if(strncmp(data, "0x", 2) == 0) + val = strtoul(data, NULL, 16); /* use strtoul so people don't have to do + sign-extended 2's complement hex*/ + else + val = strtol(data, NULL, 10); + } + + if(val < 0 || val > 15) + FatalError("%s(%d) => fragnum value out of range \"%s\"\n", + file_name, file_line, data); + + ds_ptr->fragnum = val; +} + + +/**************************************************************************** + * + * Function: WifiFragNumDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiFragNumDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiFragNumData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_FRAGNUM_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + if(p->wifih->type == TYPE_CONTROL){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Frame is TYPE_CONTROL\n");); + return 0; + } + + /* your detection function tests go here */ + if((plugin_data->not_flag && (p->wifih->fragnum != plugin_data->fragnum)) || + (!plugin_data->not_flag && (p->wifih->fragnum == plugin_data->fragnum))) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_fragnum.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_fragnum.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_fragnum.h Fri Jul 25 06:02:56 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_fragnum.h,v 1.1 2003/07/25 10:02:56 andrew Exp $ */ + +#ifndef __SP_WIFI_FRAGNUM_H__ +#define __SP_WIFI_FRAGNUM_H__ + +void SetupWifiFragNum(); + +#endif /* __SP_WIFI_FRAGNUM_H__ */ Index: snort/src/detection-plugins/sp_wifi_frame_control.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_frame_control.c:1.4 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_frame_control.c Sat Jul 26 21:32:50 2003 @@ -0,0 +1,215 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_frame_control.c,v 1.4 2003/07/27 01:32:50 andrew Exp $ */ + +/* sp_wifi_frame_control + * + * Purpose: + * + * Tests 802.11 frames frame_control field. + * + * Arguments: + * + * {{ '!' | {} } { 0 <= n <= 65535 } } + * + * n may be specified in either hex or decimal + * + * Effect: + * + * Success on frame_control field match, failure otherwise. + * + */ + +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiFrameControlData +{ + u_int16_t frame_control; + u_int8_t not_flag; +} WifiFrameControlData; + +void WifiFrameControlInit(char *, OptTreeNode *, int); +void WifiFrameControlRuleParseFunction(char *, OptTreeNode *); +int WifiFrameControlDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiFrameControl() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiFrameControl() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("frame_control", WifiFrameControlInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiFrameControl Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiFrameControlInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiFrameControlInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_FRAME_CONTROL_CHECK] = (WifiFrameControlData *) calloc(sizeof(WifiFrameControlData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiFrameControlRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiFrameControlDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiFrameControlRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiFrameControlRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiFrameControlData *ds_ptr; /* data struct pointer */ + unsigned long val = 1 << 16; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_FRAME_CONTROL_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + ds_ptr->not_flag = 1; + data++; + } + + /* set the final option arguments here */ + + if(*data) + if(strncmp(data, "0x", 2) == 0) + val = strtoul(data, NULL, 16); /* use strtoul so people don't have to do + sign-extended 2's complement hex*/ + else + val = strtol(data, NULL, 10); + + + if(val < 0 || val > 65535) + FatalError("%s(%d) => frame_control value out of range \"%s\"\n", + file_name, file_line, data); + + ds_ptr->frame_control = val; +} + + +/**************************************************************************** + * + * Function: WifiFrameControlDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiFrameControlDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiFrameControlData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_FRAME_CONTROL_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + /* your detection function tests go here */ + if((plugin_data->not_flag && (p->wifih->frame_control != plugin_data->frame_control)) || + (!plugin_data->not_flag && (p->wifih->frame_control == plugin_data->frame_control))) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_frame_control.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_frame_control.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_frame_control.h Thu Jul 24 02:33:56 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_frame_control.h,v 1.1 2003/07/24 06:33:56 andrew Exp $ */ + +#ifndef __SP_WIFI_FRAME_CONTROL_H__ +#define __SP_WIFI_FRAME_CONTROL_H__ + +void SetupWifiFrameControl(); + +#endif /* __SP_WIFI_FRAME_CONTROL_H__ */ Index: snort/src/detection-plugins/sp_wifi_from_ds.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_from_ds.c:1.2 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_from_ds.c Fri Jul 25 05:13:46 2003 @@ -0,0 +1,218 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_from_ds.c,v 1.2 2003/07/25 09:13:46 andrew Exp $ */ + +/* sp_wifi_from_ds + * + * Purpose: + * + * Tests 802.11 frames from_ds control field. + * + * Arguments: + * + * {{ '!' | {} } { ON | OFF | TRUE | FALSE } } + * + * Effect: + * + * Success on from_ds match, failure otherwise. + * + */ + +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiFromDsData +{ + int val; +} WifiFromDsData; + +void WifiFromDsInit(char *, OptTreeNode *, int); +void WifiFromDsRuleParseFunction(char *, OptTreeNode *); +int WifiFromDsDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiFromDs() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiFromDs() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("from_ds", WifiFromDsInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiFromDs Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiFromDsInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiFromDsInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_FROM_DS_CHECK] = (WifiFromDsData *) calloc(sizeof(WifiFromDsData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiFromDsRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiFromDsDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiFromDsRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiFromDsRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiFromDsData *ds_ptr; /* data struct pointer */ + int not_flag = 0; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_FROM_DS_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + not_flag = 1; + data++; + } + + /* set the final option arguments here */ + if(strcmp(data, "FALSE") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "OFF") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "NO") == 0) + ds_ptr->val = 0; + + else if(strcmp(data, "TRUE") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "ON") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "YES") == 0) + ds_ptr->val = 1; + + else + FatalError("%s(%d) => Bad from_ds flag value \"%s\"\n", + file_name, file_line, data); + + if(not_flag) + ds_ptr->val = (ds_ptr->val) ? 0 : 1; + +} + + +/**************************************************************************** + * + * Function: WifiFromDsDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiFromDsDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiFromDsData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_FROM_DS_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + /* your detection function tests go here */ + if (p->wifih->from_ds == plugin_data->val) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_from_ds.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_from_ds.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_from_ds.h Thu Jul 24 02:20:23 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_from_ds.h,v 1.1 2003/07/24 06:20:23 andrew Exp $ */ + +#ifndef __SP_WIFI_FROM_DS_H__ +#define __SP_WIFI_FROM_DS_H__ + +void SetupWifiFromDs(); + +#endif /* __SP_WIFI_FROM_DS_H__ */ Index: snort/src/detection-plugins/sp_wifi_more_data.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_more_data.c:1.2 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_more_data.c Fri Jul 25 05:12:40 2003 @@ -0,0 +1,218 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_more_data.c,v 1.2 2003/07/25 09:12:40 andrew Exp $ */ + +/* sp_wifi_more_data + * + * Purpose: + * + * Tests 802.11 frames more_data control field. + * + * Arguments: + * + * {{ '!' | {} } { ON | OFF | TRUE | FALSE } } + * + * Effect: + * + * Success on more_data flag match, failure otherwise. + * + */ + +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiMoreDataData +{ + int val; +} WifiMoreDataData; + +void WifiMoreDataInit(char *, OptTreeNode *, int); +void WifiMoreDataRuleParseFunction(char *, OptTreeNode *); +int WifiMoreDataDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiMoreData() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiMoreData() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("more_data", WifiMoreDataInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiMoreData Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiMoreDataInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiMoreDataInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_MORE_DATA_CHECK] = (WifiMoreDataData *) calloc(sizeof(WifiMoreDataData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiMoreDataRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiMoreDataDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiMoreDataRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiMoreDataRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiMoreDataData *ds_ptr; /* data struct pointer */ + int not_flag = 0; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_MORE_DATA_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + not_flag = 1; + data++; + } + + /* set the final option arguments here */ + if(strcmp(data, "FALSE") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "OFF") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "NO") == 0) + ds_ptr->val = 0; + + else if(strcmp(data, "TRUE") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "ON") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "YES") == 0) + ds_ptr->val = 1; + + else + FatalError("%s(%d) => Bad more_data flag value \"%s\"\n", + file_name, file_line, data); + + if(not_flag) + ds_ptr->val = (ds_ptr->val) ? 0 : 1; + +} + + +/**************************************************************************** + * + * Function: WifiMoreDataDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiMoreDataDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiMoreDataData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_MORE_DATA_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + /* your detection function tests go here */ + if (p->wifih->more_data == plugin_data->val) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_more_data.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_more_data.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_more_data.h Thu Jul 24 02:20:23 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_more_data.h,v 1.1 2003/07/24 06:20:23 andrew Exp $ */ + +#ifndef __SP_WIFI_MORE_DATA_H__ +#define __SP_WIFI_MORE_DATA_H__ + +void SetupWifiMoreData(); + +#endif /* __SP_WIFI_MORE_DATA_H__ */ Index: snort/src/detection-plugins/sp_wifi_more_frags.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_more_frags.c:1.2 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_more_frags.c Fri Jul 25 05:10:54 2003 @@ -0,0 +1,218 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_more_frags.c,v 1.2 2003/07/25 09:10:54 andrew Exp $ */ + +/* sp_wifi_more_frags + * + * Purpose: + * + * Tests 802.11 frames more_frags control field. + * + * Arguments: + * + * {{ '!' | {} } { ON | OFF | TRUE | FALSE } } + * + * Effect: + * + * Success on more_frags flag match, failure otherwise. + * + */ + +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiMoreFragsData +{ + int val; +} WifiMoreFragsData; + +void WifiMoreFragsInit(char *, OptTreeNode *, int); +void WifiMoreFragsRuleParseFunction(char *, OptTreeNode *); +int WifiMoreFragsDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiMoreFrags() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiMoreFrags() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("more_frags", WifiMoreFragsInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiMoreFrags Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiMoreFragsInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiMoreFragsInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_MORE_FRAGS_CHECK] = (WifiMoreFragsData *) calloc(sizeof(WifiMoreFragsData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiMoreFragsRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiMoreFragsDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiMoreFragsRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiMoreFragsRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiMoreFragsData *ds_ptr; /* data struct pointer */ + int not_flag = 0; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_MORE_FRAGS_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + not_flag = 1; + data++; + } + + /* set the final option arguments here */ + if(strcmp(data, "FALSE") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "OFF") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "NO") == 0) + ds_ptr->val = 0; + + else if(strcmp(data, "TRUE") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "ON") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "YES") == 0) + ds_ptr->val = 1; + + else + FatalError("%s(%d) => Bad more_frags flag value \"%s\"\n", + file_name, file_line, data); + + if(not_flag) + ds_ptr->val = (ds_ptr->val) ? 0 : 1; + +} + + +/**************************************************************************** + * + * Function: WifiMoreFragsDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiMoreFragsDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiMoreFragsData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_MORE_FRAGS_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + /* your detection function tests go here */ + if (p->wifih->more_frags == plugin_data->val) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_more_frags.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_more_frags.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_more_frags.h Thu Jul 24 02:20:23 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_more_frags.h,v 1.1 2003/07/24 06:20:23 andrew Exp $ */ + +#ifndef __SP_WIFI_MORE_FRAGS_H__ +#define __SP_WIFI_MORE_FRAGS_H__ + +void SetupWifiMoreFrags(); + +#endif /* __SP_WIFI_MORE_FRAGS_H__ */ Index: snort/src/detection-plugins/sp_wifi_order.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_order.c:1.2 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_order.c Fri Jul 25 05:09:34 2003 @@ -0,0 +1,218 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_order.c,v 1.2 2003/07/25 09:09:34 andrew Exp $ */ + +/* sp_wifi_order + * + * Purpose: + * + * Tests 802.11 frames order control field. + * + * Arguments: + * + * {{ '!' | {} } { ON | OFF | TRUE | FALSE } } + * + * Effect: + * + * Success on order flag match, failure otherwise. + * + */ + +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiOrderData +{ + int val; +} WifiOrderData; + +void WifiOrderInit(char *, OptTreeNode *, int); +void WifiOrderRuleParseFunction(char *, OptTreeNode *); +int WifiOrderDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiOrder() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiOrder() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("order", WifiOrderInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiOrder Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiOrderInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiOrderInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_ORDER_CHECK] = (WifiOrderData *) calloc(sizeof(WifiOrderData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiOrderRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiOrderDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiOrderRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiOrderRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiOrderData *ds_ptr; /* data struct pointer */ + int not_flag = 0; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_ORDER_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + not_flag = 1; + data++; + } + + /* set the final option arguments here */ + if(strcmp(data, "FALSE") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "OFF") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "NO") == 0) + ds_ptr->val = 0; + + else if(strcmp(data, "TRUE") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "ON") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "YES") == 0) + ds_ptr->val = 1; + + else + FatalError("%s(%d) => Bad order flag value \"%s\"\n", + file_name, file_line, data); + + if(not_flag) + ds_ptr->val = (ds_ptr->val) ? 0 : 1; + +} + + +/**************************************************************************** + * + * Function: WifiOrderDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiOrderDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiOrderData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_ORDER_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + /* your detection function tests go here */ + if (p->wifih->order == plugin_data->val) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_order.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_order.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_order.h Thu Jul 24 02:20:23 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_order.h,v 1.1 2003/07/24 06:20:23 andrew Exp $ */ + +#ifndef __SP_WIFI_ORDER_H__ +#define __SP_WIFI_ORDER_H__ + +void SetupWifiOrder(); + +#endif /* __SP_WIFI_ORDER_H__ */ Index: snort/src/detection-plugins/sp_wifi_pwr_mgmt.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_pwr_mgmt.c:1.2 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_pwr_mgmt.c Fri Jul 25 05:08:23 2003 @@ -0,0 +1,218 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_pwr_mgmt.c,v 1.2 2003/07/25 09:08:23 andrew Exp $ */ + +/* sp_wifi_pwr_mgmt + * + * Purpose: + * + * Tests 802.11 frames pwr_mgmt control field. + * + * Arguments: + * + * {{ '!' | {} } { ON | OFF | TRUE | FALSE } } + * + * Effect: + * + * Success on pwr_mgmt flag match, failure otherwise. + * + */ + +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiPwrMgmtData +{ + int val; +} WifiPwrMgmtData; + +void WifiPwrMgmtInit(char *, OptTreeNode *, int); +void WifiPwrMgmtRuleParseFunction(char *, OptTreeNode *); +int WifiPwrMgmtDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiPwrMgmt() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiPwrMgmt() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("pwr_mgmt", WifiPwrMgmtInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiPwrMgmt Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiPwrMgmtInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiPwrMgmtInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_PWR_MGMT_CHECK] = (WifiPwrMgmtData *) calloc(sizeof(WifiPwrMgmtData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiPwrMgmtRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiPwrMgmtDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiPwrMgmtRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiPwrMgmtRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiPwrMgmtData *ds_ptr; /* data struct pointer */ + int not_flag = 0; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_PWR_MGMT_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + not_flag = 1; + data++; + } + + /* set the final option arguments here */ + if(strcmp(data, "FALSE") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "OFF") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "NO") == 0) + ds_ptr->val = 0; + + else if(strcmp(data, "TRUE") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "ON") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "YES") == 0) + ds_ptr->val = 1; + + else + FatalError("%s(%d) => Bad pwr_mgmt flag value \"%s\"\n", + file_name, file_line, data); + + if(not_flag) + ds_ptr->val = (ds_ptr->val) ? 0 : 1; + +} + + +/**************************************************************************** + * + * Function: WifiPwrMgmtDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiPwrMgmtDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiPwrMgmtData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_PWR_MGMT_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + /* your detection function tests go here */ + if (p->wifih->pwr_mgmt == plugin_data->val) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_pwr_mgmt.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_pwr_mgmt.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_pwr_mgmt.h Thu Jul 24 02:20:23 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_pwr_mgmt.h,v 1.1 2003/07/24 06:20:23 andrew Exp $ */ + +#ifndef __SP_WIFI_PWR_MGMT_H__ +#define __SP_WIFI_PWR_MGMT_H__ + +void SetupWifiPwrMgmt(); + +#endif /* __SP_WIFI_PWR_MGMT_H__ */ Index: snort/src/detection-plugins/sp_wifi_retry.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_retry.c:1.2 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_retry.c Fri Jul 25 05:07:07 2003 @@ -0,0 +1,218 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_retry.c,v 1.2 2003/07/25 09:07:07 andrew Exp $ */ + +/* sp_wifi_retry + * + * Purpose: + * + * Tests 802.11 frames retry control field. + * + * Arguments: + * + * {{ '!' | {} } { ON | OFF | TRUE | FALSE } } + * + * Effect: + * + * Success on retry flag match, failure otherwise. + * + */ + +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiRetryData +{ + int val; +} WifiRetryData; + +void WifiRetryInit(char *, OptTreeNode *, int); +void WifiRetryRuleParseFunction(char *, OptTreeNode *); +int WifiRetryDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiRetry() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiRetry() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("retry", WifiRetryInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiRetry Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiRetryInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiRetryInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_RETRY_CHECK] = (WifiRetryData *) calloc(sizeof(WifiRetryData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiRetryRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiRetryDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiRetryRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiRetryRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiRetryData *ds_ptr; /* data struct pointer */ + int not_flag = 0; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_RETRY_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + not_flag = 1; + data++; + } + + /* set the final option arguments here */ + if(strcmp(data, "FALSE") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "OFF") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "NO") == 0) + ds_ptr->val = 0; + + else if(strcmp(data, "TRUE") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "ON") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "YES") == 0) + ds_ptr->val = 1; + + else + FatalError("%s(%d) => Bad retry flag value \"%s\"\n", + file_name, file_line, data); + + if(not_flag) + ds_ptr->val = (ds_ptr->val) ? 0 : 1; + +} + + +/**************************************************************************** + * + * Function: WifiRetryDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiRetryDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiRetryData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_RETRY_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + /* your detection function tests go here */ + if (p->wifih->retry == plugin_data->val) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_retry.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_retry.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_retry.h Thu Jul 24 02:20:23 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_retry.h,v 1.1 2003/07/24 06:20:23 andrew Exp $ */ + +#ifndef __SP_WIFI_RETRY_H__ +#define __SP_WIFI_RETRY_H__ + +void SetupWifiRetry(); + +#endif /* __SP_WIFI_RETRY_H__ */ Index: snort/src/detection-plugins/sp_wifi_seqnum.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_seqnum.c:1.4 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_seqnum.c Sat Jul 26 21:32:50 2003 @@ -0,0 +1,222 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_seqnum.c,v 1.4 2003/07/27 01:32:50 andrew Exp $ */ + +/* sp_wifi_seqnum + * + * Purpose: + * + * Tests 802.11 frames seqnum control field. + * + * Arguments: + * + * {{ '!' | {} } { 0 <= n <= 4095 } } + * + * n may be specified in either hex or decimal + * + * Effect: + * + * Success on seqnum control field match, failure otherwise. + * + */ + +#include +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + +#include "wifi_datatypes.h" + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiSeqNumData +{ + u_int16_t seqnum; + u_int8_t not_flag; +} WifiSeqNumData; + +void WifiSeqNumInit(char *, OptTreeNode *, int); +void WifiSeqNumRuleParseFunction(char *, OptTreeNode *); +int WifiSeqNumDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiSeqNum() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiSeqNum() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("seqnum", WifiSeqNumInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiSeqNum Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiSeqNumInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiSeqNumInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_SEQNUM_CHECK] = (WifiSeqNumData *) calloc(sizeof(WifiSeqNumData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiSeqNumRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiSeqNumDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiSeqNumRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiSeqNumRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiSeqNumData *ds_ptr; /* data struct pointer */ + unsigned long val = 1 << 12; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_SEQNUM_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + ds_ptr->not_flag = 1; + data++; + } + + /* set the final option arguments here */ + + if(*data){ + if(strncmp(data, "0x", 2) == 0) + val = strtoul(data, NULL, 16); /* use strtoul so people don't have to do + sign-extended 2's complement hex */ + else + val = strtol(data, NULL, 10); + } + + if(val < 0 || val > 4095) + FatalError("%s(%d) => seqnum value out of range \"%s\"\n", + file_name, file_line, data); + + ds_ptr->seqnum = val; +} + + +/**************************************************************************** + * + * Function: WifiSeqNumDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiSeqNumDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiSeqNumData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_SEQNUM_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + if(p->wifih->type == TYPE_CONTROL){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Frame is TYPE_CONTROL\n");); + return 0; + } + + /* your detection function tests go here */ + if((plugin_data->not_flag && (p->wifih->seqnum != plugin_data->seqnum)) || + (!plugin_data->not_flag && (p->wifih->seqnum == plugin_data->seqnum))) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_seqnum.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_seqnum.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_seqnum.h Fri Jul 25 05:51:44 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_seqnum.h,v 1.1 2003/07/25 09:51:44 andrew Exp $ */ + +#ifndef __SP_WIFI_SEQNUM_H__ +#define __SP_WIFI_SEQNUM_H__ + +void SetupWifiSeqNum(); + +#endif /* __SP_WIFI_SEQNUM_H__ */ Index: snort/src/detection-plugins/sp_wifi_ssid.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_ssid.c:1.3 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_ssid.c Sun Jul 27 03:03:04 2003 @@ -0,0 +1,257 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_ssid.c,v 1.3 2003/07/27 07:03:04 andrew Exp $ */ + +/* sp_wifi_ssid + * + * Purpose: + * + * Tests 802.11 frames SSID. + * + * Arguments: + * + * {{ '!' | {} } } + * + * Effect: + * + * Success on SSID match, failure otherwise. + * + */ + +#include +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + +#include "wifi_datatypes.h" + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiSsidData +{ + char *ssid; + u_int8_t ssid_len; + u_int8_t not_flag; +} WifiSsidData; + +void WifiSsidInit(char *, OptTreeNode *, int); +void WifiSsidRuleParseFunction(char *, OptTreeNode *); +int WifiSsidDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiSsid() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiSsid() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("ssid", WifiSsidInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiSsid Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiSsidInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiSsidInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_SSID_CHECK] = (WifiSsidData *) calloc(sizeof(WifiSsidData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiSsidRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiSsidDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiSsidRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiSsidRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiSsidData *ds_ptr; /* data struct pointer */ + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_SSID_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + ds_ptr->not_flag = 1; + data++; + } + + /* set the final option arguments here */ + + ds_ptr->ssid = data; + if((ds_ptr->ssid_len = strlen(data)) > 32) + FatalError("%s (%d) => SSID exceeds maximum length \"%s\"\n", file_name, file_line, data); +} + + +/**************************************************************************** + * + * Function: WifiSsidDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiSsidDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiSsidData *plugin_data; + WifiElementID *ssid_id; + u_int8_t *ssid; + + plugin_data = otn->ds_list[PLUGIN_WIFI_SSID_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + + if(p->wifih->type != TYPE_MANAGEMENT){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Frame is not TYPE_MANAGEMENT\n");); + return 0; + } + + ssid_id = (u_int8_t *)p->wifih + _OFFSET_MANAGEMENT_BODY; + ssid = (u_int8_t *)p->wifih + _OFFSET_MANAGEMENT_BODY; + + switch(p->wifih->stype){ + case STYPE_BEACON: + ssid_id +=_OFFSET_BEACON_SSID_ID; + ssid +=_OFFSET_BEACON_SSID; + break; + case STYPE_ASSOCREQ: + ssid_id += _OFFSET_ASSOCREQ_SSID_ID; + ssid += _OFFSET_ASSOCREQ_SSID; + break; + + case STYPE_REASSOC_REQ: + ssid_id += _OFFSET_REASSOC_REQ_SSID_ID; + ssid += _OFFSET_REASSOC_REQ_SSID; + break; + + case STYPE_PROBEREQ: + ssid_id += _OFFSET_PROBEREQ_SSID_ID; + ssid += _OFFSET_PROBEREQ_SSID; + break; + + case STYPE_PROBERESP: + ssid_id += _OFFSET_PROBERESP_SSID_ID; + ssid += _OFFSET_PROBERESP_SSID; + break; + + case STYPE_ASSOCRESP: + case STYPE_REASSOC_RESP: + case STYPE_ATIM: + case STYPE_DISASSOC: + case STYPE_AUTH: + case STYPE_DEAUTH: + default: + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Management frame subtype does not contain SSID\n");); + return 0; + } + + /* your detection function tests go here */ + + if((plugin_data->not_flag && (memcmp(ssid, plugin_data->ssid, plugin_data->ssid_len) != 0)) || + (!plugin_data->not_flag && (memcmp(ssid, plugin_data->ssid, plugin_data->ssid_len) == 0))) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} + + + Index: snort/src/detection-plugins/sp_wifi_ssid.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_ssid.h:1.1 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_ssid.h Sat Jul 26 23:26:08 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_ssid.h,v 1.1 2003/07/27 03:26:08 andrew Exp $ */ + +#ifndef __SP_WIFI_SSID_H__ +#define __SP_WIFI_SSID_H__ + +void SetupWifiSsid(); + +#endif /* __SP_WIFI_SSID_H__ */ Index: snort/src/detection-plugins/sp_wifi_stype.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_stype.c:1.5 --- /dev/null Mon Jun 13 11:20:17 2005 +++ snort/src/detection-plugins/sp_wifi_stype.c Thu Aug 14 22:17:48 2003 @@ -0,0 +1,292 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +/* $Id: sp_wifi_stype.c,v 1.5 2003/08/15 02:17:48 andrew Exp $ */ + +/* sp_wifi_stype + * + * Purpose: + * + * Tests 802.11 frames for their frame subtype and implicitly tests the frame's type too + * so that using a symbollic name for the subtype works in the assumed manner. + * + * Arguments: + * + * {{ '!' | {} } { wifi_stype_t } + * + * Effect: + * + * Success on frame sub-type match, failure otherwise. + * + */ + +#include +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ +#define NUM_WIFI_STYPES 40 +char *_wifi_stype_strs[] = { + "STYPE_ASSOCREQ", /* 0x00 */ + "STYPE_ASSOCRESP", /* 0x01 */ + "STYPE_REASSOC_REQ", /* 0x02 */ + "STYPE_REASSOC_RESP", /* 0x03 */ + "STYPE_PROBEREQ", /* 0x04 */ + "STYPE_PROBERESP", /* 0x05 */ + "STYPE_INVALID", /* 0x06 */ + "STYPE_INVALID", /* 0x07 */ + "STYPE_BEACON", /* 0x08 */ + "STYPE_ATIM", /* 0x09 */ + "STYPE_DISASSOC", /* 0x0a */ + "STYPE_AUTH", /* 0x0b */ + "STYPE_DEAUTH", /* 0x0c */ + "STYPE_INVALID", /* 0x0d */ + "STYPE_INVALID", /* 0x0e */ + "STYPE_INVALID", /* 0x0f */ + "STYPE_INVALID", /* 0x10 */ + "STYPE_INVALID", /* 0x11 */ + "STYPE_INVALID", /* 0x12 */ + "STYPE_INVALID", /* 0x13 */ + "STYPE_INVALID", /* 0x14 */ + "STYPE_INVALID", /* 0x15 */ + "STYPE_INVALID", /* 0x16 */ + "STYPE_INVALID", /* 0x17 */ + "STYPE_INVALID", /* 0x18 */ + "STYPE_INVALID", /* 0x19 */ + "STYPE_PSPOLL", /* 0x1a */ + "STYPE_RTS", /* 0x1b */ + "STYPE_CTS", /* 0x1c */ + "STYPE_ACK", /* 0x1d */ + "STYPE_CFEND", /* 0x1e */ + "STYPE_CFEND_CFACK", /* 0x1f */ + "STYPE_DATA", /* 0x20 */ + "STYPE_CFACK", /* 0x21 */ + "STYPE_CFPOLL", /* 0x22 */ + "STYPE_CFACK_CFPOLL", /* 0x23 */ + "STYPE_NULLFUNC", /* 0x24 */ + "STYPE_CFACK_NULLFUNC", /* 0x25 */ + "STYPE_CFPOLL_NULLFUNC", /* 0x26 */ + "STYPE_CFACK_CFPOLL_NULLFUNC" /* 0x27 */ +}; + +typedef enum { /* 802.11 management frame subtypes */ + STYPE_INVALID = -1, + STYPE_ASSOCREQ = 0x00, /* Subtypes are already AND'ed with their corresponding Types */ + STYPE_ASSOCRESP = 0x01, /* to prevent false positives and the need for checking the type */ + STYPE_REASSOC_REQ = 0x02, /* independently */ + STYPE_REASSOC_RESP = 0x03, + STYPE_PROBEREQ = 0x04, + STYPE_PROBERESP = 0x05, + STYPE_BEACON = 0x08, + STYPE_ATIM = 0x09, + STYPE_DIASSOC = 0x0a, + STYPE_AUTH = 0x0b, + STYPE_DEAUTH = 0x0c, + +/* 802.11 control frame subtypes */ + STYPE_PSPOLL = 0x1a, + STYPE_RTS = 0x1b, + STYPE_CTS = 0x1c, + STYPE_ACK = 0x1d, + STYPE_CFEND = 0x1e, + STYPE_CFEND_CFACK = 0x1f, + +/* 802.11 data frame subtypes */ + STYPE_DATA = 0x20, + STYPE_CFACK = 0x21, + STYPE_CFPOLL = 0x22, + STYPE_CFACK_CFPOLL = 0x23, + STYPE_NULLFUNC = 0x24, + STYPE_CFACK_NULLFUNC = 0x25, + STYPE_CFPOLL_NULLFUNC = 0x26, + STYPE_CFACK_CFPOLL_NULLFUNC = 0x27 +} wifi_stype_t; + +typedef struct _WifiStypeData +{ + wifi_stype_t stype; + u_int8_t not_flag; + +} WifiStypeData; + +void WifiStypeInit(char *, OptTreeNode *, int); +void WifiStypeRuleParseFunction(char *, OptTreeNode *); +int WifiStypeDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiStype() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiStype() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("stype", WifiStypeInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiStype Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiStypeInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiStypeInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_STYPE_CHECK] = (WifiStypeData *) calloc(sizeof(WifiStypeData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiStypeRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiStypeDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiStypeRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiStypeRuleParseFunction(char *data, OptTreeNode *otn) +{ + int i; + WifiStypeData *ds_ptr; /* data struct pointer */ + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_STYPE_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int)*data)) data++; + + if(*data == '!'){ + ds_ptr->not_flag = 1; + data++; + } + + ds_ptr->stype = STYPE_INVALID; + + /* set the final option arguments here */ + for(i = 0; i < NUM_WIFI_STYPES; i++) + if(strcmp(data, _wifi_stype_strs[i]) == 0 && + strcmp(data, "STYPE_INVALID") != 0){ + ds_ptr->stype = i; + break; + } + + if(ds_ptr->stype == STYPE_INVALID) + FatalError("%s(%d) => Bad frame sub-type \"%s\"\n", file_name, file_line, data); +} + + +/**************************************************************************** + * + * Function: WifiStypeDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiStypeDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + WifiStypeData *wtd; + u_int8_t stype; + wtd = otn->ds_list[PLUGIN_WIFI_STYPE_CHECK]; + + if(!p->wifih) + { + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not WIFI\n");); + return 0; + } + + stype = p->wifih->stype | (p->wifih->type << 4); + + if((wtd->not_flag && (stype != wtd->stype)) || + (!wtd->not_flag && (stype == wtd->stype))) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match\n");); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_stype.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_stype.h:1.2 --- /dev/null Mon Jun 13 11:20:18 2005 +++ snort/src/detection-plugins/sp_wifi_stype.h Sat Jul 26 20:34:00 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_stype.h,v 1.2 2003/07/27 00:34:00 andrew Exp $ */ + +#ifndef __SP_WIFI_STYPE_H__ +#define __SP_WIFI_STYPE_H__ + +void SetupWifiStype(); + +#endif /* __SP_WIFI_STYPE_H__ */ Index: snort/src/detection-plugins/sp_wifi_to_ds.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_to_ds.c:1.2 --- /dev/null Mon Jun 13 11:20:18 2005 +++ snort/src/detection-plugins/sp_wifi_to_ds.c Fri Jul 25 04:59:01 2003 @@ -0,0 +1,218 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_to_ds.c,v 1.2 2003/07/25 08:59:01 andrew Exp $ */ + +/* sp_wifi_to_ds + * + * Purpose: + * + * Tests 802.11 frames to_ds control field. + * + * Arguments: + * + * {{ '!' | {} } { ON | OFF | TRUE | FALSE } } + * + * Effect: + * + * Success on to_ds match, failure otherwise. + * + */ + +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiToDsData +{ + int val; +} WifiToDsData; + +void WifiToDsInit(char *, OptTreeNode *, int); +void WifiToDsRuleParseFunction(char *, OptTreeNode *); +int WifiToDsDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiToDs() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiToDs() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("to_ds", WifiToDsInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiToDs Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiToDsInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiToDsInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_TO_DS_CHECK] = (WifiToDsData *) calloc(sizeof(WifiToDsData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiToDsRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiToDsDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiToDsRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiToDsRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiToDsData *ds_ptr; /* data struct pointer */ + int not_flag = 0; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_TO_DS_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + not_flag = 1; + data++; + } + + /* set the final option arguments here */ + if(strcmp(data, "FALSE") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "OFF") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "NO") == 0) + ds_ptr->val = 0; + + else if(strcmp(data, "TRUE") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "ON") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "YES") == 0) + ds_ptr->val = 1; + + else + FatalError("%s(%d) => Bad to_ds flag value \"%s\"\n", + file_name, file_line, data); + + if(not_flag) + ds_ptr->val = (ds_ptr->val) ? 0 : 1; + +} + + +/**************************************************************************** + * + * Function: WifiToDsDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiToDsDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiToDsData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_TO_DS_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + /* your detection function tests go here */ + if (p->wifih->to_ds == plugin_data->val) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_to_ds.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_to_ds.h:1.1 --- /dev/null Mon Jun 13 11:20:18 2005 +++ snort/src/detection-plugins/sp_wifi_to_ds.h Thu Jul 24 02:20:23 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_to_ds.h,v 1.1 2003/07/24 06:20:23 andrew Exp $ */ + +#ifndef __SP_WIFI_TO_DS_H__ +#define __SP_WIFI_TO_DS_H__ + +void SetupWifiToDs(); + +#endif /* __SP_WIFI_TO_DS_H__ */ Index: snort/src/detection-plugins/sp_wifi_type.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_type.c:1.2 --- /dev/null Mon Jun 13 11:20:18 2005 +++ snort/src/detection-plugins/sp_wifi_type.c Sat Jul 26 20:33:01 2003 @@ -0,0 +1,221 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + + +/* $Id: sp_wifi_type.c,v 1.2 2003/07/27 00:33:01 andrew Exp $ */ +/* Snort Detection Plugin Source File WifiType */ + +/* sp_wifi_type + * + * Purpose: + * + * Tests 802.11 frames for their frame type. + * + * Arguments: + * + * {{ '!' | {} } { TYPE_MANAGEMENT | TYPE_CONTROL | TYPE_DATA } } + * + * Effect: + * + * Success on frame type match, failure otherwise. + * + */ + +#include +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + +#include "wifi_datatypes.h" + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +char *_wifi_type_strs[] = { + "TYPE_MANAGEMENT", + "TYPE_CONTROL", + "TYPE_DATA" +}; + +typedef struct _WifiTypeData +{ + wifi_type_t type; + u_int8_t not_flag; + +} WifiTypeData; + +void WifiTypeInit(char *, OptTreeNode *, int); +void WifiTypeRuleParseFunction(char *, OptTreeNode *); +int WifiTypeDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiType() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiType() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("type", WifiTypeInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiType Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiTypeInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiTypeInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_TYPE_CHECK] = (WifiTypeData *) calloc(sizeof(WifiTypeData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiTypeRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiTypeDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiTypeRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiTypeRuleParseFunction(char *data, OptTreeNode *otn) +{ + int i; + WifiTypeData *ds_ptr; /* data struct pointer */ + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_TYPE_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int)*data)) data++; + + if(*data == '!'){ + ds_ptr->not_flag = 1; + data++; + } + + ds_ptr->type = TYPE_INVALID; + + /* set the final option arguments here */ + for(i = 0; i < 3; i++) + if(strcmp(data, _wifi_type_strs[i]) == 0){ + ds_ptr->type = i; + break; + } + + if(ds_ptr->type == TYPE_INVALID) + FatalError("%s(%d) => Bad frame type \"%s\"\n", + file_name, file_line, data); +} + + +/**************************************************************************** + * + * Function: WifiTypeDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiTypeDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + WifiTypeData *wtd; + wtd = otn->ds_list[PLUGIN_WIFI_TYPE_CHECK]; + + if(!p->wifih) + { + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not WIFI\n");); + return 0; + } + + if((wtd->not_flag && (p->wifih->type != wtd->type)) || + (!wtd->not_flag && (p->wifih->type == wtd->type))) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match\n");); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_type.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_type.h:1.2 --- /dev/null Mon Jun 13 11:20:18 2005 +++ snort/src/detection-plugins/sp_wifi_type.h Sat Jul 26 20:33:01 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_type.h,v 1.2 2003/07/27 00:33:01 andrew Exp $ */ + +#ifndef __SP_WIFI_TYPE_H__ +#define __SP_WIFI_TYPE_H__ + +void SetupWifiType(); + +#endif /* __SP_WIFI_TYPE_H__ */ Index: snort/src/detection-plugins/sp_wifi_wep.c diff -u /dev/null snort/src/detection-plugins/sp_wifi_wep.c:1.2 --- /dev/null Mon Jun 13 11:20:18 2005 +++ snort/src/detection-plugins/sp_wifi_wep.c Fri Jul 25 04:55:58 2003 @@ -0,0 +1,218 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_wep.c,v 1.2 2003/07/25 08:55:58 andrew Exp $ */ + +/* sp_wifi_wep + * + * Purpose: + * + * Tests 802.11 frames WEP control field. + * + * Arguments: + * + * {{ '!' | {} } { ON | OFF | TRUE | FALSE } } + * + * Effect: + * + * Success on WEP control field match, failure otherwise. + * + */ + +#include +#include +#include + +#include "rules.h" +#include "decode.h" +#include "plugbase.h" +#include "parser.h" +#include "debug.h" +#include "util.h" +#include "plugin_enum.h" + + +/* don't forget to include the name of this file in plugbase.h! */ + +extern char *file_name; /* this is the file name from rules.c, generally used + for error messages */ + +extern int file_line; /* this is the file line number from rules.c that is + used to indicate file lines for error messages */ + +typedef struct _WifiWepData +{ + int val; +} WifiWepData; + +void WifiWepInit(char *, OptTreeNode *, int); +void WifiWepRuleParseFunction(char *, OptTreeNode *); +int WifiWepDetectorFunction(Packet *, struct _OptTreeNode *, OptFpList *); + +/**************************************************************************** + * + * Function: SetupWifiWep() + * + * Purpose: Generic detection engine plugin template. Registers the + * configuration function and links it to a rule keyword. This is + * the function that gets called from InitPlugins in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + ****************************************************************************/ +void SetupWifiWep() +{ + /* map the keyword to an initialization/processing function */ + RegisterPlugin("wep", WifiWepInit); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: WifiWep Setup\n");); +} + + +/**************************************************************************** + * + * Function: WifiWepInit(char *, OptTreeNode *) + * + * Purpose: Generic rule configuration function. Handles parsing the rule + * information and attaching the associated detection function to + * the OTN. + * + * Arguments: data => rule arguments/data + * otn => pointer to the current rule option list node + * + * Returns: void function + * + ****************************************************************************/ +void WifiWepInit(char *data, OptTreeNode *otn, int protocol) +{ + /* allocate the data structure and attach it to the + rule's data struct list */ + otn->ds_list[PLUGIN_WIFI_WEP_CHECK] = (WifiWepData *) calloc(sizeof(WifiWepData), sizeof(char)); + + /* be sure to check that the protocol that is passed in matches the + transport layer protocol that you're using for this rule! */ + + /* this is where the keyword arguments are processed and placed into the + rule option's data structure */ + WifiWepRuleParseFunction(data, otn); + + /* finally, attach the option's detection function to the rule's + detect function pointer list */ + AddOptFuncToList(WifiWepDetectorFunction, otn); +} + + + +/**************************************************************************** + * + * Function: WifiWepRuleParseFunction(char *, OptTreeNode *) + * + * Purpose: This is the function that is used to process the option keyword's + * arguments and attach them to the rule's data structures. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: void function + * + ****************************************************************************/ +void WifiWepRuleParseFunction(char *data, OptTreeNode *otn) +{ + WifiWepData *ds_ptr; /* data struct pointer */ + int not_flag = 0; + + /* set the ds pointer to make it easier to reference the option's + particular data struct */ + ds_ptr = otn->ds_list[PLUGIN_WIFI_WEP_CHECK]; + + /* manipulate the option arguments here */ + while(isspace((int) *data)) data++; + + if(*data == '!'){ + not_flag = 1; + data++; + } + + /* set the final option arguments here */ + if(strcmp(data, "FALSE") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "OFF") == 0) + ds_ptr->val = 0; + else if(strcmp(data, "NO") == 0) + ds_ptr->val = 0; + + else if(strcmp(data, "TRUE") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "ON") == 0) + ds_ptr->val = 1; + else if(strcmp(data, "YES") == 0) + ds_ptr->val = 1; + + else + FatalError("%s(%d) => Bad wep flag value \"%s\"\n", + file_name, file_line, data); + + if(not_flag) + ds_ptr->val = (ds_ptr->val) ? 0 : 1; + +} + + +/**************************************************************************** + * + * Function: WifiWepDetectorFunction(char *, OptTreeNode *) + * + * Purpose: Use this function to perform the particular detection routine + * that this rule keyword is supposed to encompass. + * + * Arguments: data => argument data + * otn => pointer to the current rule's OTN + * + * Returns: If the detection test fails, this function *must* return a zero! + * On success, it calls the next function in the detection list + * + ****************************************************************************/ +int WifiWepDetectorFunction(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) +{ + + WifiWepData *plugin_data; + plugin_data = otn->ds_list[PLUGIN_WIFI_WEP_CHECK]; + + if(!p->wifih){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not a WIFI frame\n");); + return 0; + } + + /* your detection function tests go here */ + if (p->wifih->wep == plugin_data->val) + { + return fp_list->next->OptTestFunc(p, otn, fp_list->next); + } +#ifdef DEBUG + else + { + /* you can put debug comments here or not */ + DebugMessage(DEBUG_PLUGIN,"No match\n"); + } +#endif + + /* if the test isn't successful, this function *must* return 0 */ + return 0; +} Index: snort/src/detection-plugins/sp_wifi_wep.h diff -u /dev/null snort/src/detection-plugins/sp_wifi_wep.h:1.1 --- /dev/null Mon Jun 13 11:20:18 2005 +++ snort/src/detection-plugins/sp_wifi_wep.h Thu Jul 24 02:20:23 2003 @@ -0,0 +1,26 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: sp_wifi_wep.h,v 1.1 2003/07/24 06:20:23 andrew Exp $ */ + +#ifndef __SP_WIFI_WEP_H__ +#define __SP_WIFI_WEP_H__ + +void SetupWifiWep(); + +#endif /* __SP_WIFI_WEP_H__ */ Index: snort/src/detection-plugins/wifi_datatypes.h diff -u /dev/null snort/src/detection-plugins/wifi_datatypes.h:1.3 --- /dev/null Mon Jun 13 11:20:18 2005 +++ snort/src/detection-plugins/wifi_datatypes.h Sat Jul 26 23:22:30 2003 @@ -0,0 +1,162 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: wifi_datatypes.h,v 1.3 2003/07/27 03:22:30 andrew Exp $ */ + +/* Data types for wifi plugins */ + +#ifndef __WIFI_DATATYPES_H__ +#define __WIFI_DATATYPES_H__ + +typedef enum { /* 802.11 frame types */ + TYPE_INVALID = -1, + TYPE_MANAGEMENT = 0x00, + TYPE_CONTROL = 0x01, + TYPE_DATA = 0x02 +} wifi_type_t; + +typedef enum { /* 802.11 management frame subtypes */ + STYPE_INVALID = -1, + STYPE_ASSOCREQ = 0x00, + STYPE_ASSOCRESP = 0x01, + STYPE_REASSOC_REQ = 0x02, + STYPE_REASSOC_RESP = 0x03, + STYPE_PROBEREQ = 0x04, + STYPE_PROBERESP = 0x05, + STYPE_BEACON = 0x08, + STYPE_ATIM = 0x09, + STYPE_DISASSOC = 0x0a, + STYPE_AUTH = 0x0b, + STYPE_DEAUTH = 0x0c, + +/* 802.11 control frame subtypes */ + STYPE_PS = 0x0a, + STYPE_RTS = 0x0b, + STYPE_CTS = 0x0c, + STYPE_ACK = 0x0d, + STYPE_CFEND = 0x0e, + STYPE_CFEND_CFACK = 0x0f, + +/* 802.11 data frame subtypes */ + STYPE_DATA = 0x00, + STYPE_CFACK = 0x01, + STYPE_CFPOLL = 0x02, + STYPE_CFACK_CFPOLL = 0x03, + STYPE_NULL = 0x04, + STYPE_CFACK_NULL = 0x05, + STYPE_CFPOLL_NULL = 0x06, + STYPE_CFACK_CFPOLL_NULL = 0x07 +} wifi_stype_t; + +typedef struct _WifiElementID{ /* 802.11 element id */ + u_int8_t id; + u_int8_t len; +} WifiElementID; + +typedef struct _WifiCapInfo{ /* 802.11 capability information */ + u_int16_t cap_ess:1; + u_int16_t cap_ibss:1; + u_int16_t cap_cfpoll:1; + u_int16_t cap_cfpoll_req:1; + u_int16_t cap_wep:1; + u_int16_t cap_reserved:11; +} WifiCapInfo; + +#define _OFFSET_MANAGEMENT_BODY sizeof(WifiHdr) - 6 + +typedef struct _WifiBeacon{ /* 802.11 beacon body */ +#define _OFFSET_TIMESTAMP 0x00 + u_int32_t *timestamp1; + u_int32_t *timestamp2; +#define _OFFSET_BEACON_INT _OFFSET_TIMESTAMP + 2 * sizeof(u_int32_t) + u_int16_t *beacon_int; +#define _OFFSET_BEACON_CAP_INFO _OFFSET_BEACON_INT + sizeof(u_int16_t) + WifiCapInfo *cap_info; +#define _OFFSET_BEACON_SSID_ID _OFFSET_BEACON_CAP_INFO + sizeof(WifiCapInfo) + WifiElementID *ssid_id; +#define _OFFSET_BEACON_SSID _OFFSET_BEACON_SSID_ID + sizeof(WifiElementID) + u_int8_t *ssid; + WifiElementID *rates_id; + u_int8_t *rates; + u_int8_t *current_chan; + /* we don't care about the rest right now */ +} WifiBeacon; + + +typedef struct _WifiAssocReq{ /* 802.11 association request body */ +#define _OFFSET_ASSOCREQ_CAP_INFO 0x00 + WifiCapInfo *cap_info; +#define _OFFSET_ASSOCREQ_LISTEN_INT _OFFSET_ASSOCREQ_CAP_INFO + sizeof(WifiCapInfo) + u_int16_t *listen_int; +#define _OFFSET_ASSOCREQ_SSID_ID _OFFSET_ASSOCREQ_LISTEN_INT + sizeof(u_int16_t) + WifiElementID *ssid_id; +#define _OFFSET_ASSOCREQ_SSID _OFFSET_ASSOCREQ_SSID_ID + sizeof(WifiElementID) + u_int8_t *ssid; + WifiElementID *rates_id; + u_int8_t *rates; +} WifiAssocReq; + +typedef struct _WifiReAssocReq{ /* 802.11 re-association request body */ +#define _OFFSET_REASSOC_REQ 0x00 + WifiCapInfo *cap_info; +#define _OFFSET_REASSOC_REQ_LISTEN_INT _OFFSET_REASSOC_REQ + sizeof(WifiCapInfo) + u_int16_t *listen_int; +#define _OFFSET_REASSOC_REQ_CURRENT_AP _OFFSET_REASSOC_REQ_LISTEN_INT + sizeof(u_int16_t) + u_int8_t *current_ap; +#define _OFFSET_REASSOC_REQ_SSID_ID _OFFSET_REASSOC_REQ_CURRENT_AP + 6 + WifiElementID *ssid_id; +#define _OFFSET_REASSOC_REQ_SSID _OFFSET_REASSOC_REQ_SSID_ID + sizeof(WifiElementID) + u_int8_t *ssid; + WifiElementID *rates_id; + u_int8_t *rates; +} WifiReAssocReq; + + +typedef struct _WifiProbeReq{ /* 802.11 probe request body */ +#define _OFFSET_PROBEREQ_SSID_ID 0 + WifiElementID *ssid_id; +#define _OFFSET_PROBEREQ_SSID _OFFSET_PROBEREQ_SSID_ID + sizeof(WifiElementID) + u_int8_t *ssid; + WifiElementID *rates_id; + u_int8_t *rates; +} WifiProbeReq; + + +typedef struct _WifiProbeResp{ /* 802.11 probe response body */ +#define _OFFSET_TIMESTAMP 0x00 + u_int32_t *timestamp1; + u_int32_t *timestamp2; +#define _OFFSET_BEACON_INT _OFFSET_TIMESTAMP + 2 * sizeof(u_int32_t) + u_int16_t *beacon_int; +#define _OFFSET_PROBERESP_CAP_INFO _OFFSET_BEACON_INT + sizeof(u_int16_t) + WifiCapInfo *cap_info; +#define _OFFSET_PROBERESP_SSID_ID _OFFSET_PROBERESP_CAP_INFO + sizeof(WifiCapInfo) + WifiElementID *ssid_id; +#define _OFFSET_PROBERESP_SSID _OFFSET_PROBERESP_SSID_ID + sizeof(WifiElementID) + u_int8_t *ssid; + WifiElementID *rates_id; + u_int8_t *rates; + u_int8_t *current_chan; + /* we don't care about the rest right now */ +} WifiProbeResp; + + + + + +#endif /* __WIFI_DATATYPES_H__ */ Index: snort/src/preprocessors/Makefile.am diff -u snort/src/preprocessors/Makefile.am:1.1.1.5 snort/src/preprocessors/Makefile.am:1.6 --- snort/src/preprocessors/Makefile.am:1.1.1.5 Mon Apr 25 03:26:43 2005 +++ snort/src/preprocessors/Makefile.am Mon Apr 25 13:05:05 2005 @@ -25,7 +25,8 @@ spp_xlink2state.c spp_xlink2state.h \ xlink2state.c xlink2state.h \ str_search.c str_search.h \ -stream.h - +stream.h \ +spp_rogue_ap.c spp_rogue_ap.h \ +spp_antistumbler.c spp_antistumbler.h INCLUDES = @INCLUDES@ Index: snort/src/preprocessors/spp_antistumbler.c diff -u /dev/null snort/src/preprocessors/spp_antistumbler.c:1.2 --- /dev/null Mon Jun 13 11:20:21 2005 +++ snort/src/preprocessors/spp_antistumbler.c Thu Jul 24 02:32:37 2003 @@ -0,0 +1,432 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: spp_antistumbler.c,v 1.2 2003/07/24 06:32:37 andrew Exp $ */ + +/* spp_antistumbler + * + * Purpose: + * + * Detects wireless stations actively scanning for APs + * + * Arguments: + * + * probe_reqs => number of probe requests during time delta it takes to trigger an alert + * + * probe_period => time period used to keep count of probe requests over + * + * expire_timeout => number of seconds to wait for removing a MAC address from + * the list of detected Netstumblers + * + * Effect: + * + * Sends an alert for each station it detects actively scanning for APs + * + * Comments: + * + * Any comments? + * + */ + + +#include "generators.h" +#include "log.h" +#include "detect.h" +#include "decode.h" +#include "event.h" +#include "plugbase.h" +#include "parser.h" +#include "mstring.h" +#include "debug.h" +#include "util.h" + + +#ifndef __SPP_ANTISTUMBLER_C__ +#define __SPP_ANTISTUMBLER_C__ +#include "spp_antistumbler.h" +#endif + + +#define MODNAME "spp_antistumbler" + +/* external globals from rules.c */ +extern char *file_name; +extern int file_line; + + +AntiStumblerData antistumbler_data; + +/* + * Function: SetupAntiStumbler() + * + * Purpose: Registers the preprocessor keyword and initialization + * function into the preprocessor list. This is the function that + * gets called from InitPreprocessors() in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + */ +void SetupAntiStumbler() +{ + /* link the preprocessor keyword to the init function in + the preproc list */ + RegisterPreprocessor("antistumbler", AntiStumblerInit); + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Preprocessor: AntiStumbler is setup...\n");) +} + + +/* + * Function: AntiStumblerInit(u_char *) + * + * Purpose: Calls the argument parsing function, performs final setup on data + * structs, links the preproc function into the function list. + * + * Arguments: args => ptr to argument string + * + * Returns: void function + * + */ +void AntiStumblerInit(u_char *args) +{ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Preprocessor: AntiStumbler Initialized\n");); + + /* parse the argument list from the rules file */ + AntiStumblerParseArgs(args); + + /* Set the preprocessor function into the function list */ + AddFuncToPreprocList(AntiStumblerDetect); +/* AddFuncToCleanExitList(PreprocCleanExitFunction); */ +/* AddFuncToRestartList(PreprocRestartFunction); */ +} + + + +/* + * Function: AntiStumblerParseArgs(char *) + * + * Purpose: Process the preprocessor arguements from the rules file and + * initialize the preprocessor's data struct. This function doesn't + * have to exist if it makes sense to parse the args in the init + * function. + * + * Arguments: args => argument list + * + * Returns: void function + * + */ +void AntiStumblerParseArgs(char *args) +{ + int i, n, n_args, n_arg_args; + char **arg_toks = NULL, **arg_args = NULL; + + /* init preproc data with defaults */ + antistumbler_data.probe_reqs = ANTISTUMBLER_PROBE_REQS; + antistumbler_data.probe_period = ANTISTUMBLER_PROBE_PERIOD; + antistumbler_data.expire_timeout = ANTISTUMBLER_EXPIRE_TIMEOUT; + antistumbler_data.stumblers = NULL; + + if(args == NULL) + return; + + if(*args){ + + arg_toks = mSplit(args, ",", 3, &n_args, 0); + if(n_args != 3){ + FatalError("%s: %s (%d) => antistumbler configuration format: probe_reqs , probe_period , expire_timeout \n", + MODNAME, file_name, file_line); + } + + for(i = 0; i < n_args; i++){ + + arg_args = mSplit(arg_toks[i], " ", 2, &n_arg_args, 0); + if(n_arg_args != 2){ + FatalError("%s: %s (%d) => antistumbler configuration format: probe_reqs , probe_period , expire_timeout \n", + MODNAME, file_name, file_line); + } + + if(strcmp(arg_args[0], "probe_reqs") == 0){ + n = strtol(arg_args[1], NULL, 10); + if(n <= 0){ + FatalError("%s: %s (%d) => \"probe_reqs\" must be greater than 0\n", MODNAME, file_name, file_line); + } + antistumbler_data.probe_reqs = n; + } + else if(strcmp(arg_args[0], "probe_period") == 0){ + n = strtol(arg_args[1], NULL, 10); + if(n <= 0){ + FatalError("%s: %s (%d) => \"probe_period\" must be greater than 0\n", MODNAME, file_name, file_line); + } + antistumbler_data.probe_period = n; + } + else if(strcmp(arg_args[0], "expire_timeout") == 0){ + n = strtol(arg_args[1], NULL, 10); + if(n <= 0){ + FatalError("%s: %s (%d) => \"expire_timeout\" must be greater than 0\n", MODNAME, file_name, file_line); + } + antistumbler_data.expire_timeout = n; + } + else{ + FatalError("%s: %s (%d) => Invalid argument \"%s %s\"\n", MODNAME, file_name, file_line, arg_args[0], arg_args[1]); + } + } + } + else{ + FatalError("%s: %s (%d) => antistumbler configuration format: probe_reqs , probe_period , expire_timeout \n", + MODNAME, file_name, file_line); + } +} + +/* + * Function: AntiStumblerDetect(Packet *) + * + * Purpose: Perform the preprocessor's intended function. This can be + * simple (statistics collection) or complex (IP defragmentation) + * as you like. Try not to destroy the performance of the whole + * system by trying to do too much.... + * + * Arguments: p => pointer to the current packet data struct + * + * Returns: void function + * + */ +void AntiStumblerDetect(Packet *p) +{ + int on_list = 0; + time_t time_curr; + Stumbler *stumbler_ptr = NULL; + Event event; + char log_message[128]; + ProbeReq fixed_params; + Beacon beacon_body; + + time_curr = time(NULL); + + if(p->wifih == NULL) + return; + + + if(p->wifih->type == TYPE_MANAGEMENT && p->wifih->stype == STYPE_BEACON){ + beacon_body.ssid_id = p->wifih + _OFFSET_BEACON_SSID_ID; + beacon_body.ssid = p->wifih + _OFFSET_BEACON_SSID; + + if(beacon_body.ssid_id->len == 15 && beacon_body.cap_info->cap_ibss){ + if(strncmp(beacon_body.ssid, "Wavelan Network", 15) == 0){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: AdHoc network detected (SSID \"Wavelan Network\")\n");); + if(antistumbler_data.stumblers == NULL) + antistumbler_data.stumblers = AllocStumblerList(); + + stumbler_ptr = InsertStumbler(p->wifih->addr3, antistumbler_data.stumblers); + + snprintf(log_message, 128, "Detected possible Kismet use from %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", + stumbler_ptr->addr[0], stumbler_ptr->addr[1], stumbler_ptr->addr[2], + stumbler_ptr->addr[3], stumbler_ptr->addr[4], stumbler_ptr->addr[5]); + SetEvent(&event, GENERATOR_SPP_ANTISTUMBLER, STUMBLER_DETECTED, 1, 4, 2, 0); + if(p->iph == NULL) /* ugh, the horrible hack arises once again */ + p->iph = (IPHdr *)calloc(1, sizeof(IPHdr)); + + CallAlertFuncs(p, log_message, NULL, &event); /* send alert */ + } + } + return; + } + + + if(p->wifih->type != TYPE_MANAGEMENT || p->wifih->stype != STYPE_PROBEREQ) + return; + + fixed_params.ssid_id = p->pkt + _OFFSET_PROBEREQ_SSID_ID; + fixed_params.ssid = p->pkt + _OFFSET_PROBEREQ_SSID; +/* fixed_params.rates_id = fixed_params.ssid + fixed_params.ssid_id->len; */ +/* fixed_params.rates = fixed_params.rates_id + sizeof(ElementID); */ + + if(fixed_params.ssid_id->len != 0){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: SSID in probe request not NULL\n", MODNAME);); + return; + } + + if(antistumbler_data.stumblers == NULL) + antistumbler_data.stumblers = AllocStumblerList(); + + stumbler_ptr = antistumbler_data.stumblers->head; + while(stumbler_ptr){ + + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: STA: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X (probe_cnt: %d, ts_init: %d, ts_last: %d, ts_diff: %d)\n", + MODNAME, stumbler_ptr->addr[0], stumbler_ptr->addr[1], stumbler_ptr->addr[2], + stumbler_ptr->addr[3], stumbler_ptr->addr[4], stumbler_ptr->addr[5], + stumbler_ptr->probe_cnt, stumbler_ptr->ts_init, stumbler_ptr->ts_last, + stumbler_ptr->ts_last - stumbler_ptr->ts_init);); + + if(memcmp(p->wifih->addr2, stumbler_ptr->addr, 6) == 0){ /* check to see if STA is on list */ + on_list = 1; + stumbler_ptr->probe_cnt++; + stumbler_ptr->ts_last = time_curr; + + + if(stumbler_ptr->probe_cnt >= antistumbler_data.probe_reqs){ + + if(stumbler_ptr->alert_flag == 0){ + stumbler_ptr->alert_flag = 1; + + snprintf(log_message, 128, "Detected Netstumbler traffic from %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", + stumbler_ptr->addr[0], stumbler_ptr->addr[1], stumbler_ptr->addr[2], + stumbler_ptr->addr[3], stumbler_ptr->addr[4], stumbler_ptr->addr[5]); + + SetEvent(&event, GENERATOR_SPP_ANTISTUMBLER, STUMBLER_DETECTED, 1, 4, 2, 0); + if(p->iph == NULL) /* horrible hack to get this to show up in ACID */ + p->iph = (IPHdr *)calloc(1, sizeof(IPHdr)); + + CallAlertFuncs(p, log_message, NULL, &event); /* send alert */ + } + } + + if(stumbler_ptr->ts_last - stumbler_ptr->ts_init >= antistumbler_data.probe_period){ + stumbler_ptr->ts_init = time_curr; + stumbler_ptr->probe_cnt = 1; + } + + } + if(time_curr - stumbler_ptr->ts_last >= antistumbler_data.expire_timeout){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Removing expired STA (%.2X:%.2X:%.2X:%.2X:%.2X:%.2X) from stumbler list\n", + MODNAME, stumbler_ptr->addr[0], stumbler_ptr->addr[1], stumbler_ptr->addr[2], + stumbler_ptr->addr[3], stumbler_ptr->addr[4], stumbler_ptr->addr[5]);); + stumbler_ptr = RemoveStumbler(stumbler_ptr, antistumbler_data.stumblers); + continue; + } + + stumbler_ptr = stumbler_ptr->next; + } + + if(!on_list){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Adding STA (%.2X:%.2X:%.2X:%.2X:%.2X:%.2X) to stumbler list\n", MODNAME, + p->wifih->addr2[0], p->wifih->addr2[1], p->wifih->addr2[2], + p->wifih->addr2[3], p->wifih->addr2[4], p->wifih->addr2[5]);); + + InsertStumbler(p->wifih->addr2, antistumbler_data.stumblers); + } +} + + + + void PreprocCleanExitFunction(int signal) +{ + /* clean exit code goes here */ +} + +void PreprocRestartFunction(int signal) +{ + /* restart code goes here */ +} + + +StumblerList *AllocStumblerList(void){ + return (StumblerList *)calloc(1, sizeof(StumblerList)); +} + + +void DestroyStumblerList(StumblerList *list){ +#warning "Implement DestroyStumblerList()" +} + + +/* + * Function: InsertStumbler(u_int8_t *, StumblerList *) + * + * Purpose: Creates a Stumbler node from a byte array and inserts + * it into the specified StumblerList + * + * Arguments: addr => byte array containing a MAC address + * list => StumblerList to insert new node in + * + * Returns: pointer to newly inserted Stumbler node or NULL + * if bssid or list is NULL + * + */ + +Stumbler *InsertStumbler(u_int8_t *addr, StumblerList *list){ + Stumbler *stumbler_ptr = NULL; + + if(list == NULL || addr == NULL) + return NULL; + + /* allocate new Stumbler node */ + stumbler_ptr = (Stumbler *)malloc(sizeof(Stumbler)); + memcpy(stumbler_ptr->addr, addr, 6); + stumbler_ptr->alert_flag = 0; + stumbler_ptr->probe_cnt = 1; + stumbler_ptr->ts_init = time(NULL); + stumbler_ptr->ts_last = stumbler_ptr->ts_init; + stumbler_ptr->next = NULL; + stumbler_ptr->prev = NULL; + + if(list->head == NULL && list->tail == NULL){ /* if empty list, set head and tail */ + list->head = stumbler_ptr; + list->tail = stumbler_ptr; + } + else{ /* if already a tail, link new node in */ + stumbler_ptr->prev = list->tail; + list->tail->next = stumbler_ptr; + list->tail = stumbler_ptr; + } + + return stumbler_ptr; /* return pointer to new Stumbler node */ +} + + + +/* + * Function: RemoveStumbler(Stumbler *, StumblerList *) + * + * Purpose: Removes a Stumbler node from a StumblerList + * + * Arguments: node => pointer to Stumbler node to be removed + * list => StumblerList to remove node from + * + * Returns: next Stumbler node in the list or NULL if one + * does not exist + */ + +Stumbler *RemoveStumbler(Stumbler *node, StumblerList *list){ + Stumbler *stumbler_ptr; + + if(list == NULL) + return node; + + if(node == list->head){ + if((list->head = node->next) == NULL) + list->tail = NULL; + else + node->next->prev = NULL; + } + else{ + if((node->next->prev = node->next) == NULL) + list->tail = node->prev; + else + node->next->prev = node->prev; + } + + stumbler_ptr = node->next; + free(node); + + return stumbler_ptr; +} + + + Index: snort/src/preprocessors/spp_antistumbler.h diff -u /dev/null snort/src/preprocessors/spp_antistumbler.h:1.2 --- /dev/null Mon Jun 13 11:20:21 2005 +++ snort/src/preprocessors/spp_antistumbler.h Thu Jul 24 02:32:37 2003 @@ -0,0 +1,166 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: spp_antistumbler.h,v 1.2 2003/07/24 06:32:37 andrew Exp $ */ + +#include "snort.h" + +#ifndef __SPP_ANTISTUMBLER_H__ +#define __SPP_ANTISTUMBLER_H__ + +#ifdef __SPP_ANTISTUMBLER_C__ + +#define ANTISTUMBLER_PROBE_REQS 5 +#define ANTISTUMBLER_PROBE_PERIOD 3 +#define ANTISTUMBLER_EXPIRE_TIMEOUT 60 + +typedef struct _Stumbler { + u_int8_t addr[6]; + int alert_flag; + int probe_cnt; + time_t ts_init, ts_last; + struct _Stumbler *next, *prev; +} Stumbler; + +typedef struct _StumblerList { + struct _Stumbler *head, *tail; +} StumblerList; + +typedef struct _AntiStumblerData +{ + int probe_reqs; + time_t probe_period; + time_t expire_timeout; + StumblerList *stumblers; +} AntiStumblerData; + + +typedef enum { /* 802.11 frame types */ + TYPE_INVALID = -1, + TYPE_MANAGEMENT = 0x00, + TYPE_CONTROL = 0x01, + TYPE_DATA = 0x02 +} wifi_type_t; + + +typedef enum { /* 802.11 management frame subtypes */ + STYPE_ASSOCREQ = 0x00, /* Subtypes are already AND'ed with their corresponding Types */ + STYPE_ASSOCRESP = 0x01, /* to prevent false positives and the need for checking the type */ + STYPE_REASSOC_REQ = 0x02, /* independently */ + STYPE_REASSOC_RESP = 0x03, + STYPE_PROBEREQ = 0x04, + STYPE_PROBERESP = 0x05, + STYPE_BEACON = 0x08, + STYPE_ATIM = 0x09, + STYPE_DIASSOC = 0x0a, + STYPE_AUTH = 0x0b, + STYPE_DEAUTH = 0x0c, + + STYPE_INVALID = 0x0d, + +/* 802.11 control frame subtypes */ + STYPE_PS = 0x0a, + STYPE_RTS = 0x0b, + STYPE_CTS = 0x0c, + STYPE_ACK = 0x0d, + STYPE_CFEND = 0x0e, + STYPE_CFEND_CFACK = 0x0f, + +/* 802.11 data frame subtypes */ + STYPE_DATA = 0x00, + STYPE_CFACK = 0x01, + STYPE_CFPOLL = 0x02, + STYPE_CFACK_CFPOLL = 0x03, + STYPE_NULLFUNC = 0x04, + STYPE_CFACK_NULLFUNC = 0x05, + STYPE_CFPOLL_NULLFUNC = 0x06, + STYPE_CFACK_CFPOLL_NULLFUNC = 0x07 +} wifi_stype_t; + +typedef struct _ElementID{ /* 802.11 element id */ + u_int8_t id; + u_int8_t len; +} ElementID; + +typedef struct _CapInfo{ /* 802.11 capability information */ + u_int16_t cap_ess:1; + u_int16_t cap_ibss:1; + u_int16_t cap_cfpoll:1; + u_int16_t cap_cfpoll_req:1; + u_int16_t cap_wep:1; + u_int16_t cap_reserved:11; +} CapInfo; + +#define _OFFSET_MANAGEMENT_BODY sizeof(WifiHdr) - 6 + +typedef struct _ProbeReq{ /* 802.11 probe request body */ +#define _OFFSET_PROBEREQ_SSID_ID 0 + ElementID *ssid_id; +#define _OFFSET_PROBEREQ_SSID _OFFSET_PROBEREQ_SSID_ID + sizeof(ElementID) + u_int8_t *ssid; + ElementID *rates_id; + u_int8_t *rates; +} ProbeReq; + + + + +typedef struct _Beacon{ /* relevant portion of beacon frame + for detecting Orinoco cards in monitor mode */ +#define _OFFSET_TIMESTAMP 0x00 + u_int32_t *timestamp1; + u_int32_t *timestamp2; + +#define _OFFSET_BEACON_INT _OFFSET_TIMESTAMP + 2 * sizeof(u_int32_t) + u_int16_t *beacon_interval; + +#define _OFFSET_BEACON_CAP_INFO _OFFSET_BEACON_INT + sizeof(u_int16_t) + CapInfo *cap_info; + +#define _OFFSET_BEACON_SSID_ID _OFFSET_BEACON_CAP_INFO + sizeof(CapInfo) + ElementID *ssid_id; +#define _OFFSET_BEACON_SSID _OFFSET_BEACON_SSID_ID + sizeof(ElementID) + u_int8_t *ssid; + + ElementID *rates_id; + u_int8_t *rates; + + u_int8_t *current_chan; + + /* we don't care about the rest right now */ +} Beacon; + +#define DECODE_PARAMS + +StumblerList *AllocStumblerList(void); +void DestroyStumblerList(StumblerList *); +Stumbler *InsertStumbler(u_int8_t *, StumblerList *); +Stumbler *RemoveStumbler(Stumbler *, StumblerList *); + +#endif /* __SPP_ANTISBUMBLER_C__ */ + +/* list of function prototypes for this preprocessor */ +void SetupAntiStumbler(); +void AntiStumblerInit(u_char *); +void AntiStumblerParseArgs(char *); +void AntiStumblerDetect(Packet *); +void PreprocRestartFunction(int); +void PreprocCleanExitFunction(int); + + +#endif /* __SPP_ANTISTUMBLER_H__ */ Index: snort/src/preprocessors/spp_rogue_ap.c diff -u /dev/null snort/src/preprocessors/spp_rogue_ap.c:1.1 --- /dev/null Mon Jun 13 11:20:21 2005 +++ snort/src/preprocessors/spp_rogue_ap.c Thu Jul 24 02:20:23 2003 @@ -0,0 +1,646 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: spp_rogue_ap.c,v 1.1 2003/07/24 06:20:23 andrew Exp $ */ + +/* spp_rogue_ap + * + * Purpose: + * + * Detects unauthorized wireless APs and AdHoc networks + * + * Arguments: + * + * , , scan_flag [0 | 1], scan_timeout , expire_timeout + * + * Where: + * + * => a single BSSID or a list specified as [, ...] + * + * => a single channel or a list specified as [, , ...] + * + * scan_flag => enable scanning of multiple channels + * + * scan_timeout => seconds to wait between scanning channels + * + * expire_timeout => expiration timeout for detected access points + * + * + * Effect: + * + * Sends an alert for each rogue network it detects of the form: + * "Rogue AP detected (BSSID XX:XX:XX:XX:XX:XX)" + * + * Comments: + * + * Detection on multiple channels will be implemented later + * + */ + +#include "generators.h" +#include "log.h" +#include "detect.h" +#include "decode.h" +#include "event.h" +#include "plugbase.h" +#include "parser.h" +#include "mstring.h" +#include "debug.h" +#include "util.h" + +#ifndef __SPP_ROGUE_AP_C__ +#define __SPP_ROGUE_AP_C__ +#include "spp_rogue_ap.h" +#endif + + +#define MODNAME "spp_rogue_ap" + +/* external globals from rules.c */ +extern char *file_name; +extern int file_line; + +RogueApData rogue_ap_data; /* preprocessor data */ + +/* + * Function: SetupRogueAp() + * + * Purpose: Registers the preprocessor keyword and initialization + * function into the preprocessor list. This is the function that + * gets called from InitPreprocessors() in plugbase.c. + * + * Arguments: None. + * + * Returns: void function + * + */ +void SetupRogueAp() +{ + /* link the preprocessor keyword to the init function in + the preproc list */ + RegisterPreprocessor("rogue_ap", RogueApInit); + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Preprocessor: RogueAp is setup...\n");); +} + + +/* + * Function: RogueApInit(u_char *) + * + * Purpose: Calls the argument parsing function, performs final setup on data + * structs, links the preproc function into the function list. + * + * Arguments: args => ptr to argument string + * + * Returns: void function + * + */ +void RogueApInit(u_char *args) +{ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Preprocessor: RogueAp Initialized\n");); + + /* parse the argument list from the rules file */ + RogueApParseArgs(args); + + /* Set the preprocessor function into the function list */ + AddFuncToPreprocList(RogueApDetect); +/* AddFuncToCleanExitList(RogueApCleanExit); */ +/* AddFuncToRestartList(RogueApRestart); */ + + + if(rogue_ap_data.scan_flag){ +#warning "Implement channel hopping" + } +} + + + +/* + * Function: RogueApParseArgs(char *) + * + * Purpose: Process the preprocessor arguements from the rules file and + * initialize the preprocessor's data struct. This function doesn't + * have to exist if it makes sense to parse the args in the init + * function. + * + * Arguments: args => argument list + * + * Returns: void function + * + */ + +void RogueApParseArgs(char *args) +{ + char *end_ptr; + char **arg_toks = NULL, **arg_args = NULL; + int i, n, n_args, n_arg_args; + BSSIDList *bssid_list; + u_int8_t bssid[6] = { 0 }; + + + memset(&rogue_ap_data, 0x00, sizeof(rogue_ap_data)); + rogue_ap_data.scan_timeout = ROGUE_AP_SCAN_TIMEOUT; /* default scan_timeout */ + rogue_ap_data.expire_timeout = ROGUE_AP_EXPIRE_TIMEOUT; /* default expire_timeout */ + + if(args == NULL) + return; + + rogue_ap_data.pass_list = BuildApList(&args); + rogue_ap_data.rogue_list = AllocBSSIDList(); + rogue_ap_data.channel_mask = BuildChannelMask(&args); + + if(*args){ + arg_toks = mSplit(args, ",", 3, &n_args, 0); + + if(n_args != 3){ + FatalError("%s: %s (%d) => rogue_ap configuration format: , ," + " scan_flag [ 0 | 1 ], scan_timeout , expire_timeout \n", MODNAME, file_name, file_line); + } + + for(i = 0; i < n_args; i++){ + arg_args = mSplit(arg_toks[i], " ", 2, &n_arg_args, 0); + if(n_arg_args != 2){ + FatalError("%s: %s (%d) => rogue_ap configuration format: , ," + " scan_flag [ 0 | 1 ], scan_timeout , expire_timeout \n", MODNAME, file_name, file_line); + } + + if(strcmp(arg_args[0], "scan_flag") == 0){ + n = strtol(arg_args[1], NULL, 10); + if(n != 0 && n != 1){ + FatalError("%s: %s (%d) => \"scan_flag\" must either be 0 or 1\n", MODNAME, file_name, file_line); + } + rogue_ap_data.scan_flag = n; + } + else if(strcmp(arg_args[0], "scan_timeout") == 0){ + n = strtol(arg_args[1], NULL, 10); + if(n <= 0){ + FatalError("%s: %s (%d) => \"scan_timeout\" must be non-negative\n", MODNAME, file_name, file_line); + } + rogue_ap_data.scan_timeout = n; + } + else if(strcmp(arg_args[0], "expire_timeout") == 0){ + n = strtol(arg_args[1], NULL, 10); + if(n <= 0){ + FatalError("%s: %s (%d) => \"expire_timeout\" must be non-negative\n", MODNAME, file_name, file_line); + } + rogue_ap_data.expire_timeout = n; + } + else{ + FatalError("%s: %s (%d) => Invalid argument \"%s %s\"\n", MODNAME, file_name, file_line, arg_args[0], arg_args[1]); + } + } + } + +} + + + +/* + * Function: RogueApDetect(Packet *) + * + * Purpose: Detect APs and AdHoc networks excluding ones specified + * by the ACCESS_POINTS variable in snort.conf + * + * Arguments: p => pointer to the current packet data struct + * + * Returns: void function + * + */ + +void RogueApDetect(Packet *p) +{ + Event event; + char log_message[128]; + BSSID *bssid_ptr; + u_int8_t *bssid; + time_t time_curr; + + if(!p->wifih) + return; + + time_curr = time(NULL); + + switch(p->wifih->type){ /* point bssid to the correct field in the frame */ + + case TYPE_MANAGEMENT: + bssid = p->wifih->addr3; + break; + + case TYPE_CONTROL: + + if(p->wifih->stype == STYPE_RTS || p->wifih->stype == STYPE_CTS || p->wifih->stype == STYPE_ACK){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Received Control frame subtype that does not contain BSSID\n", MODNAME);); + return; + } + else if(p->wifih->stype == STYPE_PS) + bssid = p->wifih->addr1; + else if(p->wifih->stype == STYPE_CFEND) + bssid = p->wifih->addr2; + else if(p->wifih->stype == STYPE_CFEND_CFACK) + bssid = p->wifih->addr2; + else{ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Received Control frame with unknown/invalid subtype\n", MODNAME);); + return; + } + + break; + + case TYPE_DATA: + if(p->wifih->to_ds){ + if(p->wifih->from_ds){ /* to_ds == 1 && from_ds == 1 */ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Received Data frame subtype that does not contain BSSID\n", MODNAME);); + return; + } + else /* to_ds == 1 && from_ds == 0 */ + bssid = p->wifih->addr1; + } + else{ + if(p->wifih->from_ds) /* to_ds == 0 && from_ds == 1 */ + bssid = p->wifih->addr2; + else /* to_ds == 0 && from_ds == 0 */ + bssid = p->wifih->addr3; + } + + break; + + default: + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Received frame with unknown/invalid type\n", MODNAME);); + return; + } + + + /* iterate through rogue AP list */ + bssid_ptr = rogue_ap_data.rogue_list->head; + while(bssid_ptr){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Checking %.2X:%.2X:%.2X:%.2X:%.2X:%.2X against rogue " + "(BSSID %.2X:%.2X:%.2X:%.2X:%.2X:%.2X)\n", MODNAME, + bssid[0], bssid[1], bssid[2], + bssid[3], bssid[4], bssid[5], + bssid_ptr->bssid[0], bssid_ptr->bssid[1], bssid_ptr->bssid[2], + bssid_ptr->bssid[3], bssid_ptr->bssid[4], bssid_ptr->bssid[5]);); + + if(time_curr - bssid_ptr->timestamp >= rogue_ap_data.expire_timeout){ + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Removing expired AP from rogue AP list (BSSID %.2X:%.2X:%.2X:%.2X:%.2X:%.2X)\n", + MODNAME, bssid_ptr->bssid[0], bssid_ptr->bssid[1], bssid_ptr->bssid[2], + bssid_ptr->bssid[3], bssid_ptr->bssid[4], bssid_ptr->bssid[5]);); + + bssid_ptr = RemoveBSSID(bssid_ptr, rogue_ap_data.rogue_list); /* remove BSSIDs that have expired */ + continue; + } + + if(memcmp(bssid, bssid_ptr->bssid, 6) == 0){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: BSSID already on rogue AP list (BSSID %.2X:%.2X:%.2X:%.2X:%.2X:%.2X)\n", + MODNAME, bssid_ptr->bssid[0], bssid_ptr->bssid[1], bssid_ptr->bssid[2], + bssid_ptr->bssid[3], bssid_ptr->bssid[4], bssid_ptr->bssid[5]);); + return; /* return if BSSID is already on the list */ + } + + bssid_ptr = bssid_ptr->next; + } + + /* iterate through legitimate AP list */ + for(bssid_ptr = rogue_ap_data.pass_list->head; bssid_ptr != NULL; bssid_ptr = bssid_ptr->next) + if(memcmp(bssid_ptr->bssid, bssid, 6) == 0){ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: BSSID on good AP list (BSSID %.2X:%.2X:%.2X:%.2X:%.2X:%.2X)\n", + MODNAME, bssid_ptr->bssid[0], bssid_ptr->bssid[1], bssid_ptr->bssid[2], + bssid_ptr->bssid[3], bssid_ptr->bssid[4], bssid_ptr->bssid[5]);); + return; /* return if the AP is legit */ + } + /* construct alert message */ + snprintf(log_message, 128, "Rogue AP detected (BSSID %.2X:%.2X:%.2X:%.2X:%.2X:%.2X)", + bssid[0], bssid[1], bssid[2], + bssid[3], bssid[4], bssid[5]); + + SetEvent(&event, GENERATOR_SPP_ROGUE_AP, ROGUE_AP_DETECTED, 1, 4, 2, 0); + if(p->iph == NULL) /* horrible hack to get this to show up in ACID */ + p->iph = (IPHdr *)calloc(1, sizeof(IPHdr)); + + CallAlertFuncs(p, log_message, NULL, &event); /* send alert */ + + InsertBSSID(bssid, rogue_ap_data.rogue_list); /* insert BSSID into rogue AP list */ + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Adding %.2X:%.2X:%.2X:%.2X:%.2X:%.2X to rogue AP list\n", MODNAME, + bssid[0], bssid[1], bssid[2], + bssid[3], bssid[4], bssid[5]);); +} + + + +void RogueApCleanExitFunction(int signal) +{ +#warning "Implement RogueApCleanExitFunction()" + /* clean exit code goes here */ +} + + + +void RogueApRestartFunction(int signal) +{ +#warning "Implement RogueApRestartFunction()" + /* restart code goes here */ +} + + + +/* + * Function: BuildApList(char **) + * + * Purpose: Parses bssid argument from the preprocessor's arguments string into a + * BSSIDList and points it to the end of the bssid argument + * + * Arguments: args_ptr => pointer to a string containing the preprocessor's arguments + * + * Returns: a BSSIDList of BSSIDs to exclude from alerts + * + */ + +BSSIDList *BuildApList(char **args_ptr){ + char *end_ptr; + char *args = *args_ptr; + BSSIDList *bssid_list = NULL; + u_int8_t bssid[6]; + + if(args == NULL || *args == '\0') + FatalError("%s: %s (%d) => rogue_ap configuration format: , ," + " scan_flag [ 0 | 1 ], scan_timeout , expire_timeout \n", MODNAME, file_name, file_line); + + + while(*args && isspace(*args)) /* eat up initial whitespace */ + args++; + + bssid_list = AllocBSSIDList(); + + memset(bssid, 0xff, 6); + InsertBSSID(bssid, bssid_list); + + /* parse the bssid or list of bssids */ + if(args[0] == '['){ + + for(end_ptr = ++args; *end_ptr && *end_ptr != ']'; end_ptr++) + if(*end_ptr == ','){ + *end_ptr = '\0'; + if(ParseBSSID(bssid, args) < 0) + FatalError("%s: %s (%d) => Error parsing BSSID \"%s\"\n", + MODNAME, file_name, file_line, args); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Adding %.2X:%.2X:%.2X:%.2X:%.2X:%.2X to good AP list\n", + MODNAME, bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);); + InsertBSSID(bssid, bssid_list); + args = end_ptr + 1; + } + + *end_ptr = '\0'; + if(ParseBSSID(bssid, args) < 0) + FatalError("%s: %s (%d) => Error parsing BSSID \"%s\"\n", + MODNAME, file_name, file_line, args); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Adding %.2X:%.2X:%.2X:%.2X:%.2X:%.2X to good AP list\n", + MODNAME, bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);); + InsertBSSID(bssid, bssid_list); + args = end_ptr + 1; + while(*args && *args != ',') args++; + if(*args) args++; + } + else{ + + for(end_ptr = args; *end_ptr && *end_ptr != ','; end_ptr++); + + *end_ptr = '\0'; + if(ParseBSSID(bssid, args) < 0) + FatalError("%s: %s (%d) => Error parsing BSSID \"%s\"\n", + MODNAME, file_name, file_line, args); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: Adding %.2X:%.2X:%.2X:%.2X:%.2X:%.2X to good AP list\n", + MODNAME, bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);); + InsertBSSID(bssid, bssid_list); + args = end_ptr + 1; + } + + *args_ptr = args; + + return bssid_list; +} + + + +/* + * Function: BuildChannelMask(char **) + * + * Purpose: Parses channel argument from the preprocessor's arguments string into a + * bitmask and points it to the end of the channel argument + * + * Arguments: args_ptr => pointer to a string containing the preprocessor's arguments + * + * Returns: a 16 bit mask containing the channels to be monitored + * + */ + +u_int16_t BuildChannelMask(char **args_ptr){ + char *end_ptr; + char *args = *args_ptr; + u_int16_t mask = 0; + int n; + + if(args == NULL || *args == '\0') + FatalError("%s: %s (%d) => rogue_ap configuration format: , ," + " scan_flag [ 0 | 1 ], scan_timeout , expire_timeout \n", MODNAME, file_name, file_line); + + while(*args && isspace(*args)) args++; /* eat initial white space */ + + + if(args[0] == '['){ + for(end_ptr = ++args; *end_ptr && *end_ptr != ']'; end_ptr++) + if(*end_ptr == ','){ + *end_ptr = '\0'; + n = strtol(args, NULL, 10); + if(n < ROGUE_AP_MIN_CHANNEL || n > ROGUE_AP_MAX_CHANNEL) + FatalError("%s: %s (%d) => Channel \"%s\" out of range\n", + MODNAME, file_name, file_line, args); + mask |= 1 << n; + args = end_ptr + 1; + } + + *end_ptr = '\0'; + n = strtol(args, NULL, 10); + if(n < ROGUE_AP_MIN_CHANNEL || n > ROGUE_AP_MAX_CHANNEL) + FatalError("%s: %s (%d) => Channel \"%s\" out of range\n", + MODNAME, file_name, file_line, args); + mask |= 1 << n; + args = end_ptr + 1; + + /* eat up to and including next ',' */ + while(*args && *args != ',') args++; + if(*args) args++; + } + else{ + for(end_ptr = args; *end_ptr && *end_ptr != ','; end_ptr++); + *end_ptr = '\0'; + n = strtol(args, NULL, 10); + if(n < ROGUE_AP_MIN_CHANNEL || n > ROGUE_AP_MAX_CHANNEL) + FatalError("%s: %s (%d) => Channel \"%s\" out of range\n", + MODNAME, file_name, file_line, args); + mask |= 1 << n; + args = end_ptr + 1; + } + + + + *args_ptr = args; + + return mask; +} + + + +/* + * Function: AllocBSSIDList(void) + * + * Purpose: Allocates a BSSIDList + * + * Arguments: None + * + * Returns: A pointer to the newly allocated BSSIDList or + * NULL on error + * + */ + + +BSSIDList *AllocBSSIDList(void){ + return (BSSIDList *)calloc(1, sizeof(BSSIDList)); +} + + + +void DestroyBSSIDList(BSSIDList *list){ +#warning "Implement DestroyBSSIDList()" +} + + + +/* + * Function: InsertBSSID(u_int8_t *, BSSIDList *) + * + * Purpose: Creates a BSSID node from a byte array and inserts + * it into the specified BSSIDList + * + * Arguments: bssid => byte array containing a BSSID + * list => BSSIDList to insert new node in + * + * Returns: pointer to newly inserted BSSID node or NULL + * if bssid or list is NULL + * + */ + +BSSID *InsertBSSID(u_int8_t *bssid, BSSIDList *list){ + BSSID *bssid_ptr = NULL; + + if(list == NULL || bssid == NULL) + return NULL; + + /* allocate new BSSID node */ + bssid_ptr = (BSSID *)malloc(sizeof(BSSID)); + bssid_ptr->not_flag = 0; + memcpy(bssid_ptr->bssid, bssid, 6); + bssid_ptr->timestamp = time(NULL); + bssid_ptr->next = NULL; + bssid_ptr->prev = NULL; + + if(list->head == NULL && list->tail == NULL){ /* if empty list, set head and tail */ + list->head = bssid_ptr; + list->tail = bssid_ptr; + } + else{ /* if already a tail, link new node in */ + bssid_ptr->prev = list->tail; + list->tail->next = bssid_ptr; + list->tail = bssid_ptr; + } + + return bssid_ptr; /* return pointer to new BSSID node */ +} + + + +/* + * Function: RemoveBSSID(BSSID *, BSSIDList *) + * + * Purpose: Removes a BSSID node from a BSSIDList + * + * Arguments: node => pointer to BSSID node to be removed + * list => BSSIDList to remove node from + * + * Returns: next BSSID node in the list or NULL if one + * does not exist + */ + +BSSID *RemoveBSSID(BSSID *node, BSSIDList *list){ + BSSID *bssid_ptr; + + if(list == NULL) + return node; + + if(node == list->head){ + if((list->head = node->next) == NULL) + list->tail = NULL; + else + node->next->prev = NULL; + } + else{ + if((node->next->prev = node->next) == NULL) + list->tail = node->prev; + else + node->next->prev = node->prev; + } + + bssid_ptr = node->next; + free(node); + + return bssid_ptr; +} + + + +/* + * Function: ParseBSSID(u_int8_t *, char *) + * + * Purpose: Parses BSSIDs from a character string and stores them + * in a byte array. + * + * Arguments: bssid => pointer to byte array to store parsed BSSID in + * mac_str => character string containing BSSID + * + * Returns: 0 on success, -1 on error + * + */ + +int ParseBSSID(u_int8_t *bssid, char *mac_str){ + int i = 0; + char *next = mac_str; + + while(*next){ + if((bssid[i] = strtol(mac_str, &next, 16)) > 255){ + return -1; + } + if(mac_str != next && i < 6){ + mac_str = next + 1; + i++; + } + else + return -1; + } + + return 0; +} Index: snort/src/preprocessors/spp_rogue_ap.h diff -u /dev/null snort/src/preprocessors/spp_rogue_ap.h:1.2 --- /dev/null Mon Jun 13 11:20:21 2005 +++ snort/src/preprocessors/spp_rogue_ap.h Sat Jul 26 23:21:44 2003 @@ -0,0 +1,132 @@ +/* +** Copyright (C) 2003 Andrew Lockhart +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* $Id: spp_rogue_ap.h,v 1.2 2003/07/27 03:21:44 andrew Exp $ */ +/* Snort Preprocessor Plugin Header File RogueAp */ + +#include "snort.h" + +#ifndef __SPP_ROGUE_AP_H__ +#define __SPP_ROGUE_AP_H__ + +#define ROGUE_AP_NUM_ARGS 2 +#define ROGUE_AP_SCAN_TIMEOUT 60 +#define ROGUE_AP_EXPIRE_TIMEOUT 60 * 60 * 12 /* 12 hours */ +#define ROGUE_AP_MAX_BSSIDS 255 +#define ROGUE_AP_MIN_CHANNEL 1 +#define ROGUE_AP_MAX_CHANNEL 11 + +#ifdef __SPP_ROGUE_AP_C__ + +typedef struct _BSSID { + u_int8_t not_flag; + u_int8_t bssid[6]; + time_t timestamp; + struct _BSSID *next, *prev; +} BSSID; + +typedef struct _BSSIDList { + struct _BSSID *head, *tail; +} BSSIDList; + +typedef struct _RogueApData { + BSSIDList *pass_list; /* list of our BSSIDs -- var ACCESS_POINTS from snort.conf */ + BSSIDList *rogue_list; /* list of gathered rogue BSSIDs */ + u_int16_t channel_mask; /* bitmask for channels 1-11 or 1-14 */ + u_int8_t scan_flag; /* channel scan flag */ + time_t scan_timeout; /* scan_timeout from snort.conf */ + time_t expire_timeout; /* expire_timeout from snort.conf */ + time_t scan_timer; /* timer for channel switching */ +} RogueApData; + +typedef enum { /* 802.11 frame types */ + TYPE_INVALID = -1, + TYPE_MANAGEMENT = 0x00, + TYPE_CONTROL = 0x01, + TYPE_DATA = 0x02 +} wifi_type_t; + +typedef enum { /* 802.11 management frame subtypes */ + STYPE_ASSOCREQ = 0x00, /* Subtypes are already AND'ed with their corresponding Types */ + STYPE_ASSOCRESP = 0x01, /* to prevent false positives and the need for checking the type */ + STYPE_REASSOC_REQ = 0x02, /* independently */ + STYPE_REASSOC_RESP = 0x03, + STYPE_PROBEREQ = 0x04, + STYPE_PROBERESP = 0x05, + STYPE_BEACON = 0x08, + STYPE_ATIM = 0x09, + STYPE_DISASSOC = 0x0a, + STYPE_AUTH = 0x0b, + STYPE_DEAUTH = 0x0c, + + STYPE_INVALID = 0x0d, +/* STYPE_INVALID = 0x0e, */ +/* STYPE_INVALID = 0x0f, */ +/* STYPE_INVALID = 0x10, */ +/* STYPE_INVALID = 0x11, */ +/* STYPE_INVALID = 0x12, */ +/* STYPE_INVALID = 0x13, */ +/* STYPE_INVALID = 0x14, */ +/* STYPE_INVALID = 0x15, */ +/* STYPE_INVALID = 0x16, */ +/* STYPE_INVALID = 0x17, */ +/* STYPE_INVALID = 0x18, */ +/* STYPE_INVALID = 0x19, */ + + +/* 802.11 control frame subtypes */ + STYPE_PS = 0x0a, + STYPE_RTS = 0x0b, + STYPE_CTS = 0x0c, + STYPE_ACK = 0x0d, + STYPE_CFEND = 0x0e, + STYPE_CFEND_CFACK = 0x0f, + +/* 802.11 data frame subtypes */ + STYPE_DATA = 0x00, + STYPE_CFACK = 0x01, + STYPE_CFPOLL = 0x02, + STYPE_CFACK_CFPOLL = 0x03, + STYPE_NULLFUNC = 0x04, + STYPE_CFACK_NULLFUNC = 0x05, + STYPE_CFPOLL_NULLFUNC = 0x06, + STYPE_CFACK_CFPOLL_NULLFUNC = 0x07 +} wifi_stype_t; + + +BSSIDList *BuildApList(char **); +u_int16_t BuildChannelMask(char **); +BSSIDList *AllocBSSIDList(void); +void DestroyBSSIDList(BSSIDList *); +BSSID *InsertBSSID(u_int8_t *, BSSIDList *); +BSSID *RemoveBSSID(BSSID *, BSSIDList *); +int ParseBSSID(u_int8_t *, char *); + +#endif /* __SPP_ROGUE_AP_C__ */ + + +void SetupRogueAp(); +void RogueApInit(u_char *); +void RogueApParseArgs(char *); +void RogueApDetect(Packet *); +void RogueApRestart(int); +void RogueApCleanExit(int); + + + +#endif /* !__SPP_ROGUE_AP_H__ */ Index: snort/src/win32/WIN32-Prj/Makefile diff -u /dev/null snort/src/win32/WIN32-Prj/Makefile:1.1.1.2 --- /dev/null Mon Jun 13 11:20:23 2005 +++ snort/src/win32/WIN32-Prj/Makefile Wed Apr 21 18:26:57 2004 @@ -0,0 +1,7 @@ +# Microsoft Visual Studio NMAKE File +# +# $Id: Makefile,v 1.2 2003/08/31 23:04:19 chris_reid Exp $ + +!MESSAGE Please use the following command line instead: +!MESSAGE NMAKE /f "snort.mak" CFG="?" +