diff -c tbit-1.0/inet.c tbit-1.0-newrelease/inet.c *** tbit-1.0/inet.c Tue Mar 1 15:23:49 2011 --- tbit-1.0-newrelease/inet.c Tue Mar 1 15:23:25 2011 *************** *** 288,293 **** --- 288,297 ---- char *ip_opt; int ip_optlen; int i; + + /* NE: print TCP SACK options */ + int len, numsb, k; + uint32 sb[8]; printf("%s.%u > ", InetAddress(ip->ip_src), ntohs(tcp->tcp_sport)); printf("%s.%u ", InetAddress(ip->ip_dst), ntohs(tcp->tcp_dport)); *************** *** 399,404 **** --- 403,430 ---- i = i + TCPOLEN_SACK_PERMITTED ; break ; + /* NE: Print TCP SACK option(s) */ + case TCPOPT_SACK: + printf (" opt%d: %s ", i + 1, "TCPOPT_SACK"); + + len = ((uint8*)opt[i+1]); + printf ("len: %d ", len); + + if (len > 2) { + numsb = (len - 2)/8; + } + + for (k = 0 ; k < 2 * numsb; k++) { + memcpy(&sb[k], ((char *)opt) + i + 2 + k * sizeof(uint32), sizeof(uint32)); + sb[k] = ntohl(sb[k]); + + if (k % 2 == 1) + printf ("[%u-%u] ", sb[k-1], sb[k]); + } + + i = i + len; + break; + case TCPOPT_TIMESTAMP: printf (" opt%d: %s ", i + 1, "TCPOPT_TIMESTAMP"); i = i + TCPOLEN_TIMESTAMP ; Common subdirectories: tbit-1.0/libpcap-0.4 and tbit-1.0-newrelease/libpcap-0.4 diff -c tbit-1.0/sack_rcvr.c tbit-1.0-newrelease/sack_rcvr.c *** tbit-1.0/sack_rcvr.c Tue Mar 1 15:23:49 2011 --- tbit-1.0-newrelease/sack_rcvr.c Tue Mar 1 15:23:25 2011 *************** *** 40,45 **** --- 40,52 ---- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* Contact information for test cases related to Misbehaviors in TCP SACK Generation + * NE: Nasif Ekiz (Protocol Engineering Lab @ University of Delaware) + * nekiz@udel.edu + * Abu: Abuthahir Habeeb Rahman (Protocol Engineering Lab @ University of Delaware) + * abu@udel.edu + */ + #include "base.h" #include "inet.h" #include "session.h" *************** *** 52,58 **** extern struct TcpSession session; extern struct History history[]; ! void SackRcvrTest (uint32 sourceAddress, uint16 sourcePort, uint32 targetAddress, uint16 targetPort, int mss) { int optlen ; char *opt ; --- 59,65 ---- extern struct TcpSession session; extern struct History history[]; ! void SackRcvrTest (uint32 sourceAddress, uint16 sourcePort, uint32 targetAddress, uint16 targetPort, int mss, int testopt) { int optlen ; char *opt ; *************** *** 76,82 **** opt[6] = (uint8)TCPOPT_SACK_PERMITTED ; opt[7] = (uint8)TCPOLEN_SACK_PERMITTED ; ! if (EstablishSession(sourceAddress, sourcePort, targetAddress, targetPort, --- 83,89 ---- opt[6] = (uint8)TCPOPT_SACK_PERMITTED ; opt[7] = (uint8)TCPOLEN_SACK_PERMITTED ; ! if (EstablishSession2(sourceAddress, sourcePort, targetAddress, targetPort, *************** *** 88,94 **** 5, 5, 0, ! 0) == 0) { printf("ERROR: Couldn't establish session\nRETURN CODE: %d", NO_SESSION_ESTABLISH); Quit(NO_SESSION_ESTABLISH); } --- 95,102 ---- 5, 5, 0, ! 0, ! testopt) == 0) { printf("ERROR: Couldn't establish session\nRETURN CODE: %d", NO_SESSION_ESTABLISH); Quit(NO_SESSION_ESTABLISH); } *************** *** 98,105 **** Quit(NO_SACK); } ! SendBrokenRequest(); ! checkSackRcvr(); Quit(SUCCESS); } --- 106,115 ---- Quit(NO_SACK); } ! SendBrokenRequest(testopt); ! ! if (testopt == SACKRCVR) ! checkSackRcvr(); Quit(SUCCESS); } *************** *** 149,158 **** } ! void SendBrokenRequest() { ! struct IPPacket *p, *datapkt; struct PacketInfo pi; char *read_packet; int i ; --- 159,171 ---- } ! /* NE: This function is used to create all SackRcvr* test cases including ! * test cases for Misbehaviors in TCP SACK Generation. ! */ ! void SendBrokenRequest(int testopt) { ! struct IPPacket *p, *ackpkt, *datapkt; struct PacketInfo pi; char *read_packet; int i ; *************** *** 160,273 **** double startTime; char *dataptr ; char data[MAXREQUESTLEN]; ! int datalen; p = NULL; datapkt = NULL; ! /* ! * Send data packets 1 and 3. ! * The ack for 1 should have no sack blocks. ! * The ack for 3 should have sack blocks indicating a hole at 2. ! * Each packet will be 1 byte long. ! * Wait for 2 seconds after each packet is sent to receive an ack, ! * otherwise, quit. ! */ ! datalen = PrepareRequest(data, session.filename); ! for (i = 0; i < 14 ; i++) { ! datapkt = AllocateIPPacket(0, 0, 1, "SackRcvr (DataPkt)"); ! dataptr = (char *)datapkt->tcp + sizeof(struct TcpHeader); ! memcpy((void *)dataptr, (void *)data + i, 1); ! if (session.verbose) { ! printf ("s %f %d\n", GetTime() - session.epochTime, session.snd_nxt); } ! SendSessionPacket(datapkt, ! sizeof(struct IpHeader) + sizeof(struct TcpHeader) + 1, ! TCPFLAGS_PSH | TCPFLAGS_ACK, ! 0, ! 0, ! 0); ! startTime = GetTime(); ! while (1) { /* Check if we have received any packets */ if ((read_packet =(char *)CaptureGetPacket(&pi)) != NULL) { ! p = (struct IPPacket *)FindHeaderBoundaries(read_packet); ! /* ! * packet that we sent? ! */ ! if (INSESSION(p,session.src,session.sport,session.dst,session.dport) && ! (p->tcp->tcp_flags == (TCPFLAGS_PSH | TCPFLAGS_ACK)) && ! (ntohl(p->tcp->tcp_seq) > lastSeqSent) && ! (ntohl(p->tcp->tcp_ack) <= session.rcv_nxt)) { ! ! lastSeqSent = ntohl(p->tcp->tcp_seq); ! if (session.debug) { ! printf("saw the packet we sent: xmit %d\n", i); ! PrintTcpPacket(p); ! } ! StorePacket(p); ! session.totSeenSent++ ; ! free(p); ! continue ; ! } ! /* ! * from them? ! */ ! if (INSESSION(p,session.dst,session.dport,session.src,session.sport) && ! (p->tcp->tcp_flags & TCPFLAGS_ACK) && ! (ntohl(p->tcp->tcp_ack) >= session.snd_una)) { ! if (ntohl(p->tcp->tcp_ack) > session.snd_una) { ! session.snd_una = ntohl(p->tcp->tcp_ack); ! } ! if (session.debug) { ! PrintTcpPacket(p); ! } ! StorePacket(p); ! session.totRcvd++; ! free(p); ! break; ! } ! } ! if (GetTime() - startTime >= REXMITDELAY) { ! printf ("ERROR: no response\nRETURN CODE: %d", NO_CONNECTION); ! Quit(NO_CONNECTION); ! } } ! free(datapkt); ! /* Now, bump up the snd_nxt to create a false loss and skip an ! * iteration. Is skipping iteration necessary? ! */ ! session.snd_nxt += 2; ! i += 1; ! } } void checkSackRcvr() { /* --- 173,674 ---- double startTime; char *dataptr ; char data[MAXREQUESTLEN]; ! ! char emptyData[1460]; /* NE: null data to create SACK gaps*/ ! ! int totalPacketsSent = 0; ! int tcpPayloadSize = 1460; /* NE: data size to send */ ! int sendData = 1; /* turns on/off sending data */ ! ! int maximumNumberOfSackBlocks = 0; /* number of SACK blocks (gaps) to be created */ ! int currentNumberOfSackBlocks = 0; ! int numberOfSackBlocks55 = 1; ! ! uint32 src; ! uint32 dst; ! uint16 sport; ! uint16 dport; ! uint32 seq; ! uint32 ack; ! uint8 flags; ! uint16 win; ! uint16 urp; ! uint16 datalen; ! uint16 ip_optlen; ! uint16 optlen; p = NULL; datapkt = NULL; + + memset(emptyData, 0, 1460); ! switch (testopt) { ! ! case SACKRCVR: ! datalen = PrepareRequest(data, session.filename); ! totalPacketsSent = 14; ! break; ! case SACKRCVR1: /* NE: testA for Misbehaviors in SACK Generation */ ! datalen = PrepareRequest(data, session.filename); ! totalPacketsSent = 10; ! break; ! case SACKRCVR2: /* NE: testB for Misbehaviors in SACK Generation */ ! datalen = PrepareRequest(data, session.filename); ! totalPacketsSent = 10; ! break; ! case SACKRCVR3: /* NE: testC for Misbehaviors in SACK Generation */ ! datalen = PrepareRequest(data, session.filename); ! totalPacketsSent = 8; ! break; ! case SACKRCVR4: /* NE: testD for Misbehaviors in SACK Generation */ ! datalen = PrepareRequest3(data, session.filename); /* HTTP 1.0 request */ ! tcpPayloadSize = datalen; ! totalPacketsSent = 30; ! maximumNumberOfSackBlocks = 1; ! break; ! case SACKRCVR5: /* NE: testE having one SACK block for Misbehaviors in SACK Generation */ ! datalen = PrepareRequest2(data, session.filename); /* HTTP 1.1 request */ ! tcpPayloadSize = datalen; ! totalPacketsSent = 50; ! maximumNumberOfSackBlocks = 1; ! break; ! case SACKRCVR52: /* NE: testF having two SACK blocks for Misbehaviors in SACK Generation */ ! datalen = PrepareRequest2(data, session.filename); /* HTTP 1.1 request */ ! tcpPayloadSize = datalen; ! totalPacketsSent = 50; ! maximumNumberOfSackBlocks = 2; ! break; ! case SACKRCVR53: /* NE: testF having three SACK blocks for Misbehaviors in SACK Generation */ ! datalen = PrepareRequest2(data, session.filename); /* HTTP 1.1 request */ ! tcpPayloadSize = datalen; ! totalPacketsSent = 50; ! maximumNumberOfSackBlocks = 3; ! break; ! case SACKRCVR54: /* NE: testF having four SACK blocks for Misbehaviors in SACK Generation */ ! datalen = PrepareRequest2(data, session.filename); /* HTTP 1.1 request */ ! tcpPayloadSize = datalen; ! totalPacketsSent = 50; ! maximumNumberOfSackBlocks = 4; ! break; ! case SACKRCVR55: /* NE: testF (paper version) for Misbehaviors in SACK Generation */ ! datalen = PrepareRequest2(data, session.filename); /* HTTP 1.1 request */ ! tcpPayloadSize = datalen; ! totalPacketsSent = 50; ! maximumNumberOfSackBlocks = 0; ! break; ! case SACKRCVR7: /* NE: first part of testG for Misbehaviors in SACK Generation */ ! datalen = PrepareRequest(data, session.filename); ! totalPacketsSent = 4; ! break; ! case SACKRCVR8: /* NE: second part of testG for Misbehaviors in SACK Generation */ ! datalen = PrepareRequest(data, session.filename); ! totalPacketsSent = 6; ! break; ! default: ! printf("Unknown SackRcvr Test!"); ! return; ! } ! for (i = 0; i < totalPacketsSent ; i++) { ! ! if ( testopt == SACKRCVR ) ! datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr (DataPkt)"); ! ! if ( testopt == SACKRCVR1 ) ! datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr1 (DataPkt)"); ! ! if ( testopt == SACKRCVR2 ) ! datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr2 (DataPkt)"); ! if ( testopt == SACKRCVR3 ) ! datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr3 (DataPkt)"); ! ! if ( testopt == SACKRCVR4 ) { ! datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr4 (DataPkt)"); ! } ! if ( testopt == SACKRCVR5 ) { ! datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr5 (DataPkt)"); ! } ! if ( testopt == SACKRCVR52 ) { ! datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr52 (DataPkt)"); ! } ! if ( testopt == SACKRCVR53 ) { ! datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr53 (DataPkt)"); } ! if ( testopt == SACKRCVR54 ) { ! datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr54 (DataPkt)"); ! } ! if ( testopt == SACKRCVR55 ) { ! datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr55 (DataPkt)"); ! } ! if ( testopt == SACKRCVR7 ) { ! datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr7 (DataPkt)"); ! } + if ( testopt == SACKRCVR8 ) { + datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr8 (DataPkt)"); + } + + if ( sendData ) { + + dataptr = (char *)datapkt->tcp + sizeof(struct TcpHeader); + + + if ( testopt == SACKRCVR1 || testopt == SACKRCVR2 || testopt == SACKRCVR3 + || testopt == SACKRCVR7 || testopt == SACKRCVR8) { + memcpy((void *)dataptr, (void *)emptyData, tcpPayloadSize); + } + else + memcpy((void *)dataptr, (void *)data + (session.snd_nxt - session.iss - 1), tcpPayloadSize); + + if (session.verbose) { + printf ("s %f %d\n", GetTime() - session.epochTime, session.snd_nxt); + } + + SendSessionPacket(datapkt, + sizeof(struct IpHeader) + sizeof(struct TcpHeader) + tcpPayloadSize, + TCPFLAGS_PSH | TCPFLAGS_ACK, + 0, + 0, + 0); + + startTime = GetTime(); + + if ( testopt == SACKRCVR5 || testopt == SACKRCVR52 || testopt == SACKRCVR53 || + testopt == SACKRCVR54 || testopt == SACKRCVR55 || testopt == SACKRCVR4 ) + sendData = 0; + } + + while (1) { + /* Check if we have received any packets */ if ((read_packet =(char *)CaptureGetPacket(&pi)) != NULL) { + + p = (struct IPPacket *)FindHeaderBoundaries(read_packet); + + /* + * packet that we sent? + */ + if (INSESSION(p,session.src,session.sport,session.dst,session.dport) && + (p->tcp->tcp_flags == (TCPFLAGS_PSH | TCPFLAGS_ACK)) && + (ntohl(p->tcp->tcp_seq) > lastSeqSent) && + (ntohl(p->tcp->tcp_ack) <= session.rcv_nxt)) { + + lastSeqSent = ntohl(p->tcp->tcp_seq); + if (session.debug) { + printf("saw the packet we sent: xmit %d\n", i); + PrintTcpPacket(p); + } + + StorePacket(p); + session.totSeenSent++ ; + free(p); + continue ; + + } + + /* + * from them? + */ + if (INSESSION(p,session.dst,session.dport,session.src,session.sport) && + (p->tcp->tcp_flags & TCPFLAGS_ACK) && + (ntohl(p->tcp->tcp_ack) >= session.snd_una)) { + + if (ntohl(p->tcp->tcp_ack) > session.snd_una) { + session.snd_una = ntohl(p->tcp->tcp_ack); + } + + if (session.debug) { + PrintTcpPacket(p); + } + + StorePacket(p); + session.totRcvd++; + + if (testopt == SACKRCVR5 || testopt == SACKRCVR52 || testopt == SACKRCVR53 || + testopt == SACKRCVR54 || testopt == SACKRCVR55 ) { + + ReadIPPacket(p, &src, &dst, + &sport, &dport, + &seq, &ack, &flags, &win, + &urp, &datalen, + &ip_optlen, &optlen); + + if ( (seq + datalen - 1) > session.maxseqseen) { + + /* NE: set the cum ACK value */ + session.maxseqseen = seq + datalen - 1; + + // NE: SackRcvr5* test cases + while ( currentNumberOfSackBlocks < maximumNumberOfSackBlocks ) { + + if ( currentNumberOfSackBlocks == 0 ) + session.snd_nxt += (50 + 1460); + else + session.snd_nxt += (2*1460); + + currentNumberOfSackBlocks++; + tcpPayloadSize = 1460; + + datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr5* (DataPkt)"); + memcpy((void *)dataptr, (void *)emptyData, tcpPayloadSize); + + if (session.verbose) { + printf ("s %f %d\n", GetTime() - session.epochTime, session.snd_nxt); + } + + /* NE: send data to create another SACK (gap) */ + SendSessionPacket(datapkt, + sizeof(struct IpHeader) + sizeof(struct TcpHeader) + tcpPayloadSize, + TCPFLAGS_PSH | TCPFLAGS_ACK, + 0, + 0, + 0); + + startTime = GetTime(); + + i += 1; + } + + /* NE: testF */ + if ( numberOfSackBlocks55 <= 4 && testopt == SACKRCVR55 ) { + + numberOfSackBlocks55++; + + tcpPayloadSize = 1460; + + session.snd_nxt += (2*1460); + + /* Allocate IP ACK Packet */ + ackpkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr55 (data + ACK)"); + memcpy((void *)dataptr, (void *)emptyData, tcpPayloadSize); + + session.rcv_nxt = seq + datalen; + + /* NE: send data + ACK to create another SACK (gap) */ + SendSessionPacket(ackpkt, + sizeof(struct IpHeader) + sizeof(struct TcpHeader) + tcpPayloadSize, + TCPFLAGS_PSH | TCPFLAGS_ACK, + 0 /* ip opt len */, + 0 /* tcp opt len */, + 0 /*tos */); + + i += 1; + } + else { + + /* Allocate IP ACK Packet */ + ackpkt = AllocateIPPacket(0, 0, 0, "SackRcvr5"); + + session.rcv_nxt = seq + datalen; + + /* NE: send an ACK for the received data */ + SendSessionPacket(ackpkt, + sizeof(struct IpHeader) + sizeof(struct TcpHeader), + TCPFLAGS_ACK, + 0 /* ip opt len */, + 0 /* tcp opt len */, + 0 /*tos */); + + i += 1; + } + + /* NE: return when index.pdf (11K) is received for tests D, E, F */ + if ( (session.maxseqseen - session.irs) >= 11800 ) { + return; + } + } + } + + /* Abu: testD */ + if (testopt == SACKRCVR4) { + + ReadIPPacket(p, &src, &dst, + &sport, &dport, + &seq, &ack, &flags, &win, + &urp, &datalen, + &ip_optlen, &optlen); + + if (seq + datalen - 1> session.maxseqseen) { + + + while ( currentNumberOfSackBlocks < maximumNumberOfSackBlocks ) { + + if ( currentNumberOfSackBlocks == 0 ) + session.snd_nxt += (50 + 1460); + else + session.snd_nxt += (2*1460); + + currentNumberOfSackBlocks++; + tcpPayloadSize = 1460; + + datapkt = AllocateIPPacket(0, 0, tcpPayloadSize, "SackRcvr4 (DataPkt)"); + memcpy((void *)dataptr, (void *)emptyData, tcpPayloadSize); + + if (session.verbose) { + printf ("s %f %d\n", GetTime() - session.epochTime, session.snd_nxt); + } + + SendSessionPacket(datapkt, + sizeof(struct IpHeader) + sizeof(struct TcpHeader) + tcpPayloadSize, + TCPFLAGS_PSH | TCPFLAGS_ACK, + 0, + 0, + 0); + + startTime = GetTime(); + + i += 1; + } + + /* "regular" packet */ + session.maxseqseen = seq + datalen - 1; + + /* Allocate IP ACK Packet */ + ackpkt = AllocateIPPacket(0, 0, 0, "SackRcvr4"); + + session.rcv_nxt = seq + datalen; + + SendSessionPacket(ackpkt, + sizeof(struct IpHeader) + sizeof(struct TcpHeader), + TCPFLAGS_ACK, + 0 /* ip opt len */, + 0 /* tcp opt len */, + 0 /*tos */); + } + } ! free(p); ! break; ! } ! } ! if (GetTime() - startTime >= REXMITDELAY) { ! printf ("ERROR: no response\nRETURN CODE: %d", NO_CONNECTION); ! Quit(NO_CONNECTION); ! } ! } ! free(datapkt); ! ! // SackRcvr test ! if ( testopt == SACKRCVR ) { ! /* Now, bump up the snd_nxt to create a false loss and skip an ! * iteration. Is skipping iteration necessary? ! */ ! session.snd_nxt += 2; ! i += 1; ! ! } ! // NE: SackRcvr1 (testA) ! if ( testopt == SACKRCVR1 ) { ! session.snd_nxt += (2*1460); //MOD ABU ! i += 1; ! ! } ! // NE: SackRcvr2 (testB) ! if ( testopt == SACKRCVR2 ) { ! ! switch(session.snd_nxt - session.iss) { + case 1: + session.snd_nxt += (3*1460); + i += 1; + break; + + case 4380 + 1: + session.snd_nxt += (2*1460); + i += 1; + break; + + case 7300 + 1: + session.snd_nxt -= (3*1460); + i += 1; + break; + + case 2920 + 1: + session.snd_nxt -= (1*1460); + i += 1; + break; + + default: + session.snd_nxt += (1*1460); + i += 1; + } } ! // NE: SackRcvr3 (testC) ! if ( testopt == SACKRCVR3 ) { ! switch(session.snd_nxt - session.iss) { ! ! case 1: ! session.snd_nxt += (2*1460); ! i += 1; ! break; ! ! case 2920 + 1: ! session.snd_nxt += (2*1460); ! i += 1; ! break; ! ! case 5840 + 1: ! session.snd_nxt -= (1*1460); ! i += 1; ! break; ! ! default: ! session.snd_nxt += (1*1460); ! i += 1; ! } ! } ! ! // Abu: SackRcvr7 (first part of testG) ! if ( testopt == SACKRCVR7 ) { + session.snd_nxt += (2*1460); + i += 1; + + } ! // Abu: SackRcvr8 (second part of testG) ! if ( testopt == SACKRCVR8 ) { + switch(session.snd_nxt - session.iss) { + + case 1: + session.snd_nxt += (3*1460) ; + i += 1; + break; + + case 4380 + 1: + session.snd_nxt -= (2*1460); + i += 1; + break; + + default: + session.snd_nxt += (1*1460); + i += 1; + } + } + } } + void checkSackRcvr() { /* diff -c tbit-1.0/sack_rcvr.h tbit-1.0-newrelease/sack_rcvr.h *** tbit-1.0/sack_rcvr.h Tue Mar 1 15:23:49 2011 --- tbit-1.0-newrelease/sack_rcvr.h Tue Mar 1 15:23:25 2011 *************** *** 42,49 **** */ #define MAXSB 100 ! void SackRcvrTest (uint32 sourceIpAddress, uint16 sourcePort, uint32 targetIpAddress, uint16 targetPort, int mss); int isSack (); ! void SendBrokenRequest(); void checkSackRcvr(); void GetSB (void *opt, int optlen, int ptr, uint32 *sb, int *numsb); --- 42,65 ---- */ #define MAXSB 100 ! /* NE: Constant values for each Sack test. */ ! #define SACKRCVR 0 ! #define SACKRCVR1 1 ! #define SACKRCVR2 2 ! #define SACKRCVR3 3 ! #define SACKRCVR4 4 ! #define SACKRCVR5 5 ! #define SACKRCVR52 52 ! #define SACKRCVR53 53 ! #define SACKRCVR54 54 ! #define SACKRCVR55 55 ! #define SACKRCVR7 7 ! #define SACKRCVR8 8 ! ! /* NE: changed (added a testopt parameter) to handle multiple test cases. */ ! void SackRcvrTest (uint32 sourceIpAddress, uint16 sourcePort, uint32 targetIpAddress, uint16 targetPort, int mss, int testopt); int isSack (); ! void SendBrokenRequest(int testopt); ! void SendBrokenRequest2(int testopt); void checkSackRcvr(); void GetSB (void *opt, int optlen, int ptr, uint32 *sb, int *numsb); diff -c tbit-1.0/session.c tbit-1.0-newrelease/session.c *** tbit-1.0/session.c Tue Mar 1 15:23:49 2011 --- tbit-1.0-newrelease/session.c Tue Mar 1 15:23:25 2011 *************** *** 47,52 **** --- 47,53 ---- #include "support.h" #include "tbit.h" #include + #include "sack_rcvr.h" struct TcpSession session; *************** *** 85,91 **** session.sport = sourcePort; session.dst = targetAddress; session.dport = targetPort; ! session.rcv_wnd = maxwin * mss; session.snd_nxt = (uint32)mrand48(); /* random initial sequence number */ session.iss = session.snd_nxt; session.rcv_nxt = 0; --- 86,92 ---- session.sport = sourcePort; session.dst = targetAddress; session.dport = targetPort; ! session.rcv_wnd = 3 * maxwin * mss;; /* NE: changed to receive 11K data */ session.snd_nxt = (uint32)mrand48(); /* random initial sequence number */ session.iss = session.snd_nxt; session.rcv_nxt = 0; *************** *** 299,304 **** --- 300,610 ---- } + /* NE: EstablishSession2 provides the test cases for Misbehaviors in TCP + * SACK Generation to have specified Initial Sequence Numbers as shown in paper. + */ + int EstablishSession2(uint32 sourceAddress, + uint16 sourcePort, + uint32 targetAddress, + uint16 targetPort, + int ip_optlen, // AM: add support for IP options + char *ip_opt, // AM: add support for IP options + int mss, + int optlen, + char *opt, + int maxwin, + int maxpkts, + uint8 iptos, + uint8 tcp_flags, // AM: Add a tcp_flags parameter + int offset ) + { + + int rawSocket; + + struct IPPacket *p; + struct IPPacket *synPacket; + char *read_packet; + struct PacketInfo pi; + int synAckReceived = 0; + int numRetransmits = 0; + double timeoutTime; + double ts1, ts2; + int flag = 1; + + if (session.debug) { + printf("In EstablishSession...\n"); + } + + session.src = sourceAddress; + session.sport = sourcePort; + session.dst = targetAddress; + session.dport = targetPort; + session.rcv_wnd = 3 * maxwin * mss; /* NE: changed to receive 11K data */ + session.snd_nxt = (uint32)mrand48(); /* random initial sequence number */ + switch(offset) { + + case SACKRCVR1: + session.snd_nxt = session.snd_nxt + 100000 - 76; + break; + + case SACKRCVR2: + session.snd_nxt = session.snd_nxt + 200000 - 76; + break; + + case SACKRCVR3: + session.snd_nxt = session.snd_nxt + 300000 - 76; + break; + + case SACKRCVR4: + session.snd_nxt = session.snd_nxt + 400000 - 76; + break; + + case SACKRCVR5: + session.snd_nxt = session.snd_nxt + 500000 - 76; + break; + + case SACKRCVR52: + session.snd_nxt = session.snd_nxt + 500000 - 76; + break; + + case SACKRCVR53: + session.snd_nxt = session.snd_nxt + 500000 - 76; + break; + + case SACKRCVR54: + session.snd_nxt = session.snd_nxt + 500000 - 76; + break; + + case SACKRCVR55: + session.snd_nxt = session.snd_nxt + 500000 - 76; + break; + + case SACKRCVR7: + session.snd_nxt = session.snd_nxt + 700000 - 76; + break; + + case SACKRCVR8: + session.snd_nxt = session.snd_nxt + 700000 - 76; + break; + + default: + break; + + } + + session.iss = session.snd_nxt; + session.rcv_nxt = 0; + session.irs = 0; + session.mss = mss ; + session.maxseqseen = 0 ; + session.epochTime = GetTime(); + session.maxpkts = maxpkts; + session.num_unwanted_drops = 0; + session.num_reordered = 0; + session.num_rtos = 0; + session.num_dup_acks = 0; + session.num_pkts_0_dup_acks = 0; + session.num_pkts_1_dup_acks = 0; + session.num_pkts_2_dup_acks = 0; + session.num_pkts_3_dup_acks = 0; + session.num_pkts_4_or_more_dup_acks = 0; + session.num_dupack_ret = 0; + session.num_reord_ret = 0; + session.num_reordered = 0; + session.num_dup_transmissions = 0; + session.ignore_result = 0; + session.curr_ttl = 0; + + if ((session.mtu < 1) || (session.mtu > 1460)) { + session.mtu = 1500; + } + + if (session.verbose) { + printf("session.MTU = %d\n", session.mtu); + } + + if ((session.dataRcvd = (uint8 *)calloc(sizeof(uint8), mss * session.maxpkts)) == NULL) { + perror("ERROR: no memmory to store data:\n"); + printf("RETURN CODE: %d\n", ERR_MEM_ALLOC); + Quit(ERR_MEM_ALLOC); + } + + /* Now open a raw socket for sending our "fake" TCP segments */ + if ((rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { + perror("ERROR: couldn't open socket:"); + printf("RETURN CODE: %d\n", ERR_SOCKET_OPEN); + Quit(ERR_SOCKET_OPEN); + } + + if (setsockopt(rawSocket, IPPROTO_IP, IP_HDRINCL, (char *)&flag,sizeof(flag)) < 0) { + perror("ERROR: couldn't set raw socket options:"); + printf("RETURN CODE: %d\n", ERR_SOCKOPT); + Quit(ERR_SOCKOPT); + } + + session.socket = rawSocket; + + /* set firewall */ + SetFireWall(); + + /* Allocate SYN packet */ + synPacket = AllocateIPPacket(ip_optlen, optlen, 0, "EstablishSession (SYN)"); + + /* Copy IP options at the end of IpHeader structure - New */ + if (ip_optlen > 0) { + memcpy((char *)synPacket->ip + sizeof(struct IpHeader), ip_opt, ip_optlen); + } + + /* Copy TCP options at the end of TcpHeader structure - New */ + if (optlen > 0) { + memcpy((char *)synPacket->tcp + sizeof(struct TcpHeader), opt, optlen); + } + + /* Send SYN Pkt */ + SendSessionPacket(synPacket, + sizeof(struct IpHeader) + ip_optlen + sizeof(struct TcpHeader) + optlen, + TCPFLAGS_SYN | tcp_flags, + ip_optlen, /* IP opt len */ + optlen, /* TCP opt len */ + iptos); + + timeoutTime = GetTime() + SYNTIMEOUT; + + /* + * Wait for SYN/ACK and retransmit SYN if appropriate + * not great, but it gets the job done + */ + + while(!synAckReceived && numRetransmits < MAXSYNRETRANSMITS) { + + while(GetTime() < timeoutTime) { + + /* Have we captured any packets? */ + + if ((read_packet = (char *)CaptureGetPacket(&pi)) != NULL) { + + p = (struct IPPacket *)FindHeaderBoundaries(read_packet); + + /* Received a packet from us to them */ + if (INSESSION(p, session.src, session.sport, session.dst, session.dport)) { + + /* Is it a SYN? */ + if (p->tcp->tcp_flags & TCPFLAGS_SYN) { + + if (session.debug) { + printf("saw the packet we sent...\n"); + PrintTcpPacket(p); + } + + StorePacket(p); + + ts1 = pi.ts.tv_sec + (double)pi.ts.tv_usec/1000000.0; + session.totSeenSent ++ ; + + } + + free(p); + continue; + + + } + + if (INSESSION(p, session.dst, session.dport, session.src, session.sport)) { + + /* Is it a SYN/ACK? */ + if (p->tcp->tcp_flags & (TCPFLAGS_SYN | TCPFLAGS_ACK)) { + + timeoutTime = GetTime(); /* force exit */ + synAckReceived++; + ts2 = pi.ts.tv_sec + (double)pi.ts.tv_usec/1000000.0; + session.rtt = ts2 - ts1 ; + + if (numRetransmits > 0) { + session.rtt_unreliable = 1; + printf("##### Unreliable\n"); /* ACK for which SYN? */ + } + + if (session.debug) { + printf("saw the packet he sent...\n"); + PrintTcpPacket(p); + printf("Connection setup took %d ms\n",(int)((ts2 - ts1) * 1000.0)); + } + + StorePacket(p); + + /* Save ttl for,admittedly poor,indications of reverse route change */ + session.ttl = p->ip->ip_ttl; + session.snd_wnd = ntohl(p->tcp->tcp_win); + session.totRcvd++; + + free(p); + break ; + + } + + } + + free(p->ip); + free(p->tcp); + free(p); + + } + + } + + if (!synAckReceived) { + + if (session.debug) { + printf("SYN timeout. Retransmitting\n"); + } + + SendSessionPacket(synPacket, + sizeof(struct IpHeader) + ip_optlen + sizeof(struct TcpHeader) + optlen, + TCPFLAGS_SYN | tcp_flags, + ip_optlen, /* IP opt len */ + optlen, /* TCP opt len */ + iptos); + + timeoutTime = GetTime() + SYNTIMEOUT; + numRetransmits++; + } + } + + if (numRetransmits >= MAXSYNRETRANSMITS) { + printf("ERROR: Could not establish contact after %d retries\nRETURN CODE: %d\n", + numRetransmits, NO_CONNECTION); + Quit(NO_CONNECTION); + } + + /* Update session variables */ + session.irs = ntohl(p->tcp->tcp_seq); + session.dataRcvd[0] = 1 ; + session.rcv_nxt = session.irs + 1; /* SYN/ACK takes up a byte of seq space */ + session.snd_nxt = session.iss + 1; /* SYN takes up a byte of seq space */ + session.snd_una = session.iss + 1; + session.maxseqseen = ntohl(p->tcp->tcp_seq); + + session.initSession = 1; + if (session.debug) { + printf("src = %s:%d (%u)\n", InetAddress(session.src), session.sport, session.iss); + printf("dst = %s:%d (%u)\n", InetAddress(session.dst), session.dport, session.irs); + } + + free(synPacket->ip); + free(synPacket->tcp); + free(synPacket); + + if (session.debug) { + printf("Out of EstablishSession...\n"); + } + + session.start_time = GetTime(); + + return 1; + + } + + int PrepareRequest(char *data, char *filename) { *************** *** 355,360 **** --- 661,737 ---- } + /* NE: HTTP 1.1 Request for SackRcvr5* (testE) */ + int PrepareRequest2(char *data, char *filename) + { + + char h1[] = "GET "; + char h2[] = " HTTP/1.1"; + char h3[] = "Host: "; + + char deffile[] = DEFAULT_FILENAME; + + + if (session.debug) { + printf("In PrepareRequest...\n"); + } + + if (filename == NULL) { + filename = deffile; + } + + sprintf(data, + + "%s%s%s\r\n%s%s\r\n\r\n", + h1, + "/index.pdf", // NE: get the index.pdf (11K) + h2, + h3, + "www.google.com"); + + + printf("Request: %s\n", data); + + return strlen(data); + + } + + /* Abu: HTTP 1.0 Request for SackRcvr4 (testD) */ + int PrepareRequest3(char *data, char *filename) + { + + char h1[] = "GET "; + char h2[] = " HTTP/1.0"; + char h3[] = "Host: "; + + char deffile[] = DEFAULT_FILENAME; + + + if (session.debug) { + printf("In PrepareRequest...\n"); + } + + if (filename == NULL) { + filename = deffile; + } + + sprintf(data, + + "%s%s%s\r\n%s%s\r\n\r\n", + h1, + "/index.pdf", // NE: get the index.pdf (11K) + h2, + h3, + "www.google.com"); + + + printf("Request: %s\n", data); + + return strlen(data); + + } + + void SendRequest(char *filename, void (*ackData)(struct IPPacket *p)) { *************** *** 556,565 **** } icmpsz = sizeof(struct ICMPUnreachableErrorPacket); ! if (((char *)icmp_pkt = (char *)calloc(icmpsz + 1, 1)) == NULL) { ! perror("ERROR: no space for ICMP packet:"); ! Quit(ERR_MEM_ALLOC) ; ! } /* Fill IP Header of ICMP packet */ bzero((char *)icmp_pkt, sizeof(struct ICMPUnreachableErrorPacket)); --- 933,944 ---- } icmpsz = sizeof(struct ICMPUnreachableErrorPacket); ! /* NE: disable the error ! if (((char *)icmp_pkt = (char *)calloc(icmpsz + 1, 1)) == NULL) { ! perror("ERROR: no space for ICMP packet:"); ! Quit(ERR_MEM_ALLOC) ; ! } ! */ /* Fill IP Header of ICMP packet */ bzero((char *)icmp_pkt, sizeof(struct ICMPUnreachableErrorPacket)); diff -c tbit-1.0/session.h tbit-1.0-newrelease/session.h *** tbit-1.0/session.h Tue Mar 1 15:23:49 2011 --- tbit-1.0-newrelease/session.h Tue Mar 1 15:23:25 2011 *************** *** 172,179 **** --- 172,204 ---- uint8 iptos, uint8 tcp_flags); + /* NE: EstablishSession2 provides the test cases for Misbehaviors in TCP + SACK Generation to have specified Initial Sequence Numbers as shown in paper. + */ + int EstablishSession2(uint32 sourceAddress, \ + uint16 sourcePort, \ + uint32 targetAddress, + uint16 targetPort, \ + int ip_optlen,\ + char *ip_opt,\ + int mss, + int optlen, + char *opt, \ + int maxwin, + int maxpkts, + uint8 iptos, + uint8 tcp_flags, + int offset); + + void rcvData (void (*ackData)(struct IPPacket *p)); void SendRequest(char *filename, void (*ackData)(struct IPPacket *p)); int PrepareRequest(char *data, char *filename) ; + + /* NE: Added methods for Misbehaviors in TCP SACK Generation test cases */ + /* NE: HTTP 1.1 Request for SackRcvr5* (testE) */ + int PrepareRequest2(char *data, char *filename) ; + /* Abu: HTTP 1.0 Request for SackRcvr4 (testD) */ + int PrepareRequest3(char *data, char *filename) ; diff -c tbit-1.0/support.c tbit-1.0-newrelease/support.c *** tbit-1.0/support.c Tue Mar 1 15:23:49 2011 --- tbit-1.0-newrelease/support.c Tue Mar 1 15:23:25 2011 *************** *** 120,130 **** } ! if (session.initSession > 0) { ! ! SendReset(); ! shutdown(session.socket,2); ! } if (session.initCapture > 0) { --- 120,135 ---- } ! /* Abu: For SackRcvr4 (testD in Misbehaviors in TCP SACK Generation) ! test do not send reset pdus */ ! if (doNotSendResets != 1) { ! ! if (session.initSession > 0) { ! ! SendReset(); ! shutdown(session.socket,2); ! ! } } if (session.initCapture > 0) { Files tbit-1.0/tbit and tbit-1.0-newrelease/tbit differ Common subdirectories: tbit-1.0/tbit-0.6.3 and tbit-1.0-newrelease/tbit-0.6.3 Only in tbit-1.0/: tbit-1.0 diff -c tbit-1.0/tbit.c tbit-1.0-newrelease/tbit.c *** tbit-1.0/tbit.c Tue Mar 1 15:23:49 2011 --- tbit-1.0-newrelease/tbit.c Tue Mar 1 15:23:25 2011 *************** *** 159,164 **** --- 159,175 ---- REORD_RET, DSACK, WINDOW_BUILDUP, + SACK_RCVR1, /* NE: testA for Misbehaviors in TCP SACK Generation */ + SACK_RCVR2, /* testB for Misbehaviors in TCP SACK Generation */ + SACK_RCVR3, /* testC for Misbehaviors in TCP SACK Generation */ + SACK_RCVR4, /* testD for Misbehaviors in TCP SACK Generation */ + SACK_RCVR5, /* testE for Misbehaviors in TCP SACK Generation */ + SACK_RCVR52, /* testF for Misbehaviors in TCP SACK Generation */ + SACK_RCVR53, /* testF for Misbehaviors in TCP SACK Generation */ + SACK_RCVR54, /* testF for Misbehaviors in TCP SACK Generation */ + SACK_RCVR55, /* testF for Misbehaviors in TCP SACK Generation */ + SACK_RCVR7, /* testG for Misbehaviors in TCP SACK Generation */ + SACK_RCVR8, /* testG for Misbehaviors in TCP SACK Generation */ LAST_TEST_ID /* do not (re)move this */ }; *************** *** 254,259 **** --- 265,281 ---- if (strcmp(optarg, "ECN") == 0) {testid = ECN; break;} if (strcmp(optarg, "ECN_IPOnly")==0) {testid = ECN_IPONLY; break;} if (strcmp(optarg, "SackRcvr") == 0) {testid = SACK_RCVR; break;} + if (strcmp(optarg, "SackRcvr1") == 0) {testid = SACK_RCVR1; break;} + if (strcmp(optarg, "SackRcvr2") == 0) {testid = SACK_RCVR2; break;} + if (strcmp(optarg, "SackRcvr3") == 0) {testid = SACK_RCVR3; break;} + if (strcmp(optarg, "SackRcvr4") == 0) {testid = SACK_RCVR4;doNotSendResets = 1; break;} + if (strcmp(optarg, "SackRcvr5") == 0) {testid = SACK_RCVR5; break;} + if (strcmp(optarg, "SackRcvr52") == 0) {testid = SACK_RCVR52; break;} + if (strcmp(optarg, "SackRcvr53") == 0) {testid = SACK_RCVR53; break;} + if (strcmp(optarg, "SackRcvr54") == 0) {testid = SACK_RCVR54; break;} + if (strcmp(optarg, "SackRcvr55") == 0) {testid = SACK_RCVR55; break;} + if (strcmp(optarg, "SackRcvr7") == 0) {testid = SACK_RCVR7; break;} + if (strcmp(optarg, "SackRcvr8") == 0) {testid = SACK_RCVR8; break;} if (strcmp(optarg, "InitWin") == 0) {testid = INITWIN; break;} if (strcmp(optarg, "DelAck") == 0) {testid = DELACK; break;} if (strcmp(optarg, "TimeWait") == 0) {testid = TIMEWAIT; break;} *************** *** 470,478 **** case ECN_IPONLY: ECN_IPONLYTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss); break ; ! case SACK_RCVR: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss); break ; case INITWIN: --- 492,546 ---- case ECN_IPONLY: ECN_IPONLYTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss); break ; ! ! /* NE: changed function SackRcvrTest to get a testopt with the last parameter */ case SACK_RCVR: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR); ! break ; ! ! /* NE: test cases for Misbehaviors in SACK Generation */ ! case SACK_RCVR1: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR1); ! break ; ! ! case SACK_RCVR2: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR2); ! break ; ! ! case SACK_RCVR3: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR3); ! break ; ! ! case SACK_RCVR4: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR4); ! break ; ! ! case SACK_RCVR5: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR5); ! break ; ! ! case SACK_RCVR52: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR52); ! break ; ! ! case SACK_RCVR53: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR53); ! break ; ! ! case SACK_RCVR54: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR54); ! break ; ! ! case SACK_RCVR55: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR55); ! break ; ! ! case SACK_RCVR7: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR7); ! break ; ! ! case SACK_RCVR8: ! SackRcvrTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss, SACKRCVR8); break ; case INITWIN: diff -c tbit-1.0/tbit.h tbit-1.0-newrelease/tbit.h *** tbit-1.0/tbit.h Tue Mar 1 15:23:49 2011 --- tbit-1.0-newrelease/tbit.h Tue Mar 1 15:23:25 2011 *************** *** 117,119 **** --- 117,121 ---- #define _DEBUG #endif + + int doNotSendResets; /* NE: this variable is used to control sending reset pdus */