void rttgraph_read( struct ip *pip, /* the packet */ tcp_pair *ptp, /* info I have about this connection */ void *plast, /* past byte in the packet */ void *mod_data) /* module specific info for this connection */ { struct tcphdr *ptcp; struct rttgraph_info *prttg = mod_data; struct rtt_tcb *prtcb; tcb *ptcb; double rtt_us; u_long rtt_ms; /* find the start of the TCP header */ ptcp = (struct tcphdr *) ((char *)pip + 4*IP_HL(pip)); /* make sure there we could have a RTT sample */ if (!ACK_SET(ptcp)) return; /* no RTT info */ /* see which direction it is, if we don't know yet */ ptcb = ptp2ptcb(ptp,pip,ptcp); if (ptcb == prttg->a2b.ptcb) prtcb = &prttg->a2b; else if (ptcb == prttg->b2a.ptcb) prtcb = &prttg->b2a; else { fprintf(stderr, "rttgraph_read: INTERNAL error (can't kind tcb)!!\n"); exit(1); } /* grab the RTT */ rtt_us = prtcb->ptcb->rtt_last; if (rtt_us == 0.0) return; /* not a valid sample */ /* convert to ms buckets */ rtt_ms = (u_long) (rtt_us / 1000.0); if (debug && (rtt_ms == 0)) printf("rtt_ms is 0, rtt_us was %f\n", rtt_us); /* add in the sample RTT */ AddSample(&prtcb->samples, rtt_ms); }
void traffic_read( struct ip *pip, /* the packet */ tcp_pair *ptp, /* info I have about this connection */ void *plast, /* past byte in the packet */ void *mod_data) /* connection info for this one */ { struct tcphdr *ptcp = (struct tcphdr *) ((char *)pip + 4*IP_HL(pip)); struct traffic_info *pti1 = FindPort(ntohs(ptcp->th_sport)); struct traffic_info *pti2 = FindPort(ntohs(ptcp->th_dport)); u_long bytes = ntohs(pip->ip_len); static timeval last_time = {0,0}; struct conn_info *pci = mod_data; int was_rexmit = 0; /* in case files aren't set up yet */ traffic_init_files(); /* if neither port is interesting, then ignore this one */ if (!pti1 && !pti2) { return; } /* OK, this connection is now active */ pci->wasactive = 1; /* check to see if it's really "open" (traffic in both directions) */ if (!pci->wasopen) { if ((ptp->a2b.packets > 0) && (ptp->b2a.packets > 0)) { /* bidirectional: OK, we'll call it open */ pci->wasopen = 1; pci->isopen = 1; ++num_opens; ++ttl_num_opens; ++open_conns; /* instantaneous opens and closes */ if (doplot_i_open) { DoplotIOpen(ntohs(ptcp->th_dport), TRUE); DoplotIOpen(ntohs(ptcp->th_sport), TRUE); DoplotIOpen(0, TRUE); } } } /* add to port-specific counters */ if (pti1) { pti1->nbytes += bytes; pti1->npackets += 1; } if (pti2) { pti2->nbytes += bytes; pti2->npackets += 1; } /* add to GLOBAL counters */ ports[0]->nbytes += bytes; ports[0]->npackets += 1; ports[0]->npureacks += 1; /* see if we're closing it */ if (RESET_SET(ptcp) || (FIN_SET(ptcp) && /* find in BOTH directions */ ((ptp->a2b.fin_count>0) && (ptp->b2a.fin_count>0)))) { if (pci->isopen) { pci->isopen = 0; ++num_closes; --open_conns; /* instantaneous opens and closes */ if (doplot_i_open) { DoplotIOpen(ntohs(ptcp->th_dport), FALSE); DoplotIOpen(ntohs(ptcp->th_sport), FALSE); DoplotIOpen(0, FALSE); } } } /* half open conns */ if (FIN_SET(ptcp)) { if ((ptp->a2b.fin_count>0) && (ptp->b2a.fin_count>0)) { if (pci->halfopen) { /* fully closed now */ --num_halfopens; pci->halfopen = 0; } } else if (!pci->halfopen) { /* half open now */ ++num_halfopens; pci->halfopen = 1; } } /* check losses */ if (pci->last_dupacks != ptp->a2b.rtt_triple_dupack+ ptp->b2a.rtt_triple_dupack) { pci->last_dupacks = ptp->a2b.rtt_triple_dupack+ ptp->b2a.rtt_triple_dupack; ++dupacks; ++ttl_dupacks; } if (pci->last_rexmits != ptp->a2b.rexmit_pkts+ptp->b2a.rexmit_pkts) { pci->last_rexmits = ptp->a2b.rexmit_pkts+ptp->b2a.rexmit_pkts; was_rexmit = 1; ++rexmits; ++ttl_rexmits; } /* add to total data counters */ data_nbytes_all += bytes; if (!was_rexmit) data_nbytes_nonrexmit += bytes; /* RTT stats */ if (ACK_SET(ptcp)) { tcb *ptcb; int rtt; /* see which of the 2 TCB's this goes with */ if (ptp->addr_pair.a_port == ntohs(ptcp->th_dport)) ptcb = &ptp->a2b; else ptcb = &ptp->b2a; /* check the rtt counter of the last sample */ rtt = ptcb->rtt_last / 1000.0; if ((pci->last_rtts != ptcb->rtt_count + ptcb->rtt_amback) && (ptcb->rtt_last != 0.0) && (rtt > rtt_minvalid) && (rtt <= rtt_maxvalid)) { /* sample is only valid when one of these counters is higher */ pci->last_rtts = ptcb->rtt_count + ptcb->rtt_amback; /* keep stats */ rtt_ttl += rtt; ttl_rtt_ttl += rtt; ++rtt_samples; ++ttl_rtt_samples; /* also, remember min and max */ if ((rtt_max == -1) || (rtt_max < rtt)) rtt_max = rtt; if ((rtt_min == -1) || (rtt_min > rtt)) rtt_min = rtt; if (ldebug > 9) printf("Rtt: %d, min:%d, max:%d\n", rtt, rtt_min, rtt_max); } } /* see if this is now "long duration" */ if (!pci->islong) { int etime_msecs = elapsed(ptp->first_time,current_time); if (etime_msecs/1000000 > longconn_duration) { pci->islong = 1; } } /* count "pure acks" (no data) */ if (ACK_SET(ptcp)) { int tcp_length, tcp_data_length; tcp_length = getpayloadlength(pip, plast); tcp_data_length = tcp_length - (4 * TH_OFF(ptcp)); if (tcp_data_length == 0) { if (pti1) { ++pti1->npureacks; } if (pti2) { ++pti2->npureacks; } } } /* determine elapsed time and age the samples */ if (elapsed(last_time,current_time)/1000000.0 > age_interval) { AgeTraffic(); last_time = current_time; } }