Re: Skyhigh retransmit times. Yearold problem still in 2.3.26

kuznet@ms2.inr.ac.ru
Sun, 14 Nov 1999 22:40:35 +0300 (MSK)


Hello!

> >It is really worth to blame to net-tools folks, my netstat show "ka")
>
> So send a patch. :-)

Please, do not think about me too bad. If I had patches for
net-tools, I would submit them to you immediately.

The problem is in my utter conservatism, I use some version
of net-tools dated by 1996, 1.32, patched by some unknown
nowadays IPv6 patches. It was incredibly dirtily hacked for years
to show me that information, which I wanted to see that day when
debugging something 8) And I would not ever show it to my mother 8)

To get an impression, look at the function tcp_info() from it.
Do you still want a patch? 8) I bet it is much easier to make the same
things from scratch.

Alexey

static int
tcp_info(void)
{
int flag6 = 0;
char buffer[8192], local_addr[128];
char rem_addr[128], *tcp_state, timers[64];
#ifdef HAVE_AFINET6
struct sockaddr_in6 localaddr, remaddr;
char addr6[128];
extern struct aftype inet6_aftype;
#else
struct sockaddr_in localaddr, remaddr;
#endif
struct aftype *ap;
unsigned long rxq, txq, time_len, retr;
int num, local_port, rem_port, d, state;
int uid, timer_run, lnr = 0;
int refcnt;
int ino;
unsigned long ska;
struct passwd *pw;

again:
if (flag6 > 1)
goto doit;

if ((procinfo = fopen(flag6 ? "/proc/net/tcp6" : _PATH_PROCNET_TCP, "r")) == NULL) {
if (flag6)
goto doit;
if (errno != ENOENT) {
perror(_PATH_PROCNET_TCP);
return(-1);
}
if (flag_arg || flag_ver)
ESYSNOT("netstat","AF INET (tcp)");
if (flag_arg)
return(1);
else
return(0);
}

fgets(buffer, sizeof(buffer), procinfo);
while (fgets(buffer, sizeof(buffer), procinfo)) {
num = strlen(buffer)+1;
if ((line[lnr] = (char *)malloc(num)) != NULL) {
strcpy(line[lnr++], buffer);
if (flag_deb) fprintf(stderr, "%s", buffer);
}
}
(void) fclose(procinfo);
if (flag6++ == 0)
goto again;
doit:
lnr--;
while (lnr >= 0) {
#ifdef HAVE_AFINET6
num = sscanf(line[lnr--],
"%d: %[0-9A-Fa-f]:%X %[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %*d %d %d %lx\n",
&d, local_addr, &local_port,
rem_addr, &rem_port, &state,
&txq, &rxq, &timer_run, &time_len, &retr, &uid, &ino, &refcnt, &ska);

if (strlen(local_addr) > 8) {
__u32 ba[4];
__u16 * bb = (void*)ba;

sscanf(local_addr, "%08x%08x%08x%08x",
ba, ba+1, ba+2, ba+3);

sprintf(addr6, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
htons(bb[0]), htons(bb[1]), htons(bb[2]), htons(bb[3]),
htons(bb[4]), htons(bb[5]), htons(bb[6]), htons(bb[7]));
inet6_aftype.input(1, addr6, (struct sockaddr *)&localaddr);

sscanf(rem_addr, "%08x%08x%08x%08x",
ba, ba+1, ba+2, ba+3);

sprintf(addr6, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
htons(bb[0]), htons(bb[1]), htons(bb[2]), htons(bb[3]),
htons(bb[4]), htons(bb[5]), htons(bb[6]), htons(bb[7]));
inet6_aftype.input(1, addr6, (struct sockaddr *)&remaddr);
localaddr.sin6_family = AF_INET6;
remaddr.sin6_family = AF_INET6;
} else {
sscanf(local_addr, "%lX",
(unsigned long*)&((struct sockaddr_in *)&localaddr)->sin_addr.s_addr);
sscanf(rem_addr, "%lX",
(unsigned long*)&((struct sockaddr_in *)&remaddr)->sin_addr.s_addr);
((struct sockaddr *)&localaddr)->sa_family = AF_INET;
((struct sockaddr *)&remaddr)->sa_family = AF_INET;
}
if (flag_deb) fprintf(stderr, NLS_CATGETS(catfd, netstatSet, netstat_args,
"%s -> %d args"), line[lnr+1], num);
#else
num = sscanf(line[lnr--],
"%d: %lX:%X %lX:%X %X %lX:%lX %X:%lX %lX %d %*d %d %d %lx",
&d, (unsigned long*)&localaddr.sin_addr.s_addr, &local_port,
(unsigned long*)&remaddr.sin_addr.s_addr, &rem_port, &state,
&txq, &rxq, &timer_run, &time_len, &retr, &uid, &ino, &refcnt, &ska);
if (flag_deb) fprintf(stderr, NLS_CATGETS(catfd, netstatSet, netstat_args,
"%s -> %d args"), line[lnr+1], num);
localaddr.sin_family = AF_INET;
remaddr.sin_family = AF_INET;
#endif
if (num < 11) continue; /* 13 ? */
if ((ap = get_afntype(((struct sockaddr *)&localaddr)->sa_family)) == NULL) {
fprintf(stderr, NLS_CATGETS(catfd, netstatSet, netstat_netstat,
"netstat: unsupported address family %d !\n"),
((struct sockaddr *)&localaddr)->sa_family);
continue;
}
switch (state) {
case TCP_ESTABLISHED:
tcp_state = "ESTABLISHED";
break;

case TCP_SYN_SENT:
tcp_state = "SYN_SENT";
break;

case TCP_SYN_RECV:
tcp_state = "SYN_RECV";
break;

case TCP_FIN_WAIT1:
tcp_state = "FIN_WAIT1";
break;

case TCP_FIN_WAIT2:
tcp_state = "FIN_WAIT2";
break;

case TCP_TIME_WAIT:
tcp_state = "TIME_WAIT";
break;

case TCP_CLOSE:
tcp_state = "CLOSE";
break;

case TCP_CLOSING:
tcp_state = "CLOSING";
break;

case TCP_CLOSE_WAIT:
tcp_state = "CLOSE_WAIT";
break;

case TCP_LAST_ACK:
tcp_state = "LAST_ACK";
break;

case TCP_LISTEN:
tcp_state = "LISTEN";
time_len = 0;
retr = 0L;
rxq=0L;
txq=0L;
break;

default:
tcp_state = "UNKNOWN";
break;
}
strcpy(local_addr, ap->sprint((struct sockaddr *)&localaddr, flag_not));
strcpy(rem_addr, ap->sprint((struct sockaddr *)&remaddr, flag_not));
if (flag_all || rem_port) {
sprintf(buffer, "%s", get_sname(htons(local_port), "tcp", flag_not));
if ((strlen(local_addr) + strlen(buffer)) > 22) {
local_addr[22-strlen(buffer)] = '\0';
}
strcat(local_addr, ":");
strcat(local_addr, buffer);
sprintf(buffer, "%s",get_sname(htons(rem_port), "tcp", flag_not));
if ((strlen(rem_addr) + strlen(buffer)) > 22) {
rem_addr[22-strlen(buffer)] = '\0';
}
strcat(rem_addr, ":");
strcat(rem_addr, buffer);
timers[0] = '\0';
if (flag_opt) switch (timer_run) {
case 0:
sprintf(timers, NLS_CATGETS(catfd, netstatSet, netstat_off,
"off (0.00/%ld)"), retr);
break;

case 1:
sprintf(timers, NLS_CATGETS(catfd, netstatSet, netstat_on,
"on (%2.2f/%ld)"),
(double)time_len / 100, retr);
break;

case 2:
sprintf(timers, NLS_CATGETS(catfd, netstatSet, netstat_on,
"ka (%2.2f/%ld)"),
(double)time_len / 100, retr);
break;

case 3:
sprintf(timers, NLS_CATGETS(catfd, netstatSet, netstat_on,
"tw (%2.2f/%ld)"),
(double)time_len / 100, retr);
break;

default:
sprintf(timers, NLS_CATGETS(catfd, netstatSet, netstat_unkn,
"unkn-%d (%2.2f/%ld)"),
timer_run, (double)time_len / 100, retr);
break;
}
printf("tcp %6ld %6ld %-23s %-23s %-12s",
rxq, txq, local_addr, rem_addr, tcp_state);

if (flag_exp > 1) {
if (!flag_not && ((pw = getpwuid(uid)) != NULL))
printf("%-10s ", pw->pw_name);
else
printf("%-10d ",uid);
}

if (flag_opt) printf("timer %s", timers);
if (flag_opt) printf(" rc=%d ino=%d sk=%p", refcnt, ino, (void*)ska);
printf("\n");
}
}
return(0);
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/