aboutsummaryrefslogtreecommitdiffstats
path: root/mkcap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mkcap.c')
-rw-r--r--mkcap.c602
1 files changed, 307 insertions, 295 deletions
diff --git a/mkcap.c b/mkcap.c
index 0ebf50b79f..a7cefdf92e 100644
--- a/mkcap.c
+++ b/mkcap.c
@@ -105,7 +105,7 @@ struct seg_hist_s {
/* but a retransmit will have a new seg */
int flags; /* Flags as above for ack and seg loss */
int acks_first_seq; /* How many times we have seen an ack
- for the first seq number in this seg */
+ for the first seq number in this seg */
};
#define SEG_HIST_SIZE 128
@@ -120,25 +120,25 @@ int delayed_ack_wait = 30000; /* 30 mS before an ACK is generated if */
void
makeseg(char *eth1, char *eth2, char *ip1, char *ip2, char *p1, char *p2, int *s1, int *s2, char *flags, int len)
{
- int i;
-
- printf("2002/01/07 00:00:%02d.%06d\n", ts/1000000, ts%1000000);
- printf("0000 %s %s 08 00\n", eth1, eth2);
- printf("000e 45 00 %02x %02x 00 00 00 00 40 06 00 00 %s %s\n", (len+40)>>8, (len+40)&0xff, ip1, ip2);
- printf("0022 %s %s %02x %02x %02x %02x %02x %02x %02x %02x 50 %s 80 00 00 00 00 00", p1, p2,
- ((*s1)>>24)&0xff,
- ((*s1)>>16)&0xff,
- ((*s1)>>8)&0xff,
- ((*s1))&0xff,
- ((*s2)>>24)&0xff,
- ((*s2)>>16)&0xff,
- ((*s2)>>8)&0xff,
- ((*s2))&0xff,
- flags );
- for(i=0;i<(len<(snap_len-40)?len:snap_len-40);i++)printf(" 00");
- printf("\n");
- printf("\n");
- (*s1)+=len;
+ int i;
+
+ printf("2002/01/07 00:00:%02d.%06d\n", ts/1000000, ts%1000000);
+ printf("0000 %s %s 08 00\n", eth1, eth2);
+ printf("000e 45 00 %02x %02x 00 00 00 00 40 06 00 00 %s %s\n", (len+40)>>8, (len+40)&0xff, ip1, ip2);
+ printf("0022 %s %s %02x %02x %02x %02x %02x %02x %02x %02x 50 %s 80 00 00 00 00 00", p1, p2,
+ ((*s1)>>24)&0xff,
+ ((*s1)>>16)&0xff,
+ ((*s1)>>8)&0xff,
+ ((*s1))&0xff,
+ ((*s2)>>24)&0xff,
+ ((*s2)>>16)&0xff,
+ ((*s2)>>8)&0xff,
+ ((*s2))&0xff,
+ flags );
+ for(i=0;i<(len<(snap_len-40)?len:snap_len-40);i++)printf(" 00");
+ printf("\n");
+ printf("\n");
+ (*s1)+=len;
}
/*
@@ -204,12 +204,12 @@ int next_ack_due()
if (ack_lost) {
if (delayed_ack) {
if (((first_slot + 1 + 2 * ack_lost) % SEG_HIST_SIZE) >= next_slot)
- /* XXX: FIXME, what about when the window is closed */
- /* XXX: FIXME, use the correct value for this */
- return (((unsigned int)(1<<31)) - 1);
+ /* XXX: FIXME, what about when the window is closed */
+ /* XXX: FIXME, use the correct value for this */
+ return (((unsigned int)(1<<31)) - 1);
else
- return seg_hist[(first_slot + 1 + 2 * ack_lost) % SEG_HIST_SIZE].ts +
- ack_delay + jitter;
+ return seg_hist[(first_slot + 1 + 2 * ack_lost) % SEG_HIST_SIZE].ts +
+ ack_delay + jitter;
}
else
return seg_hist[slot].ts + ack_delay + jitter;
@@ -311,88 +311,88 @@ gen_next_ack(int force, int spacing)
else
cwnd = cwnd + data_acked;
if (verbose) fprintf(stderr, "Ack rcvd. ts: %d, data_acked: %d, cwnd: %d, window: %d\n",
- ts, data_acked, cwnd, window);
+ ts, data_acked, cwnd, window);
if (cwnd > window) cwnd = window;
}
void
makeackedrun(int len, int spacing, int ackdelay)
{
- int next_ack_ts=0;
- if (verbose) fprintf(stderr, "makeackedrun: Len=%d, spacing=%d, ackdelay=%d\n",
- len, spacing, ackdelay);
- while(len>0){
-
- /*
- * Each time we output a segment, we should check to see if an
- * ack is due back before the next segment is due ...
- */
- int seglen, saved_seq;
- seglen=(len>1460)?1460:len;
- /*
- * Only output what is left in the cwnd.
- * We assume there is space in the congestion window here
- */
- if (seglen > (cwnd - used_win)) seglen = cwnd - used_win;
-
- len-=seglen;
- saved_seq = seq_1;
- if (verbose) fprintf(stderr, "Sending segment. ts: %d, jitter: %d\n", ts, jitter);
- if(len){
- makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &seq_1, &seq_2, "10", seglen);
- } else {
- makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &seq_1, &seq_2, "18", seglen);
- }
- add_seg_sent(saved_seq, seglen);
-
- /*
- * Now, if the window is closed, then we have to eject an
- * ack, otherwise we can eject more data.
- * Also, the other end will tend to ack two segments at
- * a time ... and that ack might fall between two
- * outgoing segments
- */
- jitter = (rand()%10) - 5; /* What if spacing too small */
-
- if (verbose) fprintf(stderr, "used win: %d, cwnd: %d\n", used_win, cwnd);
-
- if ((next_ack_ts = next_ack_due()) < ts + spacing + jitter) {
- int old_ts = ts;
-
- /*
- * Generate the ack and retire the segments
- * If delayed ACK in use, there should be two
- * or more outstanding segments ...
- */
- if (verbose) fprintf(stderr, "Non forced ACK ...ts + spacing + jitter:%d, jitter: %d\n", ts + spacing + jitter, jitter);
- gen_next_ack(NO_FORCE_ACK, spacing);
- /*
- * We don't want time to go backwards ...
- */
- if (old_ts + spacing + jitter <= ts)
- ts++;
- else
- ts = old_ts + spacing + jitter;
-
- } else if (used_win == cwnd) {
-
- /*
- * We need an ACK, so generate it and retire the
- * segments and advance the ts to the time of the ack
- */
-
- if (verbose) fprintf(stderr, "Forced ACK ... \n");
- gen_next_ack(FORCE_ACK, spacing);
-
- ts+=(spacing+jitter); /* Should not use spacing here */
-
- }
- else {
- ts+=(spacing+jitter);
- }
-
- if (verbose) fprintf(stderr, "Next Ack Due: %d\n", next_ack_ts);
- }
+ int next_ack_ts=0;
+ if (verbose) fprintf(stderr, "makeackedrun: Len=%d, spacing=%d, ackdelay=%d\n",
+ len, spacing, ackdelay);
+ while(len>0){
+
+ /*
+ * Each time we output a segment, we should check to see if an
+ * ack is due back before the next segment is due ...
+ */
+ int seglen, saved_seq;
+ seglen=(len>1460)?1460:len;
+ /*
+ * Only output what is left in the cwnd.
+ * We assume there is space in the congestion window here
+ */
+ if (seglen > (cwnd - used_win)) seglen = cwnd - used_win;
+
+ len-=seglen;
+ saved_seq = seq_1;
+ if (verbose) fprintf(stderr, "Sending segment. ts: %d, jitter: %d\n", ts, jitter);
+ if(len){
+ makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &seq_1, &seq_2, "10", seglen);
+ } else {
+ makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &seq_1, &seq_2, "18", seglen);
+ }
+ add_seg_sent(saved_seq, seglen);
+
+ /*
+ * Now, if the window is closed, then we have to eject an
+ * ack, otherwise we can eject more data.
+ * Also, the other end will tend to ack two segments at
+ * a time ... and that ack might fall between two
+ * outgoing segments
+ */
+ jitter = (rand()%10) - 5; /* What if spacing too small */
+
+ if (verbose) fprintf(stderr, "used win: %d, cwnd: %d\n", used_win, cwnd);
+
+ if ((next_ack_ts = next_ack_due()) < ts + spacing + jitter) {
+ int old_ts = ts;
+
+ /*
+ * Generate the ack and retire the segments
+ * If delayed ACK in use, there should be two
+ * or more outstanding segments ...
+ */
+ if (verbose) fprintf(stderr, "Non forced ACK ...ts + spacing + jitter:%d, jitter: %d\n", ts + spacing + jitter, jitter);
+ gen_next_ack(NO_FORCE_ACK, spacing);
+ /*
+ * We don't want time to go backwards ...
+ */
+ if (old_ts + spacing + jitter <= ts)
+ ts++;
+ else
+ ts = old_ts + spacing + jitter;
+
+ } else if (used_win == cwnd) {
+
+ /*
+ * We need an ACK, so generate it and retire the
+ * segments and advance the ts to the time of the ack
+ */
+
+ if (verbose) fprintf(stderr, "Forced ACK ... \n");
+ gen_next_ack(FORCE_ACK, spacing);
+
+ ts+=(spacing+jitter); /* Should not use spacing here */
+
+ }
+ else {
+ ts+=(spacing+jitter);
+ }
+
+ if (verbose) fprintf(stderr, "Next Ack Due: %d\n", next_ack_ts);
+ }
}
@@ -400,88 +400,88 @@ makeackedrun(int len, int spacing, int ackdelay)
void
makeackedrundroppedtail8kb(int len, int spacing, int ackdelay)
{
- int old_seq1;
- int dropped_tail;
- int i;
- int num_dupes;
- if (verbose) fprintf(stderr, "makeackedrundroppedtail8kB: Len=%d, spacing=%d, ackdelay=%d\n",
- len, spacing, ackdelay);
- old_seq1=seq_1;
- while(len>0){
- int seglen;
- seglen=(len>1460)?1460:len;
- len-=seglen;
- if(seglen==1460){
- makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &seq_1, &seq_2, "10", seglen);
- } else {
- makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &seq_1, &seq_2, "18", seglen);
- }
- ts+=spacing;
- }
-
- ts+=ackdelay;
-
- i=0;
- num_dupes=-1;
- dropped_tail=0;
- while(old_seq1!=seq_1){
- int ack_len;
-
- ack_len=((seq_1-old_seq1)>2920)?2920:(seq_1-old_seq1);
-
- i++;
- if(i==6){
- dropped_tail=old_seq1;
- }
- old_seq1+=ack_len;
- if(i<6){
- makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &old_seq1, "10", 0);
- } else if (i==6) {
- makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &dropped_tail, "10", 0);
- num_dupes+=2;
- } else {
- makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &dropped_tail, "10", 0);
- makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &dropped_tail, "10", 0);
- num_dupes+=2;
- }
- ts+=spacing/2;
- }
-
- if(!dropped_tail){
- return;
- }
-
- if(num_dupes<3){
- int seglen;
- ts+=1000000;
- seglen=((seq_1-dropped_tail)>1460)?1460:(seq_1-dropped_tail);
- if(seglen==1460){
- makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &dropped_tail, &seq_2, "10", seglen);
- } else {
- makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &dropped_tail, &seq_2, "18", seglen);
- }
- ts+=ackdelay;
-
- makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &seq_1, "10", 0);
- ts+=spacing;
- return;
- }
-
- while(dropped_tail!=seq_1){
- int seglen;
- int ack;
- seglen=((seq_1-dropped_tail)>1460)?1460:(seq_1-dropped_tail);
- if(seglen==1460){
- makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &dropped_tail, &seq_2, "10", seglen);
- } else {
- makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &dropped_tail, &seq_2, "18", seglen);
- }
- ts+=ackdelay;
-
- ack=dropped_tail;
- makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &ack, "10", 0);
- ts+=spacing;
- }
+ int old_seq1;
+ int dropped_tail;
+ int i;
+ int num_dupes;
+ if (verbose) fprintf(stderr, "makeackedrundroppedtail8kB: Len=%d, spacing=%d, ackdelay=%d\n",
+ len, spacing, ackdelay);
+ old_seq1=seq_1;
+ while(len>0){
+ int seglen;
+ seglen=(len>1460)?1460:len;
+ len-=seglen;
+ if(seglen==1460){
+ makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &seq_1, &seq_2, "10", seglen);
+ } else {
+ makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &seq_1, &seq_2, "18", seglen);
+ }
+ ts+=spacing;
+ }
+
+ ts+=ackdelay;
+
+ i=0;
+ num_dupes=-1;
+ dropped_tail=0;
+ while(old_seq1!=seq_1){
+ int ack_len;
+
+ ack_len=((seq_1-old_seq1)>2920)?2920:(seq_1-old_seq1);
+
+ i++;
+ if(i==6){
+ dropped_tail=old_seq1;
+ }
+ old_seq1+=ack_len;
+ if(i<6){
+ makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &old_seq1, "10", 0);
+ } else if (i==6) {
+ makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &dropped_tail, "10", 0);
+ num_dupes+=2;
+ } else {
+ makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &dropped_tail, "10", 0);
+ makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &dropped_tail, "10", 0);
+ num_dupes+=2;
+ }
+ ts+=spacing/2;
+ }
+
+ if(!dropped_tail){
+ return;
+ }
+
+ if(num_dupes<3){
+ int seglen;
+ ts+=1000000;
+ seglen=((seq_1-dropped_tail)>1460)?1460:(seq_1-dropped_tail);
+ if(seglen==1460){
+ makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &dropped_tail, &seq_2, "10", seglen);
+ } else {
+ makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &dropped_tail, &seq_2, "18", seglen);
+ }
+ ts+=ackdelay;
+
+ makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &seq_1, "10", 0);
+ ts+=spacing;
+ return;
+ }
+
+ while(dropped_tail!=seq_1){
+ int seglen;
+ int ack;
+ seglen=((seq_1-dropped_tail)>1460)?1460:(seq_1-dropped_tail);
+ if(seglen==1460){
+ makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &dropped_tail, &seq_2, "10", seglen);
+ } else {
+ makeseg(eth_1, eth_2, ip_1, ip_2, port_1, port_2, &dropped_tail, &seq_2, "18", seglen);
+ }
+ ts+=ackdelay;
+
+ ack=dropped_tail;
+ makeseg(eth_2, eth_1, ip_2, ip_1, port_2, port_1, &seq_2, &ack, "10", 0);
+ ts+=spacing;
+ }
}
void usage()
@@ -556,7 +556,7 @@ process_drop_list(char *drop_list)
if (!all_digits(tok)) {
fprintf(stderr, "Error in segment offset or count. Not all digits: %s\n",
- tok);
+ tok);
fprintf(stderr, "No packet drops being performed!\n");
g_free(save);
g_free(drops);
@@ -577,116 +577,128 @@ process_drop_list(char *drop_list)
int
main(int argc, char *argv[])
{
- int i;
- int len;
- int type;
- int cnt;
- extern char *optarg;
- extern int optind;
- int opt;
-
- while ((opt = getopt(argc, argv, "a:b:d:Di:I:j:l:n:N:p:P:r:s:vw:")) != EOF) {
- switch (opt) {
- case 'a':
- ack_delay = atoi(optarg);
- break;
-
- case 'b': /* Bytes ... */
- total_bytes = atoi(optarg);
- break;
-
- case 'd': /* A list of drops to simulate */
- process_drop_list(optarg);
- break;
-
- case 'D': /* Toggle tcp_nodelay */
- tcp_nodelay = (tcp_nodelay + 1) % 1;
- break;
-
- case 'i':
- ip_1 = optarg;
- break;
-
- case 'I':
- ip_2 = optarg;
- break;
-
- case 'l':
- snap_len = atoi(optarg);
- break;
-
- case 'n': /* ISN for send dirn, ie, seq_1 */
- seq_1 = atoi(optarg);
- break;
-
- case 'N': /* ISN for recv dirn, ie, seq_2 */
- seq_2 = atoi(optarg);
- break;
-
- case 'p':
- port_1 = optarg;
- break;
-
- case 'P':
- port_2 = optarg;
- break;
-
- case 'r':
- run_type = atoi(optarg);
- break;
-
- case 's':
- send_spacing = atoi(optarg);
- break;
-
- case 'v':
- verbose++;
- break;
-
- case 'w': /* Window ... */
- window = atoi(optarg);
- ssthresh = window / 2; /* Have to recalc this ... */
- break;
-
- default:
- usage();
- break;
- }
- }
-
- if (verbose) fprintf(stderr, "IP1: %s, IP2: %s, P1: %s, P2: %s, Ack Delay: %d, Send Spacing: %d\n",
- ip_1, ip_2, port_1, port_2, ack_delay, send_spacing);
-
- /*return 0; */
-
- if (run_type == 0) {
- makeackedrun(total_bytes, send_spacing, ack_delay);
- }
- else {
- for(cnt=0;cnt<200;cnt++){
- type=rand()%150;
- if(type<75){
- int j;
- j=5+rand()%10;
- for(i=0;i<j;i++){
- makeackedrun(32768, send_spacing, ack_delay);
- }
- } else if(type<90) {
- int j;
- j=4+rand()%4;
- for(i=0;i<j;i++){
- len=100+rand()&0xfff;
- makeackedrun(len, send_spacing, ack_delay);
- }
- } else {
- for(i=0;i<5;i++){
- len=100+rand()&0x3fff+0x1fff;
- makeackedrun(len, send_spacing, ack_delay);
- /*makeackedrundroppedtail8kb(len, send_spacing, ack_delay);*/
- }
- }
- }
- }
- return 0;
+ int i;
+ int len;
+ int type;
+ int cnt;
+ extern char *optarg;
+ extern int optind;
+ int opt;
+
+ while ((opt = getopt(argc, argv, "a:b:d:Di:I:j:l:n:N:p:P:r:s:vw:")) != EOF) {
+ switch (opt) {
+ case 'a':
+ ack_delay = atoi(optarg);
+ break;
+
+ case 'b': /* Bytes ... */
+ total_bytes = atoi(optarg);
+ break;
+
+ case 'd': /* A list of drops to simulate */
+ process_drop_list(optarg);
+ break;
+
+ case 'D': /* Toggle tcp_nodelay */
+ tcp_nodelay = (tcp_nodelay + 1) % 1;
+ break;
+
+ case 'i':
+ ip_1 = optarg;
+ break;
+
+ case 'I':
+ ip_2 = optarg;
+ break;
+
+ case 'l':
+ snap_len = atoi(optarg);
+ break;
+
+ case 'n': /* ISN for send dirn, ie, seq_1 */
+ seq_1 = atoi(optarg);
+ break;
+
+ case 'N': /* ISN for recv dirn, ie, seq_2 */
+ seq_2 = atoi(optarg);
+ break;
+
+ case 'p':
+ port_1 = optarg;
+ break;
+
+ case 'P':
+ port_2 = optarg;
+ break;
+
+ case 'r':
+ run_type = atoi(optarg);
+ break;
+
+ case 's':
+ send_spacing = atoi(optarg);
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+
+ case 'w': /* Window ... */
+ window = atoi(optarg);
+ ssthresh = window / 2; /* Have to recalc this ... */
+ break;
+
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (verbose) fprintf(stderr, "IP1: %s, IP2: %s, P1: %s, P2: %s, Ack Delay: %d, Send Spacing: %d\n",
+ ip_1, ip_2, port_1, port_2, ack_delay, send_spacing);
+
+ /*return 0; */
+
+ if (run_type == 0) {
+ makeackedrun(total_bytes, send_spacing, ack_delay);
+ }
+ else {
+ for(cnt=0;cnt<200;cnt++){
+ type=rand()%150;
+ if(type<75){
+ int j;
+ j=5+rand()%10;
+ for(i=0;i<j;i++){
+ makeackedrun(32768, send_spacing, ack_delay);
+ }
+ } else if(type<90) {
+ int j;
+ j=4+rand()%4;
+ for(i=0;i<j;i++){
+ len=100+rand()&0xfff;
+ makeackedrun(len, send_spacing, ack_delay);
+ }
+ } else {
+ for(i=0;i<5;i++){
+ len=100+rand()&0x3fff+0x1fff;
+ makeackedrun(len, send_spacing, ack_delay);
+ /*makeackedrundroppedtail8kb(len, send_spacing, ack_delay);*/
+ }
+ }
+ }
+ }
+ return 0;
}
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local Variables:
+ * c-basic-offset: 2
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=2 tabstop=8 expandtab:
+ * :indentSize=2:tabSize=8:noTabs=true:
+ */