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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#!/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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
#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); } |
Comments