Skip to content →

Testing Bouncer

Static testing is used to test the bouncer, that is, a separate set of test cases and sample outputs are provided. And the bouncer is given the test cases and its outputs are compared with sample outputs.

A verifier is used to accomplish the above function, and another bash script is written to automate the process.

The bash script is as follows:

#!/bin/sh

USAGE="Usage: $0 [-v] bouncer" 
CMD="./verifier "
TESTDIR="cases"

while getopts "v" optname
do
    case "$optname" in
        "v")
        CMD="./verifier -v "
        ;;
        *)
        echo $USAGE

exit 1
        ;;
    esac
done
shift $(($OPTIND-1))
BCER=$*

if [ -f "$BCER" ]
then
    find "$TESTDIR" -iname "*pcap" | while read i
do
    if [ -f "$i" ] && [ -f "$i"-ref ]
    then
        echo "======================================================================"
        echo "Verifying file: $i"
        $BCER -t -l 1.1.1.1 -s 3.3.3.3 <"$i" >"$i"-out
	BCRT=$?
	echo
"----------------------------------------------------------------------"
        if [ $BCRT != 0 ]
        then
            echo "$BCER returned with $?"
            echo "Exiting $0"
            exit 1
        fi
        $CMD -i "$i"-out -r "$i"-ref
	CMDRT=$?
	echo "----------------------------------------------------------------------"
        echo "Result for $i:"
	echo "$CMDRT packets has passed validation"
        echo
"======================================================================"
	echo "n"
    fi
done
else
    echo $USAGE
fi

exit 0

The verifier is as follows:

#include "verifier.h"
typedef unsigned short u16;
typedef unsigned long u32;

/* CRC
 * Adopted from http://www.netfor2.com/ipsum.htm

*/
u16 ip_sum_calc(u16 len_ip_header, u16 buff[]) {
    u16 word16;
    u32 sum = 0;
    u16 i;

    // make 16 bit words out of every two adjacent 8 bit words in the packet
    // and add them up
    for (i = 0; i < len_ip_header; i = i + 2) {
        word16 = ((buff[i] << 8)&0xFF00)+(buff[i + 1]&0xFF);
        sum = sum + (u32) word16;
    }

    // take only 16 bits out of the 32 bit sum and add up the carries
    while
(sum >> 16)
        sum = (sum & 0xFFFF)+(sum >> 16);

    // one's complement the result
    sum = ~sum;

    return ((u16) sum);
}

int usage() {
    fprintf(stderr, "Usage: verifier [-v] -i input_file -r reference_filen");
    exit(1);
}

int main(int argc, char **argv) {
    int verbose = 0;
    opterr = 0;
    char c;
    char *ifilename, *rfilename;
    struct stat st;
    while ((c = getopt(argc, argv,
"vi:r:")) != -1) {
        if (c == 'i') {
            ifilename = optarg;
            if (stat(ifilename, &st) != 0) {
                fprintf(stderr, "File does not exist!n");
                exit(1);
            }
        } else if (c == 'r') {
            rfilename = optarg;
            if (stat(rfilename, &st) != 0) {
                fprintf(stderr, "File does not exist!n");
                exit(1);
            }

} else if (c == 'v') {
            verbose = 1;
        } else {
            usage();
        }
    }

    pcap_t *ihandle = NULL, *rhandle = NULL;
    char errbufi[PCAP_ERRBUF_SIZE], errbufr[PCAP_ERRBUF_SIZE];
    ihandle = pcap_open_offline(ifilename, errbufi);
    rhandle = pcap_open_offline(rfilename, errbufr);
    struct pcap_pkthdr ihdr, rhdr;
    const u_char *ipkt, *rpkt;
    ipkt = malloc(MAX_PACKET_SIZE);
    rpkt =
malloc(MAX_PACKET_SIZE);
    if (ipkt == NULL || rpkt == NULL) {
        perror("malloc");
        exit(1);
    }
    int pc = -1; /* Packet counter */
    char flags[MAX_PACKETS_NO]; /* Broken or Not */
    memset(flags, PKT_OK, MAX_PACKETS_NO);
    while ((ipkt = pcap_next(ihandle, &ihdr)) && (rpkt = pcap_next(rhandle, &rhdr))) {
        pc++;
        /* Typecasting input packet*/
        const struct
sniff_ethernet *iethernet; /* The ethernet header */
        const struct sniff_ip *iip; /* The IP header */
        const struct sniff_icmp *iicmp; /* The ICMP header */
        const char *ipayload; /* Packet payload */
        u_int isize_ip;
        iethernet = (struct sniff_ethernet*) (ipkt);
        iip = (struct sniff_ip*) (ipkt + SIZE_ETHERNET);
        isize_ip = IP_HL(iip)*4;
        if (isize_ip < 20) {
            fprintf(stderr, "   * Invalid
IP header length: %u bytesn", isize_ip);
            continue;
        }
        iicmp = (struct sniff_icmp*) (ipkt + SIZE_ETHERNET + isize_ip);
        ipayload = (char *) (ipkt + SIZE_ETHERNET + isize_ip + SIZE_ICMP);
        /* Typecasting reference packet*/
        const struct sniff_ethernet *rethernet; /* The ethernet header */
        const struct sniff_ip *rip; /* The IP header */
        const struct sniff_icmp *ricmp; /* The ICMP header */

const char *rpayload; /* Packet payload */
        u_int rsize_ip;
        rethernet = (struct sniff_ethernet*) (rpkt);
        rip = (struct sniff_ip*) (rpkt + SIZE_ETHERNET);
        rsize_ip = IP_HL(rip)*4;
        if (rsize_ip < 20) {
            fprintf(stderr, "   * Invalid IP header length: %u bytesn", rsize_ip);
            continue;
        }
        ricmp = (struct sniff_icmp*) (rpkt + SIZE_ETHERNET + rsize_ip);
        rpayload = (char *) (rpkt
+ SIZE_ETHERNET + rsize_ip + SIZE_ICMP);

        /* Here comes the validation process */
        /* Check IP checksum */
        u16 ipbuf[isize_ip];
        u16 ipsum = ntohs(iip->ip_sum);
        int i;
        for (i = 0; i < isize_ip; i++) {
            if (i == 10 || i == 11)
                ipbuf[i] = 0x00;
            else
                ipbuf[i] = *((u_char *) (ipkt + SIZE_ETHERNET + i));
        }
        if (ipsum !=
ip_sum_calc(isize_ip, ipbuf)) {
            flags[pc] = ERR_IP_SUM;
            continue;
        }
        /* Check ICMP checksum */
        int plen = ihdr.len - SIZE_ETHERNET - isize_ip - 8;
        u16 icmpbuf[8 + plen];
        u16 icmpsum = ntohs(iicmp->icmp_sum);
        for (i = 0; i < 8; i++) {
            if (i == 2 || i == 3)
                icmpbuf[i] = 0x00;
            else
                icmpbuf[i] = *((u_char *) (ipkt +
SIZE_ETHERNET + isize_ip + i));
        }
        for (i = 0; i < plen; i++) {
            icmpbuf[i + 8] = *((u_char *) (ipayload + i));
        }
        if (icmpsum != ip_sum_calc(8 + plen, icmpbuf)) {
            flags[pc] = ERR_ICMP_SUM;
            continue;
        }
        /* Check IP TTL */
        if (iip->ip_ttl <= 0) {
            flags[pc] = ERR_IP_TTL;
            continue;
        }
        /* Check IP source
address */
        if (iip->ip_src.s_addr != rip->ip_src.s_addr) {
            flags[pc] = ERR_IP_SADDR;
            continue;
        }
        /* Check IP destinataion address */
        if (iip->ip_dst.s_addr != rip->ip_dst.s_addr) {
            flags[pc] = ERR_IP_DADDR;
            continue;
        }

        /* Check ICMP type */
        if (iicmp->icmp_type != ricmp->icmp_type) {
            flags[pc] = ERR_ICMP_TYPE;

continue;
        }
        /* Check ICMP ID */
        if (iicmp->icmp_id != ricmp->icmp_id) {
            flags[pc] = ERR_ICMP_ID;
            continue;
        }
        /* Check ICMP sequence number */
        if (iicmp->icmp_sequence != ricmp->icmp_sequence) {
            flags[pc] = ERR_ICMP_SEQ;
            continue;
        }
    }
    pc++;
    int bc = 0; /* Broken packet counter */
    int i;
    for (i = 1; i <= pc;
i++) {
        if (flags[i-1])
            bc++;
        if (verbose) {
            switch (flags[i-1]) {
                case PKT_OK:
                    fprintf(stdout, "Validation passed: %d/%dn", i, pc);
                    break;
                case ERR_IP_SUM:
                    fprintf(stdout, "IP checksum failed: %d/%dn", i, pc);
                    break;
                case ERR_IP_TTL:
                    fprintf(stdout, "IP TTL check
failed: %d/%dn", i, pc);
                    break;
                case ERR_IP_SADDR:
                    fprintf(stdout, "IP source address check failed: %d/%dn", i, pc);
                    break;
                case ERR_IP_DADDR:
                    fprintf(stdout, "IP destination address check failed: %d/%dn", i, pc);
                    break;
                case ERR_ICMP_SUM:
                    fprintf(stdout, "ICMP checksum
failed: %d/%dn", i, pc);
                    break;
                case ERR_ICMP_TYPE:
                    fprintf(stdout, "ICMP type check failed: %d/%dn", i, pc);
                    break;
                case ERR_ICMP_ID:
                    fprintf(stdout, "IP ID check failed: %d/%dn", i, pc);
                    break;
                case ERR_ICMP_SEQ:
                    fprintf(stdout, "IP sequence check failed: %d/%dn", i, pc);

break;
                default:
                    fprintf(stderr, "ERROR: Unknwon error type.n");
                    break;
            }
        }
    }
    if (bc == 0)
        fprintf(stdout, "%d packets passed validationn", pc);
    else
        fprintf(stdout, "%d out of %d packets failed validationn", bc, pc);
    /* Return number of packets passed validation */
    return (pc - bc);
}

Published in Bouncer

Comments

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    This site uses Akismet to reduce spam. Learn how your comment data is processed.