⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spp_defrag.c

📁 该源码是用C语言编写的,实现网络入侵检测系统的功能
💻 C
📖 第 1 页 / 共 3 页
字号:
        new_tree_node->left = t->left;
        new_tree_node->right = t;
        t->left = NULL;
        t->size = 1+node_size(t->right);
    }
    else
    {
        new_tree_node->right = t->right;
        new_tree_node->left = t;
        t->right = NULL;
        t->size = 1+node_size(t->left);
    }
    new_tree_node->key = i;
    new_tree_node->size = 1 + node_size(new_tree_node->left) + node_size(new_tree_node->right);
    return new_tree_node;
}

/* Function: Tree * fragdelete(frag i, Tree *t)       */
/* Deletes i from the tree if it's there.               */
/* Return a pointer to the resulting tree.              */

Tree *fragdelete(frag i, Tree *t)
{
    Tree * x;
    int tsize;

    if(!t) return NULL;
    tsize = t->size;
    t = fragsplay(i,t);
    if(fragcompare(i, t->key) == 0)
    {               /* found it */
        if(!t->left)
        {
            x = t->right;
        }
        else
        {
            x = fragsplay(i, t->left);
            x->right = t->right;
        }

        if(t->key != NULL)
        {
#ifdef DEBUG
            fprintf(stderr, "------------------------\n");
            fprintf(stderr,"%p - p-struct Free\n", t->key);
            fprintf(stderr, "------------------------\n");
            fflush(stderr);        
            mem_freed += sizeof(Packet);
#endif
            fragmemuse -= sizeof(Packet);
            free(t->key);
        }

#ifdef DEBUG
        fprintf(stderr, "------------------------\n");
        fprintf(stderr,"%p - Tree Free\n", t);
        fprintf(stderr, "------------------------\n");
        fflush(stderr);        
        mem_freed += sizeof(Tree);
#endif
        fragmemuse -= sizeof(Tree);
        free(t);

        if(x)
        {
            x->size = tsize-1;
        }
        return x;
    }
    else
    {
        return t;                         /* It wasn't there */
    }
}

/* Function: Tree *fragfind_rank(int r, Tree *t)               */ 
/* Returns a pointer to the node in the tree with the given rank.  */
/* Returns NULL if there is no such node.                          */
/* Does not change the tree.  To guarantee logarithmic behavior,   */
/* the node found here should be splayed to the root.              */

Tree *fragfind_rank(int r, Tree *t)
{
    int lsize;
    if((r < 0) || (r >= node_size(t))) return NULL;
    for(; t != 0 ;)
    {
        lsize = node_size(t->left);
        if(r < lsize)
        {
            t = t->left;
        }
        else if(r > lsize)
        {
            r = r - lsize -1;
            t = t->right;
        }
        else
        {
            return t;
        }
    }
    return NULL;
}

/* Function: fragget_rank(t)                                 */
/* returns the rank of a tree element                           */

int fragget_rank(Tree *t)
{
    if(!t)
        return(0);
    return(node_size(t->left)+1);
}


/* Function: treedump(t)                                        */
/* dumps the tree in table form                                 */
void treedump(Tree *t)
{
    int loc;
    Tree *temp;
    fprintf(stdout,"Rank Ptr      ID       Lptr      Rptr \n");
    fprintf(stdout,"========================================== \n");
    for(loc = 0; loc < node_size(t); loc++)
    {
        temp = fragfind_rank(loc, t);
        fprintf(stdout,"%3d %p %d %p %p\n", loc, temp, ID(temp->key), temp->left, temp->right);
    }
    fflush(stdout);
}

/******Snort Stuff******/

/*
 * Function: SetupDefrag()
 * 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 SetupDefrag()
{
    RegisterPreprocessor("defrag", DefragInit);
}

/*
 * Function: DefragInit(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 DefragInit(u_char *args)
{
    AddFuncToPreprocList(PreprocDefrag);

    froot = NULL;  /* initialize empty fragment tree */
    fragmemuse = 0;      /* No memory yet */
    fragtimeout.tv_sec = FRAGTIMEOUTSEC;
    fragtimeout.tv_usec = FRAGTIMEOUTUSEC;
    fragsweep = 0;
}



/******Fragmentation Stuff******/

/* Function: fragaddrmatch(i,j)                         */
/* returns true if the fragments belong to the same reassembly      */
int fragaddrmatch(i,j)
frag i,j;
/* This is the comparison.                                   */
/* Returns 1 if i j have matching addresses else 0           */
{
#ifdef DEBUG
    printf("   =>  sip1 = 0x%X, sip2 = 0x%X\n", SADDR(i), SADDR(j));
    printf("   =>  dip1 = 0x%X, dip2 = 0x%X\n", DADDR(i), DADDR(j));
    printf("   =>  id1 = %d, id2 = %d\n", ID(i), ID(j));
    printf("   =>  proto1 = %d, proto2 = %d\n", PROTO(i), PROTO(j));
#endif    

    if(( SADDR(i) == SADDR(j) )
       && ( DADDR(i) == DADDR(j) )
       && ( ID(i) == ID(j) )
       && ( PROTO(i) == PROTO(j) ))
    {
        return(1);
    }

    return(0);
}

/*
 * Function: Packet *ReassembleIP(frag *froot)
 * Purpose: Generate a Packet * and pass it to ProcessPacket, then deallocate packet
 * Arguments: froot - root of the tree containing the last packet of the frame
 * Returns: tree with reassembled fragments deleted
 */
Tree *ReassembleIP(Tree *froot)
{
    Packet *p;
    int writecount = 0;
    char *np;
    u_char *tmp;
    u_int psize;
    int fragrank;
    unsigned int overhead, moreoverhead;
    IPHdr slowarisfix;

    psize = (froot->key)->dsize + FOFF(froot->key); /* last frag is at top of tree */

#ifdef DEBUG
    printf("psize calculated to be %d bytes (last payload: %d)(last offset: %d)\n", psize, (froot->key)->dsize, FOFF(froot->key));
#endif        

    /* we've got to have a packet at least as large as an ICMP header */
    if(psize < 4)
    {
        ErrorMessage("[!] ERROR: Defrag plugin is fucked up, calculated packet size too small\n");
    }

    /* hopefully moreoverhead here finds out about all the wierd MAC sizes like FDDI and ATM */
    moreoverhead = (char*)froot->key->iph - (char*)froot->key->pkt;
    overhead = (char*)froot->key->pkt - (char*)froot->key->pkth;
    /* Linux fix code */
    if(overhead < sizeof(struct pcap_pkthdr) || overhead > sizeof( struct pcap_pkthdr) + 2)
    {
        overhead = sizeof(struct pcap_pkthdr) + 2;
    }

#ifdef DEBUG
    printf("Overhead = %d, struct size = %d\n", overhead, sizeof(struct pcap_pkthdr));
#endif        

    p = (Packet *)malloc(sizeof(Packet));
    fragmemuse += sizeof(Packet);

#ifdef DEBUG
    fprintf(stderr, "+++++++++++++++++++++++++\n");
    fprintf(stderr, "%p + p-struct Alloc\n", p);
    fprintf(stderr, "+++++++++++++++++++++++++\n");
    fflush(stderr);
    mem_locked += sizeof(Packet);
#endif

    if(!p)
    {
        ErrorMessage("[!] ERROR: Unable to allocate memory for fragment rebuild!\n");
        return NULL;
    }

    /* MFR: Why are we copying this header if we're in the reassembly phase?
     *  Why not use the original and modify its data in place?
     */
    memcpy(p, froot->key, sizeof(Packet));

    /* SEMI BOGUS - setting up ethernet time header - required by one of the
     * decode routines - we set the timestamp equal to froot (last fragment)
     * note also that our bogus reassembledgrams may not have the bpf header
     * contiguous and datagram access through this pointer is suspect. Been warned.
     */
    p->pkth = (struct pcap_pkthdr *)malloc(psize + overhead + moreoverhead + sizeof(IPHdr) + 32);
    fragmemuse += (psize + overhead + moreoverhead + sizeof(IPHdr) + 32);

#ifdef DEBUG
    fprintf(stderr, "+++++++++++++++++++++++++\n");
    fprintf(stderr, "%p + frankenpacket Alloc\n", p->pkth);
    fprintf(stderr, "+++++++++++++++++++++++++\n");
    fflush(stderr);
    mem_locked += sizeof(psize+overhead+moreoverhead+sizeof(IPHdr)+32);
#endif

    if(!p->pkth)
    {
        ErrorMessage("[!] ERROR: Unable to allocate memory for fragment rebuild!\n");
#ifdef DEBUG
        fprintf(stderr, "------------------------\n");
        fprintf(stderr, "%p - p-struct Free\n", p);
        fprintf(stderr, "------------------------\n");
        fflush(stderr);
        mem_freed += sizeof(Packet);
#endif
        fragmemuse -= sizeof(Packet);
        free(p);
        return NULL;
    }

    p->iph = (IPHdr *)((u_char*)p->pkth + overhead + moreoverhead);
    p->pkt = (u_char*)p->iph - moreoverhead;

    /*
     * Now copy the header and fragments into the newly-allocated buffer,
     * reconstructing the packet chunk by chunk. Current algorithm is first 
     * write to an area wins, play with splay order to change.
     * we start from the last fragment and work back....
     */

    /* fill in packet header bpf header first*/
    memcpy(p->pkth, froot->key->pkth, overhead); 

    /* then the mac junk, split into two copies for Linux 
     * non-contiguous headers 
     */
    memcpy((char*)p->pkth + overhead, froot->key->pkt, moreoverhead); 

    /*
     * then the IP header just to be paranoid for debugging because in the
     * real world we would do these in one copy
     */
    tmp = (u_char *) froot->key->iph;
    memcpy(p->iph, tmp, sizeof(IPHdr)); 

    p->pkth->caplen = psize + overhead + moreoverhead + sizeof(IPHdr);
    p->pkth->len = p->pkth->caplen;

    /*
     * Clear the more fragments bit, and set the length in the ip header
     * (in network byte order).
     */
    p->iph->ip_len = htons((unsigned short)psize);
    p->iph->ip_off = 0;
    p->frag_flag = 0;

    fragrank = fragget_rank(froot);

#ifdef DEBUG
    printf("fragrank = %d, froot = %p, fragaddrmatch = %d\n", fragrank, froot, 
           fragaddrmatch(p, froot->key));
#endif        

    while(fragrank > 0 && froot && fragaddrmatch(p,froot->key))
    {
        if(FOFF(froot->key) + froot->key->dsize <= psize)
        {
#ifdef DEBUG
            printf("Writing %d bytes from %p at %p\n", froot->key->dsize, 
                   DATA(froot->key), (u_int8_t *) DATA(p)+FOFF(froot->key));        
#endif            
            memcpy((u_int8_t *)DATA(p)+FOFF(froot->key), DATA(froot->key), 
                   froot->key->dsize);

            writecount += froot->key->dsize;

#ifdef DEBUG

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -