send_packet()
sends the probe packet, which is defined in the following structure in the ipprobe-manager
.h file:
typedef struct { u_short id; /** Probe ID */ u_short type; /** Packet type */ u_short seq; /** Packet sequence number */ struct timeval tx_time; /** Initiator transmit time */ struct timeval target_rx_time; /** Target receive time */ struct timeval target_tx_time; /** Target transmit time */ struct timeval rx_time; /** Initiator receive time */ char pad[0]; /** Pad section */ } probe_packet_data_t; typedef struct { struct ip header; /** IP header */ union { struct icmphdr icmp; /** ICMP header */ struct udphdr udp; /** UDP header */ }; probe_packet_data_t data; /** Packet data section */ } probe_packet_t;
gettimeofday()
and storing the value in the packet data field tx_time
. The tx_time
field is a FreeBSD timeval
structure that represents an elapsed time. It is declared in sys/time
.h and has the following members:
long int tv_sec
represents the number of whole seconds of elapsed time.long int tv_usec
is the rest of the elapsed time (a fraction of a second), represented as the number of microseconds.receive_probe_packets()
handler on the target router declares another timeval
structure, rx_time
, and populates it in the same way. The process_probe_packets()
function then calculates the difference between the two values. For example:
packet_stats[i].sd_delay = time_diff(&data_buf[i].tx_time, &data_buf[i].target_rx_time);
For more information about the application's statistics gathering, see Receiving Reply Packets and Calculating Statistics.
static void send_packet (evContext ctx UNUSED, void *uap UNUSED, struct timespec due UNUSED, struct timespec inter UNUSED) { probe_packet_t *packet = (probe_packet_t *)tx_buf; int send_len; do { packet->data.seq = tx_count; gettimeofday(&packet->data.tx_time, NULL); if (probe_params.protocol == IPPROTO_ICMP) { packet->icmp.icmp_cksum = 0; packet->icmp.icmp_cksum = icmp_cksum(&packet->icmp, probe_params.packet_size - sizeof(struct ip)); } else if (probe_params.protocol == IPPROTO_UDP) { packet->udp.uh_sum = 0; packet->udp.uh_sum = udp_cksum(ntohs(packet->udp.uh_ulen), &packet->header.ip_src.s_addr, &packet->header.ip_dst.s_addr, &packet->udp); } send_len = sendto(tx_socket, packet, probe_params.packet_size, 0, (struct sockaddr *)&target_addr, sizeof(target_addr)); if (send_len < 0) { PRINT_ERRORNO("Send probe packet!\n"); } if (++tx_count == probe_params.packet_count) { /* Disable the timer. */ evClearTimer(ev_ctx, ev_tx_timer_id); printf("Sent %d probe packets to %s.\n", tx_count, inet_ntoa(target_addr.sin_addr)); break; } } while (probe_params.packet_interval == 0); return; }
Receiving Reply Packets and Calculating Statistics