Subject: pkg/29517: net/oidentd lookups of IPv6 connections fail on NetBSD 2.0
To: None <pkg-manager@netbsd.org, gnats-admin@netbsd.org,>
From: None <woodstoc@quina.moeckel.org>
List: pkgsrc-bugs
Date: 02/23/2005 22:51:00
>Number: 29517
>Category: pkg
>Synopsis: net/oidentd lookups of IPv6 connections fail on NetBSD 2.0
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: pkg-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Feb 23 22:51:00 +0000 2005
>Originator: Hans Rosenfeld
>Release: NetBSD 2.0
>Organization:
>Environment:
System: NetBSD quina.moeckel.org 2.0.1 NetBSD 2.0.1 (QUINA) #2: Tue Feb 22 21:17:45 CET 2005 woodstoc@quina.moeckel.org:/usr/obj/sys/arch/i386/compile/QUINA i386
Architecture: i386
Machine: i386
>Description:
Lookups of IPv6 connections fail on 2.0 returning NO-USER to all queries.
This is because oidentd still wants to use the tcb6 structure for those lookups,
but tcb6 was removed from netinet/tcp_subr.c (version 1.151, 2003/09/04 09:17:01),
tcbtable has to be used instead (as is already done for IPv4 connections).
>How-To-Repeat:
Install net/oidentd on a IPv6-capable machine running NetBSD 2.0 and try to query
it for IPv6 connections.
>Fix:
This patch to src/kernel/netbsd.c changes the IPv6 lookup routines to use tcbtable
instead of tcb6.
--- netbsd.c.orig 2003-02-12 03:15:59.000000000 +0100
+++ netbsd.c 2005-02-23 23:24:02.000000000 +0100
@@ -29,6 +29,7 @@
#include <errno.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/param.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <netinet/in.h>
@@ -99,7 +100,7 @@
kinfo->nl[N_TCB].n_name = "_tcbtable";
#ifdef WANT_IPV6
- kinfo->nl[N_TCB6].n_name = "_tcb6";
+ kinfo->nl[N_TCB6].n_name = "_tcbtable";
#else
kinfo->nl[N_TCB6].n_name = "_oidentd_nonexistent";
#endif
@@ -162,7 +163,7 @@
if (tcbtablep == NULL)
return (NULL);
- kpcbp = tcbtablep->inpt_queue.cqh_first;
+ kpcbp = (struct inpcb *) tcbtablep->inpt_queue.cqh_first;
while (kpcbp != (struct inpcb *) ktcbtablep) {
if (getbuf((u_long) kpcbp, &pcb, sizeof(struct inpcb)) == -1)
break;
@@ -185,7 +186,7 @@
return (pcb.inp_socket);
}
- kpcbp = pcb.inp_queue.cqe_next;
+ kpcbp = (struct inpcb *) pcb.inp_queue.cqe_next;
}
return (NULL);
@@ -327,35 +328,32 @@
** Returns NULL if no match.
*/
-static struct socket *getlist6( struct in6pcb *tcb6,
+static struct socket *getlist6( struct inpcbtable *tcbtablep,
+ struct inpcbtable *ktcbtablep,
in_port_t lport,
in_port_t fport,
const struct in6_addr *laddr,
const struct in6_addr *faddr)
{
- struct in6pcb *tcb6_cur, tcb6_temp;
+ struct in6pcb *kpcbp, pcb;
- if (tcb6 == NULL)
+ if (tcbtablep == NULL)
return (NULL);
- tcb6_cur = tcb6;
-
- memcpy(&tcb6_temp, tcb6, sizeof(tcb6_temp));
-
- do {
- if (tcb6_temp.in6p_fport == fport &&
- tcb6_temp.in6p_lport == lport &&
- IN6_ARE_ADDR_EQUAL(&tcb6_temp.in6p_laddr, laddr) &&
- IN6_ARE_ADDR_EQUAL(&tcb6_temp.in6p_faddr, faddr))
+ kpcbp = (struct in6pcb *) tcbtablep->inpt_queue.cqh_first;
+ while (kpcbp != (struct in6pcb *) ktcbtablep) {
+ if (getbuf((u_long) kpcbp, &pcb, sizeof(struct in6pcb)) == -1)
+ break;
+ if (pcb.in6p_fport == fport &&
+ pcb.in6p_lport == lport &&
+ IN6_ARE_ADDR_EQUAL(&pcb.in6p_laddr, laddr) &&
+ IN6_ARE_ADDR_EQUAL(&pcb.in6p_faddr, faddr))
{
- return (tcb6_temp.in6p_socket);
+ return (pcb.in6p_socket);
}
- tcb6_cur = tcb6_temp.in6p_next;
- if (getbuf((u_long) tcb6_cur, &tcb6_temp, sizeof(tcb6_temp)) == -1)
- break;
- } while ((u_long) tcb6_cur != kinfo->nl[N_TCB6].n_value);
-
+ kpcbp = (struct in6pcb *) pcb.in6p_queue.cqe_next;
+ }
return (NULL);
}
@@ -369,15 +367,16 @@
struct sockaddr_storage *faddr)
{
struct socket *sockp, sock;
- struct in6pcb tcb6;
+ struct inpcbtable tcbtable;
int ret;
- ret = getbuf(kinfo->nl[N_TCB6].n_value, &tcb6, sizeof(tcb6));
+ ret = getbuf(kinfo->nl[N_TCB6].n_value, &tcbtable, sizeof(tcbtable));
if (ret == -1)
return (-1);
- sockp = getlist6(&tcb6, lport, fport,
- &SIN6(laddr)->sin6_addr, &SIN6(faddr)->sin6_addr);
+ sockp = getlist6(&tcbtable,
+ (struct inpcbtable *) kinfo->nl[N_TCB6].n_value,
+ lport, fport, &SIN6(laddr)->sin6_addr, &SIN6(faddr)->sin6_addr);
if (sockp == NULL)
return (-1);