Commit a3ef2703 authored by 's avatar
Browse files

Added a little application for testing that anonymization when

using authentication is correctly applied (instructions in the file).

Applicable only on packet traces (NOT live traffic).



git-svn-id: file:///home/svn/mapi/trunk@1317 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent 7fbc0cc9
#include <stdio.h>
#include <strings.h>
#include <pcap.h>
#include "../anonflib/anon_snort_decode.h"
/*
* mfukar, Oct07
*
* A small application which performs sequential traversal of two
* packet traces which have been anonymized by different applications
* with the same policy (allegedly)
* and reports mismatches between fields.
*
* View this as a test that the packets from using VOd-enabled applications
* match those that would have been produced with the correspondent anonymization
* policy applied through other means (anonymization library of DiMAPI or tools
* like AnonTool, and so forth.
*
* Currently supporting limited number of IP/TCP/UDP/ICMP protocol fields.
* This is the intended behaviour.
*
* To compile, use : gcc trace_compare.c -lpcap
*
* Written using libpcap version 0.9.5. As it follows directly from O'Toole's
* Commentary on Murphy's Law, I cannot possibly guarantee this will work with
* previous versions of libpcap.
*
* Requires "anon_snort_decode.h", found in the default DiMAPI distribution,
* in the aforementioned path. If it's not there, put it there. Don't bug me
* with system configuration BS.
*
* Report bugs or extension requests to <mfukar AT ics DOT forth DOT gr>
*/
typedef struct _anonPacket
{
struct pcap_pkthdr *pkth; /* BPF data */
unsigned char *pkt; /* base pointer to the raw packet data */
Fddi_hdr *fddihdr; /* FDDI support headers */
Fddi_llc_saps *fddisaps;
Fddi_llc_sna *fddisna;
Fddi_llc_iparp *fddiiparp;
Fddi_llc_other *fddiother;
Trh_hdr *trh; /* Token Ring support headers */
Trh_llc *trhllc;
Trh_mr *trhmr;
SLLHdr *sllh; /* Linux cooked sockets header */
PflogHdr *pfh; /* OpenBSD pflog interface header */
EtherHdr *eh; /* standard TCP/IP/Ethernet/ARP headers */
VlanTagHdr *vh;
EthLlc *ehllc;
EthLlcOther *ehllcother;
WifiHdr *wifih; /* wireless LAN header */
EtherARP *ah;
EtherEapol *eplh; /* 802.1x EAPOL header */
EAPHdr *eaph;
unsigned char *eaptype;
EapolKey *eapolk;
IPHdr *iph, *orig_iph; /* and orig. headers for ICMP_*_UNREACH family */
unsigned int ip_options_len;
unsigned char *ip_options_data;
TCPHdr *tcph, *orig_tcph;
unsigned int tcp_options_len;
unsigned char *tcp_options_data;
UDPHdr *udph, *orig_udph;
ICMPHdr *icmph, *orig_icmph;
echoext *ext; /* ICMP echo extension struct */
unsigned char *data; /* packet payload pointer */
unsigned int dsize; /* packet payload size */
unsigned int alt_dsize; /* the dsize of a packet before munging
(used for log)*/
unsigned char frag_flag; /* flag to indicate a fragmented packet */
unsigned short int frag_offset; /* fragment offset number */
unsigned char mf; /* more fragments flag */
unsigned char df; /* don't fragment flag */
unsigned char rf; /* IP reserved bit */
unsigned short int sp; /* source port (TCP/UDP) */
unsigned short int dp; /* dest port (TCP/UDP) */
unsigned short int orig_sp; /* source port (TCP/UDP) of original datagram */
unsigned short int orig_dp; /* dest port (TCP/UDP) of original datagram */
unsigned int caplen;
unsigned char uri_count; /* number of URIs in this packet */
Options ip_options[40]; /* ip options decode structure */
unsigned int ip_option_count; /* number of options in this packet */
u_char ip_lastopt_bad; /* flag to indicate that option decoding was halted due to a bad option */
Options tcp_options[40]; /* tcp options decode struct */
unsigned int tcp_option_count;
u_char tcp_lastopt_bad; /* flag to indicate that option decoding was halted due to a bad option */
unsigned char csum_flags; /* checksum flags */
unsigned int packet_flags; /* special flags for the packet */
} myPacket;
void DecodeTCP (unsigned char *pkt, const unsigned int len, myPacket * p, int snaplen);
void DecodeIP (unsigned char *pkt, const unsigned int len, myPacket * p, int snaplen);
void DecodeUDP (unsigned char *pkt, const unsigned int len, myPacket * p, int snaplen);
void DecodeICMP (unsigned char *pkt, const unsigned int len, myPacket * p, int snaplen);
void DecodeARP(unsigned char * pkt, unsigned int len, myPacket * p,int snaplen);
void
DecodeIP (unsigned char *pkt, const unsigned int len, myPacket * p,
int snaplen)
{
unsigned int ip_len; /* length from the start of the ip hdr to the
* pkt end */
unsigned int hlen; /* ip header length */
p->iph = (IPHdr *) pkt;
if (len < IP_HEADER_LEN)
{
p->iph = NULL;
return;
}
if (IP_VER (p->iph) != 4)
{
p->iph = NULL;
return;
}
ip_len = ntohs (p->iph->ip_len);
hlen = IP_HLEN (p->iph) << 2;
if (hlen < IP_HEADER_LEN)
{
p->iph = NULL;
return;
}
if (ip_len != len)
{
if (ip_len > len)
{
ip_len = len;
}
else
{
}
}
if (ip_len < hlen)
{
p->iph = NULL;
return;
}
p->ip_options_len = hlen - IP_HEADER_LEN;
/* if (p->ip_options_len > 0)
{
p->ip_options_data = pkt + IP_HEADER_LEN;
DecodeIPOptions ((pkt + IP_HEADER_LEN), p->ip_options_len, p,
snaplen);
}
else
*/ {
p->ip_option_count = 0;
}
ip_len -= hlen;
p->frag_offset = ntohs (p->iph->ip_off);
p->rf = (unsigned char) ((p->frag_offset & 0x8000) >> 15);
p->df = (unsigned char) ((p->frag_offset & 0x4000) >> 14);
p->mf = (unsigned char) ((p->frag_offset & 0x2000) >> 13);
p->frag_offset &= 0x1FFF;
if (p->frag_offset || p->mf)
{
p->frag_flag = 1;
}
if (!(p->frag_flag))
{
p->frag_flag = 0;
switch (p->iph->ip_proto)
{
case IPPROTO_TCP:
DecodeTCP (pkt + hlen, ip_len, p, snaplen);
return;
case IPPROTO_UDP:
DecodeUDP (pkt + hlen, ip_len, p, snaplen);
return;
case IPPROTO_ICMP:
DecodeICMP (pkt + hlen, ip_len, p, snaplen);
return;
default:
p->data = pkt + hlen;
p->dsize = (unsigned int) ip_len;
return;
}
}
else
{
p->data = pkt + hlen;
p->dsize = (unsigned int) ip_len;
}
}
void
DecodeTCP (unsigned char *pkt, const unsigned int len, myPacket * p,
int snaplen)
{
struct pseudoheader /* pseudo header for TCP checksum calculations */
{
unsigned int sip, dip; /* IP addr */
unsigned char zero; /* checksum placeholder */
unsigned char protocol; /* protocol number */
unsigned int tcplen; /* tcp packet length */
};
unsigned int hlen; /* TCP header length */
if (len < 20)
{
p->tcph = NULL;
return;
}
p->tcph = (TCPHdr *) pkt;
hlen = TCP_OFFSET (p->tcph) << 2;
if (hlen < 20)
{
p->tcph = NULL;
return;
}
p->tcp_options_len = hlen - 20;
/* if (p->tcp_options_len > 0)
{
p->tcp_options_data = pkt + 20;
DecodeTCPOptions ((unsigned char *) (pkt + 20),
p->tcp_options_len, p, snaplen);
}
else
*/ {
p->tcp_option_count = 0;
}
p->sp = ntohs (p->tcph->th_sport);
p->dp = ntohs (p->tcph->th_dport);
p->data = (unsigned char *) (pkt + hlen);
if (hlen < len)
{
p->dsize = (unsigned int) (len - hlen);
}
else
{
p->dsize = 0;
}
}
void
DecodeUDP (unsigned char *pkt, const unsigned int len, myPacket * p,
int snaplen)
{
struct pseudoheader
{
unsigned int sip, dip;
unsigned char zero;
unsigned char protocol;
unsigned int udplen;
};
if (len < sizeof (UDPHdr))
{
p->udph = NULL;
return;
}
p->udph = (UDPHdr *) pkt;
p->sp = ntohs (p->udph->uh_sport);
p->dp = ntohs (p->udph->uh_dport);
p->data = (unsigned char *) (pkt + UDP_HEADER_LEN);
if ((len - UDP_HEADER_LEN) > 0)
{
p->dsize = (unsigned int) (len - UDP_HEADER_LEN);
}
else
{
p->dsize = 0;
}
}
void
DecodeICMP (unsigned char *pkt, const unsigned int len, myPacket * p,
int snaplen)
{
unsigned int orig_p_caplen;
if (len < ICMP_HEADER_LEN)
{
p->icmph = NULL;
return;
}
p->icmph = (ICMPHdr *) pkt;
switch (p->icmph->type)
{
case ICMP_ECHOREPLY:
case ICMP_DEST_UNREACH:
case ICMP_SOURCE_QUENCH:
case ICMP_REDIRECT:
case ICMP_ECHO:
case ICMP_ROUTER_ADVERTISE:
case ICMP_ROUTER_SOLICIT:
case ICMP_TIME_EXCEEDED:
case ICMP_PARAMETERPROB:
case ICMP_INFO_REQUEST:
case ICMP_INFO_REPLY:
if (len < 8)
{
p->icmph = NULL;
return;
}
break;
case ICMP_TIMESTAMP:
case ICMP_TIMESTAMPREPLY:
if (len < 20)
{
p->icmph = NULL;
return;
}
break;
case ICMP_ADDRESS:
case ICMP_ADDRESSREPLY:
if (len < 12)
{
p->icmph = NULL;
return;
}
break;
}
p->dsize = (unsigned int) (len - ICMP_HEADER_LEN);
p->data = pkt + ICMP_HEADER_LEN;
switch (p->icmph->type)
{
case ICMP_ECHOREPLY:
p->dsize -= sizeof (struct idseq);
p->data += sizeof (struct idseq);
break;
case ICMP_ECHO:
p->dsize -= sizeof (struct idseq); /* add the size of the
* echo ext to the data
* * ptr and subtract it
* * from the data size */
p->data += sizeof (struct idseq);
break;
case ICMP_DEST_UNREACH:
{
if (len < 16)
{
if (len < 8)
break;
}
orig_p_caplen = len - 8;
}
break;
case ICMP_REDIRECT:
{
if (p->dsize < 28)
{
if (p->dsize < 8)
break;
}
orig_p_caplen = p->dsize - 8;
}
break;
}
return;
}
void DecodeARP(unsigned char * pkt, unsigned int len, myPacket * p,int snaplen)
{
p->ah = (EtherARP *) pkt;
if(len < sizeof(EtherARP))
return;
return;
}
void
DecodeEthPkt (myPacket * p, struct pcap_pkthdr *pkthdr, unsigned char *pkt,
int snaplen)
{
unsigned int pkt_len; /* suprisingly, the length of the packet */
unsigned int cap_len; /* caplen value */
bzero ((char *) p, sizeof (myPacket));
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 ((unsigned int) snaplen < pkt_len)
pkt_len = cap_len;
/* do a little validation */
if (p->pkth->caplen < ETHERNET_HEADER_LEN)
{
return;
}
/* lay the ethernet structure over the packet data */
p->eh = (EtherHdr *) pkt;
/* grab out the network type */
switch (ntohs (p->eh->ether_type))
{
/* case ETHERNET_TYPE_PPPoE_DISC:
case ETHERNET_TYPE_PPPoE_SESS:
DecodePPPoEPkt (p, pkthdr, pkt, snaplen);
return;
*/
case ETHERNET_TYPE_IP:
DecodeIP (p->pkt + ETHERNET_HEADER_LEN,
cap_len - ETHERNET_HEADER_LEN, p, snaplen);
return;
case ETHERNET_TYPE_ARP:
case ETHERNET_TYPE_REVARP:
DecodeARP (p->pkt + ETHERNET_HEADER_LEN,
cap_len - ETHERNET_HEADER_LEN, p, snaplen);
return;
/* case ETHERNET_TYPE_IPV6:
DecodeIPV6 (p->pkt + ETHERNET_HEADER_LEN,
(cap_len - ETHERNET_HEADER_LEN), snaplen);
return;
case ETHERNET_TYPE_IPX:
DecodeIPX (p->pkt + ETHERNET_HEADER_LEN,
(cap_len - ETHERNET_HEADER_LEN), snaplen);
return;
case ETHERNET_TYPE_8021Q:
DecodeVlan (p->pkt + ETHERNET_HEADER_LEN,
cap_len - ETHERNET_HEADER_LEN, p, snaplen);
return;
*/
default:
return;
}
return;
}
int main(int argc, char **argv)
{
pcap_t *trace1, *trace2;
char errbuf[PCAP_ERRBUF_SIZE];
u_char *packet1, *packet2;
struct pcap_pkthdr ph1, ph2;
myPacket original_p, anon_p;
trace1 = pcap_open_offline("./bananatrace.pcap", errbuf);
trace2 = pcap_open_offline("./bananatrace.anon.pcap", errbuf);
if(!(trace1 && trace2))
return;
while((packet1 = (u_char *)pcap_next(trace1, &ph1)) != NULL)
{
if((packet2 = (u_char *)pcap_next(trace2, &ph2)) != NULL)
{
DecodeEthPkt(&original_p, &ph1, packet1, 1500);
DecodeEthPkt(&anon_p, &ph2, packet2, 1500);
if(memcmp(&original_p.iph->ip_src, &anon_p.iph->ip_src, sizeof(struct in_addr)) != 0
|| memcmp(&original_p.iph->ip_dst, &anon_p.iph->ip_dst, sizeof(struct in_addr)) != 0)
{
printf("IP address mismatch.\n");
}
else if(memcmp(&original_p.iph->ip_id, &anon_p.iph->ip_id, sizeof(u_int16_t)) != 0)
{
printf("IP ID mismatch.\n");
}
else if(memcmp(&original_p.iph->ip_proto, &anon_p.iph->ip_proto, sizeof(u_int8_t)) != 0)
{
printf("IP protocol mismatch.\n");
return(-1);
}
switch(original_p.iph->ip_proto)
{
case 6: // TCP
if(memcmp(&original_p.tcph->th_sport, &anon_p.tcph->th_sport, sizeof(u_int16_t)) != 0
|| memcmp(&original_p.tcph->th_dport, &anon_p.tcph->th_dport, sizeof(u_int16_t)) != 0)
{
printf("TCP Port mismatch.\n");
}
else if(&original_p.tcph->th_sum != &anon_p.tcph->th_sum)
{
printf("TCP checksum mismatch.\n");
}
break;
case 17: // UDP
if(memcmp(&original_p.udph->uh_sport, &anon_p.udph->uh_sport, sizeof(u_int16_t)) != 0
|| memcmp(&original_p.udph->uh_dport, &anon_p.udph->uh_dport, sizeof(u_int16_t)) != 0)
{
printf("UDP Port mismatch.\n");
}
else if(original_p.udph->uh_chk != anon_p.udph->uh_chk)
{
printf("UDP checksum mismatch.\n");
}
break;
case 1: // ICMP
if(original_p.icmph->type != anon_p.icmph->type)
{
printf("ICMP type mismatch.\n");
}
else if(original_p.icmph->code != anon_p.icmph->type)
{
printf("ICMP code mismatch.\n");
return(-2);
}
else if(original_p.icmph->csum != anon_p.icmph->csum)
{
printf("ICMP checksum mismatch.\n");
}
break;
default:
return(-3);
}
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment