/* Fills the given _fg_tcp_info with the values of the OS specific tcp_info, * returns 0 on success */ int get_tcp_info(struct _flow *flow, struct _fg_tcp_info *info) { #if (defined __LINUX__ || defined __FreeBSD__) struct tcp_info tmp_info; socklen_t info_len = sizeof(tmp_info); int rc; memset(info, 0, sizeof(struct _fg_tcp_info)); rc = getsockopt(flow->fd, IPPROTO_TCP, TCP_INFO, &tmp_info, &info_len); if (rc == -1) { warn("getsockopt() failed"); return -1; } #define CPY_INFO_MEMBER(a) info->a = (int) tmp_info.a; CPY_INFO_MEMBER(tcpi_snd_cwnd); CPY_INFO_MEMBER(tcpi_snd_ssthresh); CPY_INFO_MEMBER(tcpi_rtt); CPY_INFO_MEMBER(tcpi_rttvar); CPY_INFO_MEMBER(tcpi_rto); CPY_INFO_MEMBER(tcpi_snd_mss); /* FreeBSD 9.1 doesn't fill these members */ #ifdef __LINUX__ CPY_INFO_MEMBER(tcpi_backoff); CPY_INFO_MEMBER(tcpi_unacked); CPY_INFO_MEMBER(tcpi_sacked); CPY_INFO_MEMBER(tcpi_retrans); CPY_INFO_MEMBER(tcpi_retransmits); CPY_INFO_MEMBER(tcpi_fackets); CPY_INFO_MEMBER(tcpi_reordering); #endif #else memset(info, 0, sizeof(_fg_tcp_info); #endif return 0; }
/* Fills the given _fg_tcp_info with the values of the OS specific tcp_info, * returns 0 on success */ int get_tcp_info(struct flow *flow, struct fg_tcp_info *info) { #ifdef HAVE_TCP_INFO struct tcp_info tmp_info; socklen_t info_len = sizeof(tmp_info); int rc; memset(info, 0, sizeof(struct fg_tcp_info)); rc = getsockopt(flow->fd, IPPROTO_TCP, TCP_INFO, &tmp_info, &info_len); if (rc == -1) { warn("getsockopt() failed"); return -1; } #define CPY_INFO_MEMBER(a) info->a = (int) tmp_info.a; CPY_INFO_MEMBER(tcpi_snd_cwnd); CPY_INFO_MEMBER(tcpi_snd_ssthresh); CPY_INFO_MEMBER(tcpi_rtt); CPY_INFO_MEMBER(tcpi_rttvar); CPY_INFO_MEMBER(tcpi_rto); CPY_INFO_MEMBER(tcpi_snd_mss); /* TODO FreeBSD 9.1 doesn't fill these members, but maybe FreeBSD 10.0 * will fill it, so get rid of this ifdef */ #ifdef __LINUX__ CPY_INFO_MEMBER(tcpi_backoff); CPY_INFO_MEMBER(tcpi_unacked); CPY_INFO_MEMBER(tcpi_sacked); CPY_INFO_MEMBER(tcpi_lost); CPY_INFO_MEMBER(tcpi_retrans); CPY_INFO_MEMBER(tcpi_retransmits); CPY_INFO_MEMBER(tcpi_fackets); CPY_INFO_MEMBER(tcpi_reordering); CPY_INFO_MEMBER(tcpi_ca_state); #endif /* __LINUX__ */ #else /* HAVE_TCP_INFO */ UNUSED_ARGUMENT(flow); memset(info, 0, sizeof(struct fg_tcp_info)); #endif /* HAVE_TCP_INFO */ return 0; }