Package: sysvinit Version: 2.88 X-Debbugs-CC: "Navdeep Bhatia" <navd...@aristanetworks.com>, "Fred Xia" <f...@aristanetworks.com>, "Henrique de Moraes Holschuh" <h...@debian.org>,
*Bug Description:* The addr field of the output from utmpdump contains the ip address of the connection. This is obtained by calling inet_ntoa on the ut.ut_addr field (as depicted in the code below, utmpdump.c, Release 2.88). But in case the ip address is an IPV6 address, the output contains the wrong ip address (decimal value of first 4 octets only). This code should be updated to call inet_ntop and should be checked whether the ut_addr field contains IPV4 or IPV6 address. The check can be made either by checking ut_addr_v6[1:3] for zero (this is based on the assumption that login program zeroes out fields before filling utmp structure, though it is not mentioned in man entry for utmp) or by introducing a flag in the utmp structure that depicts whether the address field contains IPV4 or IPV6 address. void print_utline(struct utmp ut) { char *addr_string, *time_string; struct in_addr in; in.s_addr = ut.ut_addr; *addr_string = inet_ntoa(in); //Code statement causes issue in case of IPV6 addresses* time_string = timetostr(ut.ut_time); cleanse(ut.ut_id); cleanse(ut.ut_user); cleanse(ut.ut_line); cleanse(ut.ut_host); /* pid id user line host addr time */ printf("[%d] [%05d] [%-4.4s] [%-*.*s] [%-*.*s] [%-*.*s] [%-15.15s] [%-28.28s]\n", ut.ut_type, ut.ut_pid, ut.ut_id, 8, UT_NAMESIZE, ut.ut_user, 12, UT_LINESIZE, ut.ut_line, 20, UT_HOSTSIZE, ut.ut_host, addr_string, time_string); } *Solution:* a) One solution could be to look for ut_addr_v6[1:3] for zero. This is based on the assumption that login program zeroes out the fields before filling utmp structure. In this case the updated program would be: void print_utline(struct utmp ut) { char addr_string[INET6_ADDRSTRLEN], *time_string; int addr_family = AF_INET6; if( ut.ut_addr_v6[1] == 0 && ut.ut_addr_v6[2] == 0 && ut.ut_addr_v6[3] == 0 ) { addr_family = AF_INET; } if( NULL == inet_ntop( addr_family, ut.ut_addr_v6, addr_string, INET6_ADDRSTRLEN ) ) { perror( "inet_ntop" ); exit(EXIT_FAILURE); } time_string = timetostr(ut.ut_time); cleanse(ut.ut_id); cleanse(ut.ut_user); cleanse(ut.ut_line); cleanse(ut.ut_host); /* pid id user line host addr time */ printf("[%d] [%05d] [%-4.4s] [%-*.*s] [%-*.*s] [%-*.*s] [%-.45s] [%-28.28s]\n", ut.ut_type, ut.ut_pid, ut.ut_id, 8, UT_NAMESIZE, ut.ut_user, 12, UT_LINESIZE, ut.ut_line, 20, UT_HOSTSIZE, ut.ut_host, addr_string, time_string); } b) The other solution could be to introduce a new flag in utmp structure that fills whether the address is IPV4 or IPV6. Thanks. Regards, Navdeep