diff -uNr snort-2.8.3.2/src/plugbase.c snort-2.8.3.2-conficker/src/plugbase.c
--- snort-2.8.3.2/src/plugbase.c	2008-08-12 11:36:27.000000000 -0700
+++ snort-2.8.3.2-conficker/src/plugbase.c	2009-04-01 11:21:36.000000000 -0700
@@ -60,6 +60,7 @@
 #include "preprocessors/spp_flow.h"
 #include "preprocessors/spp_sfportscan.h"
 #include "preprocessors/spp_frag3.h"
+#include "preprocessors/spp_conficker.h"
 
 /* built-in detection plugins */
 #include "detection-plugins/sp_pattern_match.h"
@@ -501,6 +502,7 @@
     SetupPsng();
     SetupFrag3();
     SetupStream5();
+    SetupConfickerMon();
 }
 
 void CleanupPreprocessorSigList(PreprocSignalFuncNode *sig)
diff -uNr snort-2.8.3.2/src/preprocessors/Makefile.am snort-2.8.3.2-conficker/src/preprocessors/Makefile.am
--- snort-2.8.3.2/src/preprocessors/Makefile.am	2007-11-12 15:19:26.000000000 -0800
+++ snort-2.8.3.2-conficker/src/preprocessors/Makefile.am	2009-04-01 11:21:36.000000000 -0700
@@ -25,7 +25,8 @@
 spp_frag3.c spp_frag3.h \
 str_search.c str_search.h \
 spp_stream5.c spp_stream5.h \
-stream_api.c stream_api.h 
+stream_api.c stream_api.h \
+spp_conficker.c spp_conficker.h
 
 
 INCLUDES = @INCLUDES@
diff -uNr snort-2.8.3.2/src/preprocessors/Makefile.in snort-2.8.3.2-conficker/src/preprocessors/Makefile.in
--- snort-2.8.3.2/src/preprocessors/Makefile.in	2008-12-30 08:18:08.000000000 -0800
+++ snort-2.8.3.2-conficker/src/preprocessors/Makefile.in	2009-04-01 11:21:36.000000000 -0700
@@ -55,7 +55,7 @@
 	spp_httpinspect.$(OBJEXT) snort_httpinspect.$(OBJEXT) \
 	spp_flow.$(OBJEXT) portscan.$(OBJEXT) spp_sfportscan.$(OBJEXT) \
 	spp_frag3.$(OBJEXT) str_search.$(OBJEXT) spp_stream5.$(OBJEXT) \
-	stream_api.$(OBJEXT)
+	stream_api.$(OBJEXT) spp_conficker.$(OBJEXT)
 libspp_a_OBJECTS = $(am_libspp_a_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
 depcomp =
diff -uNr snort-2.8.3.2/src/preprocessors/spp_conficker.c snort-2.8.3.2-conficker/src/preprocessors/spp_conficker.c
--- snort-2.8.3.2/src/preprocessors/spp_conficker.c	1969-12-31 16:00:00.000000000 -0800
+++ snort-2.8.3.2-conficker/src/preprocessors/spp_conficker.c	2009-04-01 16:59:40.000000000 -0700
@@ -0,0 +1,443 @@
+/*
+** Copyright (c) 2008, SRI International. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** 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
+ */
+
+
+/* Snort Preprocessor Plugin Source File */
+
+/* @file	spp_conficker.c
+ *
+ * @author	vinod yegneswaran
+ *
+ * @brief	Conficker C P2P monitor
+ *
+ * Purpose:	Monitors P2P chatter of Conficker infected hosts
+ *
+ */
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "snort.h"
+#include "detect.h"		// SetEvent (), Call{Alert,Log}Funcs ()
+#include "plugbase.h"		// AddFuncToPreproc* ()
+#include "packet_time.h"	// packet_timeofday ()
+#include "sfxhash.h"
+#include "util.h"		// LogMessage ()
+
+
+#define WORD2(x)   (*((short*)&(x)+2))
+
+#define GID_CFKRMON	231
+
+#define CFKR_P2P_PACKET 1
+
+#define CFKR_WATCHLIST_SIZE	1000
+#define CFKR_TARGET_THRESH	10
+#define CFKR_MEMCAP		100000
+
+// fire every 10000th packet after target thresh has been reached
+#define CFKR_PKT_THRESH		10000
+
+
+/* list of function prototypes for this preprocessor */
+static void CfkrMonInit(char *);
+static void CfkrMonFind(Packet *, void *);
+
+static void CfkrShutdownFunction (int, void *);
+
+typedef union {
+  int16_t  s16[8];
+  uint16_t u16[8];
+  int32_t  s32[4];
+} result_t;
+
+typedef union {
+  int64_t  s64;
+  int32_t  s32[2];
+  uint32_t u32[2];
+  int16_t  s16[4];
+} var_t;
+
+typedef struct CfkrScanner
+{
+  uint32_t loc_addr;
+  uint32_t target_map[CFKR_TARGET_THRESH];
+  int 	   tgt_count;
+  int 	   pkt_count;
+  int 	   level;
+} CfkrScanner;
+
+
+/* This array clearly has some magic structure, but we don't know what it is yet */
+static uint32_t magic[64] =
+{
+    0xffffffff, 0xffffffff, 0xf0f6bfbb, 0xbb5a5ff3,
+    0xf3977011, 0xeb67bfbf, 0x5f9bfac8, 0x34d88091,
+    0x1e2282df, 0x573402c4, 0xc0000084, 0x03000209,
+    0x01600002, 0x00005000, 0x801000c0, 0x00500040,
+    0x000000a1, 0x01000000, 0x01000000, 0x00022a20,
+    0x00000080, 0x04000000, 0x40020000, 0x88000000,
+    0x00000180, 0x00081000, 0x08801900, 0x00800b81,
+    0x00000280, 0x080002c0, 0x00a80000, 0x00008000,
+    0x00100040, 0x00100000, 0x00000000, 0x00000000,
+    0x10000008, 0x00000000, 0x00000000, 0x00000004,
+    0x00000002, 0x00000000, 0x00040000, 0x00000000,
+    0x00000000, 0x00000000, 0x00410000, 0x82000000,
+    0x00000000, 0x00000000, 0x00000001, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000008, 0x80000000
+};
+
+#define magic_shift(x) (1 << ((x >> 5) & 0x1F)) & magic[x >> 10]
+
+
+static SFXHASH	*CfkrWatchList = (SFXHASH *) NULL;
+
+
+/*
+ * Function: SetupConfickerMon()
+ *
+ * Purpose: Registers the preprocessor keyword and initialization 
+ *          function into the preprocessor list.  
+ *
+ * Arguments: None.
+ *
+ * Returns: void function
+ *
+ */
+  void
+SetupConfickerMon (void)
+{
+  RegisterPreprocessor ("cfkr", CfkrMonInit);
+  DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, 
+			  "Preprocessor: ConfickerMon is setup...\n"););
+}
+
+
+/*
+ * Function: ProcessArgs(char *)
+ *
+ * Purpose: Parse additional config items.
+ *
+ * Arguments: args => ptr to argument string
+ *
+ *
+ * Returns: void function
+ *
+ */
+  static void
+ProcessArgs(char *args)
+{
+  /***** TBD *****/
+}
+
+
+/*
+ * Function: CfkrMonInit(char *)
+ *
+ * Purpose: Link the Conficker preprocessor to the preperocessor call chain.
+ *
+ * Arguments: args => ptr to argument string 
+ *
+ * Returns: void function
+ *
+ */
+  static void
+CfkrMonInit(char *args)
+{
+  static int CfkrMonIsInitialized = 0;
+  
+  if ( !CfkrMonIsInitialized ) {
+    /*...Perform endian-check...*/
+    union {
+      long aLong;
+      char cArray[4];
+    } value = {0x00000001L};
+
+    /*...Little-endian...*/
+    if (value.cArray[0] /* != 0 */) {
+      DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,
+			      "Preprocessor: ConfikerMon Initialized\n"););
+
+      /* Set the preprocessor function into the function list */
+      AddFuncToPreprocList(CfkrMonFind, PRIORITY_SCANNER, PP_CFKR);
+      AddFuncToPreprocShutdownList (CfkrShutdownFunction, (void *) NULL,
+				    PRIORITY_SCANNER, PP_CFKR);
+      AddFuncToPreprocRestartList (CfkrShutdownFunction, (void *) NULL,
+				   PRIORITY_SCANNER, PP_CFKR);
+    }
+
+    /*...Big-endian...*/
+    else {
+      DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,
+			      "Preprocessor: ConfikerMon not initialized\n"););
+      LogMessage ("*** WARNING: "
+		  "Preprocessor cfkr only runs on little-endian platforms"
+		  " ***");
+    }
+    
+    CfkrMonIsInitialized = 1;
+  }
+  
+  if (CfkrWatchList /* != (SFXHASH *) NULL */)
+    sfxhash_delete (CfkrWatchList);
+  
+  CfkrWatchList = sfxhash_new (CFKR_WATCHLIST_SIZE, sizeof (uint32_t),
+			       sizeof (CfkrScanner), CFKR_MEMCAP,
+			       1, (int (*) (void *, void *)) NULL,
+			       (int (*) (void *, void *)) NULL, 1);
+  
+  ProcessArgs(args);
+}
+
+
+/* 
+   NB: the portgen() function below is endian-dependent, and reverse-
+   engineered for a little-endian (e.g. x86, VAX, Alpha, etc.) machine.
+   Changes will be required for the array offsets in the unions to run on a
+   big-endian (e.g. most SPARC, Power(PC), MIPS, etc.)  machine.  Other than
+   the endian issue, I believe this is portable.
+
+   Simplified with help from Drew Dean
+*/
+  static int
+check_port(int ip, int week, ushort port)
+{
+  var_t v;	
+  int64_t KONST = 0x15A4E35;
+  int i;
+  result_t res;
+
+  (void) memset(&res, 0, sizeof(result_t));
+
+  v.s32[0] = ~ip;
+
+  do {
+    do {
+      v.s64 = KONST * v.u32[0] + 1;
+      res.s16[0] ^= v.s16[2];
+      
+      for (i=1; i < 10; i++) {
+	v.s64 = KONST * v.u32[0] + 1;
+	res.s16[(i & 0x01) << 1] ^= v.s32[1] >> i;
+      }
+      
+    } while (magic_shift(res.s32[0]));
+    
+  } while (magic_shift(res.s32[1]) || res.s32[0] == res.s32[1]);
+  
+  v.s32[0] = week ^ v.s64;
+  
+  do {
+    do {
+      v.s64 = KONST * v.u32[0] + 1;
+      res.s16[4] ^= v.s16[2];
+      
+      for (i=1; i < 10; i++) {
+	v.s64 = KONST * v.u32[0] + 1;
+	res.s16[((i & 0x01) << 1) | 4] ^= v.s32[1] >> i;
+      }
+      
+    } while (magic_shift(res.s32[2]));
+    
+  } while (magic_shift(res.s32[3]) ||
+	   res.s32[2] == res.s32[3] || 
+	   res.s32[0] == res.s32[2] || res.s32[1] == res.s32[2] || 
+	   res.s32[0] == res.s32[3] || res.s32[1] == res.s32[3]);
+  
+  for (i=0; i<8; i++) {
+    if (res.u16[i] /* != 0 */ && res.u16[i] == port) {
+      return 1;
+    }
+  }
+  
+  return 0;
+}
+
+
+  static int
+TrackCfkrHost(uint32_t localip, uint32_t remoteip) {
+  CfkrScanner *cs;
+
+  if (CfkrWatchList == (SFXHASH *) NULL)
+    return;			/* close the door behind us */
+
+  cs = (CfkrScanner*) sfxhash_find(CfkrWatchList, (void*) &localip);
+
+  /*...New scanner...*/
+  if(!cs) {
+    int iRet = sfxhash_add(CfkrWatchList, (void *)&localip, NULL);
+
+    if(iRet == SFXHASH_OK) {
+      cs = (CfkrScanner*)sfxhash_mru(CfkrWatchList);
+
+      if(!cs)
+	return -1;
+      
+      cs->loc_addr = localip;
+      cs->target_map[0] = remoteip;
+      cs->tgt_count = 1;
+      cs->pkt_count = 0;
+      cs->level = 0;
+    }
+    else {
+      // clear entries?
+      return -1;
+    }
+  }
+
+  /*...Pre-existing scanner...*/
+  else {
+    int i;
+
+    for (i=0; i < cs->tgt_count; i++) {
+      if (cs->target_map[i] == remoteip)
+	return 0;
+    }
+
+    if (cs->tgt_count < CFKR_TARGET_THRESH) {
+      cs->target_map[cs->tgt_count] = remoteip;
+      cs->tgt_count++;
+      return 0;
+    }
+
+    cs->target_map[0] = remoteip;
+
+
+    switch (cs->level) {
+    case 3:
+      if (cs->pkt_count++ == CFKR_PKT_THRESH) {
+	cs->pkt_count = 0;
+	return 4;
+      }
+      break;
+    case 2:
+      if (cs->pkt_count++ == 100) {
+	cs->pkt_count = 0;
+	cs->level++;
+	return 3;
+      }
+      break;
+    case 1:
+      if (cs->pkt_count++ == 10) {
+	cs->pkt_count = 0;
+	cs->level++;
+	return 2;
+      }
+      break;
+
+    default:
+      	cs->pkt_count = 0;
+	cs->level++;
+	return 1;
+    }
+  }
+  
+  return 0;
+  
+}
+
+
+  static int
+CfkrLogAlert (u_int32_t gen_id, u_int32_t sig_id, u_int32_t sig_rev,
+	      u_int32_t classification, u_int32_t priority, char* msg,
+	      Packet p)
+{
+  /* Patches courtesy Victor Julien <victor@inliniac.net>, Mon, 10 Mar 2008 */
+  Event  event;
+
+  SetEvent (&event, gen_id, sig_id, sig_rev, classification, priority, 0);
+  CallAlertFuncs (&p, msg, NULL, &event);
+  CallLogFuncs   (&p, msg, NULL, &event);
+  
+  return event.event_id;
+}
+
+
+static void PrintAlert(int val, Packet* p) {
+  switch (val) {
+  case 1:
+    CfkrLogAlert(GID_CFKRMON, CFKR_P2P_PACKET, 1, DECODE_CLASS, 3,
+		 "Conficker P2P Communication (> 10 hosts contacted)", *p);
+    break;
+  case 2:
+    CfkrLogAlert(GID_CFKRMON, CFKR_P2P_PACKET, 1, DECODE_CLASS, 3,
+		 "Conficker P2P Communication (> 10 hosts contacted and > 100 packets sent)", *p);
+    break;
+  case 3:
+    CfkrLogAlert(GID_CFKRMON, CFKR_P2P_PACKET, 1, DECODE_CLASS, 3,
+		 "Conficker P2P Communication (> 10 hosts contacted and > 1000 packets sent)", *p);
+    break;
+  case 4:
+    CfkrLogAlert(GID_CFKRMON, CFKR_P2P_PACKET, 1, DECODE_CLASS, 3,
+		 "Conficker P2P Communication (> 10 hosts contacted and > 10000 packets sent)", *p);
+    break;
+  } 
+
+}
+
+
+/*
+ * Function: CfkrMonFind(Packet *)
+ *
+ * Purpose: Look and alert on outbound Conficker packets.
+ *
+ * Arguments: p => pointer to the current packet data struct 
+ *
+ * Returns: void function
+ *
+ *
+ */
+static void CfkrMonFind(Packet *p, void *context)
+{
+    uint16_t dstport = 0U;
+
+    if (!PacketIsIP(p) || !SourceIpIsHomenet(p))
+      return; 
+    
+    if      (PacketIsUDP(p))
+      dstport = ntohs(p->udph->uh_dport);
+    
+    else if (PacketIsTCP(p))
+      dstport = ntohs(p->tcph->th_dport);
+
+    if (dstport > 2000) {
+      uint32_t dsthost = p->iph->ip_dst.s_addr;
+      uint32_t epoch   = (uint32_t) ((packet_timeofday() - 0x54600) / (3600 * 24 * 7));
+
+      if (check_port(dsthost, epoch, dstport)) {
+	uint32_t srchost = p->iph->ip_src.s_addr;
+
+	PrintAlert(TrackCfkrHost(srchost, dsthost), p);
+      }
+    }
+       
+    return;
+}
+
+
+  static void
+CfkrShutdownFunction (int signal, void *data)
+{
+  if (CfkrWatchList /* != (SFXHASH *) NULL */) {
+    sfxhash_delete (CfkrWatchList);
+    CfkrWatchList = (SFXHASH *) NULL;
+  }
+}
diff -uNr snort-2.8.3.2/src/preprocessors/spp_conficker.h snort-2.8.3.2-conficker/src/preprocessors/spp_conficker.h
--- snort-2.8.3.2/src/preprocessors/spp_conficker.h	1969-12-31 16:00:00.000000000 -0800
+++ snort-2.8.3.2-conficker/src/preprocessors/spp_conficker.h	2009-04-01 13:24:27.000000000 -0700
@@ -0,0 +1,35 @@
+/*
+** Copyright (c) 2008, SRI International. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** 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
+ */
+
+
+/* $Id:$ */
+/* Snort Preprocessor Plugin Header File Template */
+
+/* This file gets included in plugbase.h when it is integrated into the rest
+ * of the program.
+ */
+
+#ifndef __SPP_CFKR_H__
+#define __SPP_CFKR_H__
+
+/* 
+ * list of function prototypes to export for this preprocessor 
+ */
+void SetupConfickerMon (void);
+
+#endif  
diff -uNr snort-2.8.3.2/src/preprocids.h snort-2.8.3.2-conficker/src/preprocids.h
--- snort-2.8.3.2/src/preprocids.h	2008-03-04 11:53:21.000000000 -0800
+++ snort-2.8.3.2-conficker/src/preprocids.h	2009-04-01 11:21:36.000000000 -0700
@@ -66,6 +66,8 @@
 #define PP_SKYPE                  28
 #define PP_SSL                    29
 #define PP_RULES                  30
+#define PP_BHSD                   61
+#define PP_CFKR                   62
 
 #define PRIORITY_FIRST 0x0
 #define PRIORITY_NETWORK 0x10
