📄 decode.c
字号:
/* $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 + -