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

📄 decode.c

📁 该软件是一个有名的基于网络的入侵检测系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: decode.c,v 1.23 2000/03/16 02:58:43 roesch Exp $ */
/*
** Copyright (C) 1998,1999,2000 Martin Roesch <roesch@clark.net>
**
** 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.
*/

#include "decode.h"

/****************************************************************************
 *
 * Function: DecodeEthPkt(char *, struct pcap_pkthdr*, u_char*)
 *
 * Purpose: Decode those fun loving ethernet packets, one at a time!
 *
 * Arguments: user => I don't know what this is for, I don't use it but it has
 *                    to be there
 *            pkthdr => ptr to the packet header
 *            pkt => pointer to the real live packet data
 *
 * Returns: void function
 *
 ****************************************************************************/
void DecodeEthPkt(Packet *p, struct pcap_pkthdr *pkthdr, u_char *pkt)
{
    int pkt_len;  /* suprisingly, the length of the packet */
    int 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 */
    p->caplen = cap_len;

    if (snaplen < pkt_len)
        pkt_len = cap_len;

#ifdef DEBUG
    printf("Packet!\n");
    printf("caplen: %d    pktlen: %d\n", cap_len, pkt_len);
#endif

    /* do a little validation */
    if (p->pkth->caplen < ETHERNET_HEADER_LEN)
    {
        if (pv.verbose_flag)
        {
            ErrorMessage( "Captured data length < Ethernet header length! (%d bytes)\n", p->pkth->caplen);
        }

        return;
    }

    /* lay the ethernet structure over the packet data */
    p->eh = (EtherHdr *) pkt;


#ifdef DEBUG
    ErrorMessage("%X   %X\n", *p->eh->ether_src, *p->eh->ether_dst);
#endif

    /* grab out the network type */
    switch (ntohs(p->eh->ether_type))
    {
        case ETHERNET_TYPE_IP:
            DecodeIP(p->pkt+ETHERNET_HEADER_LEN, cap_len-ETHERNET_HEADER_LEN, p);
            return;

        case ETHERNET_TYPE_ARP:
        case ETHERNET_TYPE_REVARP:
            pc.arp++;

            DecodeARP(p->pkt+ETHERNET_HEADER_LEN, cap_len-ETHERNET_HEADER_LEN, p);

            return;

        case ETHERNET_TYPE_IPV6:
            pc.ipv6++;
            if (pv.showipv6_flag)
            {
                DecodeIPV6(p->pkt+ETHERNET_HEADER_LEN, (cap_len-ETHERNET_HEADER_LEN));
            }

            return;

        case ETHERNET_TYPE_IPX:
            pc.ipx++;
            if (pv.showipx_flag)
            {
                DecodeIPX(p->pkt+ETHERNET_HEADER_LEN, (cap_len-ETHERNET_HEADER_LEN));
            }

            return;

        default:
            pc.other++;
            return;
    }

    return;
}




/****************************************************************************
 *
 * Function: DecodeNullPkt(char *, struct pcap_pkthdr*, u_char*)
 *
 * Purpose: Decoding on loopback devices.
 *
 * Arguments: user => I don't know what this is for, I don't use it but it has
 *                    to be there
 *            pkthdr => ptr to the packet header
 *            pkt => pointer to the real live packet data
 *
 * Returns: void function
 *
 ****************************************************************************/
void DecodeNullPkt(Packet *p, struct pcap_pkthdr *pkthdr, u_char *pkt)
{
    u_int len;
    u_int cap_len;


    bzero((char *)p, sizeof(Packet));

    p->pkth = pkthdr;
    p->pkt = pkt;

    len = pkthdr->len;
    cap_len = pkthdr->caplen;

#ifdef DEBUG
    printf("Packet!\n");
#endif

    /* do a little validation */
    if (cap_len < NULL_HDRLEN)
    {
        ErrorMessage( "NULL header length < captured len! (%d bytes)\n",
                      cap_len);
        return;
    }

    DecodeIP(p->pkt + NULL_HDRLEN, cap_len - NULL_HDRLEN, p);
}

/****************************************************************************
 *
 * Function: DecodeTRPkt(char *, struct pcap_pkthdr*, u_char*)
 *
 * Purpose: Decode Token Ring packets!
 *
 * Arguments: user => I don't know what this is for, I don't use it but it has
 *                    to be there
 *            pkthdr => ptr to the packet header
 *            pkt => pointer to the real live packet data
 *
 * Returns: void function
 *
 ****************************************************************************/
void DecodeTRPkt(Packet *p, struct pcap_pkthdr *pkthdr, u_char *pkt)
{
    int pkt_len;  /* suprisingly, the length of the packet */
    int cap_len;  /* caplen value */
    int dataoff; /* data offset is variable here */



    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;

#ifdef DEBUG
    printf("Packet!\n");
    printf("caplen: %d    pktlen: %d\n", cap_len, pkt_len);
#endif

    /* do a little validation */
    if (p->pkth->caplen < TR_HLEN)
    {
        if (pv.verbose_flag)
            ErrorMessage( "Captured data length < Token Ring header length! (%d < %d bytes)\n", p->pkth->caplen, TR_HLEN);
        return;
    }

    /* lay the tokenring header structure over the packet data */
    p->trh = (Trh_hdr *) pkt;  
/*
 * according to rfc 1042:	
    The presence of a Routing Information Field is indicated by the Most
    Significant Bit (MSB) of the source address, called the Routing
    Information Indicator (RII).  If the RII equals zero, a RIF is
    not present.  If the RII equals 1, the RIF is present.
    ..
    However the MSB is already zeroed by this moment, so there's no 
    real way to figure out whether RIF is presented in packet, so we are 
    doing some tricks to find IPARP signature..					       
*/

    /* first I assume that we have single-ring network
     * with no RIF information presented in frame
     */
    p->trhllc=(Trh_llc *)(pkt + sizeof(Trh_hdr));


    if (p->trhllc->dsap!=IPARP_SAP && p->trhllc->ssap!=IPARP_SAP)
    {
        /* DSAP != SSAP != 0xAA .. either we are
         * having frame which doesn't carry IP datagrams
         * or has RIF information present. We assume the
         * latter ...
         */
        p->trhmr=(Trh_mr *)(pkt + sizeof(Trh_hdr));
        p->trhllc=(Trh_llc *)(pkt + sizeof(Trh_hdr) + p->trhmr->len);
        dataoff=sizeof(Trh_hdr) + p->trhmr->len + sizeof(Trh_llc);
    }
    else
    {
        p->trhllc=(Trh_llc *)(pkt + sizeof(Trh_hdr));
        dataoff=sizeof(Trh_hdr) + sizeof(Trh_llc);
    }

    /* idealy we would need to check both SSAP, DSAP, and protoid 
     * fields:
             IP datagrams and ARP requests and replies are
             transmitted in standard 802.2 LLC Type 1 Unnumbered
             Information format, control code 3, with the DSAP and
             the SSAP fields of the 802.2 header set to 170, the
             assigned global SAP value for SNAP [6].  The 24-bit
             Organization Code in the SNAP is zero, and the
             remaining 16 bits are the EtherType from Assigned
             Numbers [7] (IP = 2048, ARP = 2054).
             ..
        but we would check SSAP and DSAP and assume this would 
        be enough to trust.
        */
    if (p->trhllc->dsap!=IPARP_SAP && p->trhllc->ssap!=IPARP_SAP)
    {
#ifdef DEBUG
        ErrorMessage("DSAP and SSAP arent set to SNAP\n");
#endif
        p->trhllc = NULL;
        return;
    }

    pkt_len -= dataoff;
    cap_len -= dataoff;

    switch (htons(p->trhllc->ethertype))
    {
        case ETHERNET_TYPE_IP:
#ifdef DEBUG
            printf("Decoding IP\n");
#endif
            DecodeIP(p->pkt+dataoff, cap_len, p);
            return;

        case ETHERNET_TYPE_ARP:
        case ETHERNET_TYPE_REVARP:
#ifdef DEBUG
            printf("Decoding ARP (not really....)\n");
#endif
            pc.arp++;

            return;

        default:
#ifdef DEBUG
            printf("Unknown network protocol: %d\n", htons(p->trhllc->ethertype));
#endif
            pc.other++;
            return;
    }

    return;
}


/****************************************************************************
 *
 * Function: DecodeFDDIPkt(char *, struct pcap_pkthdr*, u_char*)
 *
 * Purpose: For future expansion
 *
 * Arguments: user => I don't know what this is for, I don't use it but it has
 *                    to be there
 *            pkthdr => ptr to the packet header
 *            pkt => pointer to the real live packet data
 *
 * Returns: void function
 *
 * Mainly taken from CyberPsycotic's Token Ring Code -worm5er
 ****************************************************************************/
void DecodeFDDIPkt(Packet *p, struct pcap_pkthdr *pkthdr, u_char *pkt)
{
    int pkt_len; /* length of the packet */
    int cap_len; /* capture length variable */
    int dataoff; /* data offset is variable here */

    bzero((char *)p, sizeof(Packet));

    p->pkth = pkthdr;
    p->pkt = pkt;

    pkt_len = pkthdr->len;
    cap_len = pkthdr->caplen;

    if (snaplen < pkt_len)
    {
        pkt_len = cap_len;
    }

#ifdef DEBUG
    printf("Packet!\n");
    printf("caplen: %d    pktlen: %d\n", cap_len, pkt_len);
#endif

    /* Bounds checking (might not be right yet -worm5er) */
    if (p->pkth->caplen < FDDI_MIN_HLEN)
    {
        if (pv.verbose_flag)
        {
            ErrorMessage( "Captured data length < FDDI header length! "
                          "(%d %d bytes)\n", p->pkth->caplen, FDDI_MIN_HLEN);
            return;
        }
    }

    /* let's put this in as the fddi header structure */
    p->fddihdr = (Fddi_hdr *) pkt;

    p->fddisaps = (Fddi_llc_saps *)(pkt + sizeof(Fddi_hdr));

    /* First we'll check and see if it's an IP/ARP Packet... */
    /* Then we check to see if it's a SNA packet */
    /* Lastly we'll declare it none of the above and just slap something generic
       on it to discard it with (I know that sucks, but heck we're only looking
       for IP/ARP type packets currently...  -worm5er */
    if ((p->fddisaps->dsap==FDDI_DSAP_IP) && (p->fddisaps->ssap==FDDI_SSAP_IP))
    {
        p->fddiiparp = (Fddi_llc_iparp *)(pkt + sizeof(Fddi_hdr) + 
                                          sizeof(Fddi_llc_saps));

        dataoff = sizeof(Fddi_hdr) + sizeof(Fddi_llc_saps) + 
                  sizeof(Fddi_llc_iparp);
    }
    else if ((p->fddisaps->dsap==FDDI_DSAP_SNA) && 
             (p->fddisaps->ssap==FDDI_SSAP_SNA))
    {
        p->fddisna = (Fddi_llc_sna *)(pkt + sizeof(Fddi_hdr) + 
                                      sizeof(Fddi_llc_saps));
        dataoff = sizeof(Fddi_hdr) + sizeof(Fddi_llc_saps) + 
                  sizeof(Fddi_llc_sna);
    }
    else
    {
        p->fddiother = (Fddi_llc_other *)(pkt + sizeof(Fddi_hdr) + 
                                          sizeof(Fddi_llc_other));

        dataoff = sizeof(Fddi_hdr) + sizeof(Fddi_llc_saps) + 
                  sizeof(Fddi_llc_other);
    }

    /* Now let's see if we actually care about the packet...
       If we don't, throw it out!!!*/
    if ((p->fddisaps->dsap!=FDDI_DSAP_IP) && (p->fddisaps->ssap!=FDDI_SSAP_IP))
    {
#ifdef DEBUG
        ErrorMessage("This FDDI Packet isn't an IP/ARP packet...\n");
#endif
        return;
    }

⌨️ 快捷键说明

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