[Snort-devel] good news and a question

Dragos Ruiu dr at ...40...
Wed Jan 3 20:26:47 EST 2001


Mebbe I can help here...

When I call ProcessPacket is when I receive a completed
fragmentgram (:-) and I am expecting it to be processed and disposed.
You should be able to inline all your new routines where the current 
ProcessPacket call is. Let me know if there is something I have
misunderstood here or if I can help in any way.

Though separating out the disposal function opens up opportunities for
some neat optimizations.

cheers,
--dr

On Wed, 03 Jan 2001, Todd Lewis wrote:
> Ok, I have refitted the paengine interface to look like this:
> 
>      typedef struct _pa_packet {
>             unsigned int code;
>             struct pcap_pkthdr pkthdr;
>             unsigned char * buf;
>      } pa_packet;
> 
>      typedef struct _paengine_s {
>         char *name; /* name of the paengine, e.g., "pcap" */
>         int (*configure)(char * config); /* config file entry for engine; 0 on>
>                                           * success, other on error */
>         int (*init)(void); /* initialize driver; 0 on success */
>         pa_packet* (*get_packet)(void);
>         int (*dispose_packet)(pa_packet *);
>         int (*close)(void); /* close driver; 0 on success */
>         int (*get_devtype)(void); /* # of the device type; called after conf() */
>         int (*get_capabilities)(void); /* caps of the driver; called after conf() */
>      } paengine_s;
> 
> snort.c:ProcessPacket() now looks like this:
> 
>      void ProcessPacket(paengine_s *pa)
>      {
>         int i;
>         pa_packet *k;
>         Packet p;
> 
>         while(1){
> 
>          k=pa->get_packet();
>          if(k->code==PA_PACKET_CODE_OK){
>          /* call the packet decoder */
>          (*grinder)(&p, p.pkth, k->buf);
> (...This middle part is the same as it ever was...)
>          ClearDumpBuf();
> 	  k.code = p.verdict;
>          i=pa->dispose_packet(k);
>          } else {
>              fprintf(stderr, "Packet engine returned error %i\n", k->code);
>          }
>         }
>      }
> 
> I have modified the netfilter paengine to support this interface, and
> it at least loads.  I've not gotten it actually running yet, since I'm
> running 2.2 and don't feel like rebooting into 2.4 right now, and I've
> not modified paengine_pcap.c yet, but both of those should come probably
> tomorrow.
> 
> Marty, I know that this isn't exactly how you wanted this done, but
> the processing needed to be hoisted from the paengine somehow, and I
> didn't have any answers to my last set of questions about this matter,
> so this is the only way I knew how to do it.  If someone can get me
> answers to those questions, then I'll be happy to revise this along the
> lines of what you were suggesting.
> 
> So, now that it compiles (ship it! ship it!), I need to retrofit the
> only other use of ProcessPacket() to fit the new interface.  Interestingly
> enough, it's a real doozy: spp_defrag.c:ReassembleIP().  There seems
> to be some confusion in the code itself as to what it is:
> 
>      /*
>       * Function: Packet *ReassembleIP(frag *froot)
>       * Purpose: Generate a Packet * to pass to DecodeIP
>       * Arguments:
>       * froot - root of the tree containing the last packet of the frame
>       * Returns: Packet *
>       */
>      Tree *ReassembleIP(Tree *froot)
>      {
>      (...)
> 
> I am guessing, based on the conflict between the comment and the code,
> that this is recently modified code.  (Again, I'm working off of 1.6.3
> for all of this.)
> 
> I hadn't really thought about the fragmentation/reassembly case.  I have
> an idea for how to handle this case, and then I need some advice on how
> to follow that plan.
> 
> The idea is this: firmly separate ProcessPacket() into four pieces, like
> this:
> 
> 	char * buf = get_packet();
> 	Packet * p = munge_packet();
> 	handle_packet(p, buf);
> 	dispose_packet(buf);
> 
> spp_defrag is called within handle_packet(), I am guessing.  I would
> have spp_defrag take its IP fragment, put it through munge_packet()
> and handle_packet(), and then take the resulting verdict on the traffic
> and apply that to the original packets.  So, a trace would look like this:
> 
> p=pa->get_packet() => munge_packet(p) => handle_packet(p)                                 +=> dispose_packet(p);
>                                                         |                                  |
>                                                         +=> q = defrag(p)                  p.status=q.status <=+
> 							                      |                                       |
> 									        +=> munge_packet(q) => handle_packet(q)
> 
> Sorry for the crappy art; I hope that that wasn't too unclear.  To put
> it another way, The main loop would call:
> 
> 	char * buf = get_packet();
> 	Packet * p = munge_packet();
> 	handle_packet(p, buf);
> 	dispose_packet(buf, p.action);
> 
> Inside handle_packet(), spp_defrag would do this:
> 
> 	char *dfbuf = defrag(buf);
> 	Packet * q = munge_packet();
> 	handle_packet(p, dfbuf);
> 	buf.action = dfbuf.action;
> 	return;
> 
> This way, if the fragmented packets contain an attack, it will be detected
> in the normal course, via the examination of the defrag'd traffic, and
> a verdict passed on it.  spp_defrag will convey this verdict upwards
> so that it will be applied against the original, undefrag'd packets,
> which will in this case be discarded.
> 
> Is this right?
> 
> --
> Todd Lewis                                       tlewis at ...120...
> 
>   God grant me the courage not to give up what I think is right, even
>   though I think it is hopeless.          - Admiral Chester W. Nimitz
> 
> 
> _______________________________________________
> Snort-devel mailing list
> Snort-devel at lists.sourceforge.net
> http://lists.sourceforge.net/mailman/listinfo/snort-devel
-- 
Dragos Ruiu <dr at ...9...>   dursec.com ltd. / kyx.net - we're from the future 
gpg/pgp key on file at wwwkeys.pgp.net




More information about the Snort-devel mailing list