[csw-devel] SF.net SVN: gar:[17339] csw/mgar/pkg

dmichelsen at users.sourceforge.net dmichelsen at users.sourceforge.net
Fri Mar 9 13:19:14 CET 2012


Revision: 17339
          http://gar.svn.sourceforge.net/gar/?rev=17339&view=rev
Author:   dmichelsen
Date:     2012-03-09 12:19:14 +0000 (Fri, 09 Mar 2012)
Log Message:
-----------
pidentd/trunk: Initial commit

Added Paths:
-----------
    csw/mgar/pkg/pidentd/
    csw/mgar/pkg/pidentd/Makefile
    csw/mgar/pkg/pidentd/branches/
    csw/mgar/pkg/pidentd/tags/
    csw/mgar/pkg/pidentd/trunk/
    csw/mgar/pkg/pidentd/trunk/Makefile
    csw/mgar/pkg/pidentd/trunk/checksums
    csw/mgar/pkg/pidentd/trunk/files/
    csw/mgar/pkg/pidentd/trunk/files/pidentd-3.0.19-ipv6-20080101.diff
    csw/mgar/pkg/pidentd/trunk/files/pidentd.diff

Added: csw/mgar/pkg/pidentd/Makefile
===================================================================
--- csw/mgar/pkg/pidentd/Makefile	                        (rev 0)
+++ csw/mgar/pkg/pidentd/Makefile	2012-03-09 12:19:14 UTC (rev 17339)
@@ -0,0 +1,2 @@
+%:
+	$(MAKE) -C trunk $*


Property changes on: csw/mgar/pkg/pidentd/trunk
___________________________________________________________________
Added: svn:ignore
   + cookies
download
work


Added: svn:externals
   + gar https://gar.svn.sourceforge.net/svnroot/gar/csw/mgar/gar/v2


Added: csw/mgar/pkg/pidentd/trunk/Makefile
===================================================================
--- csw/mgar/pkg/pidentd/trunk/Makefile	                        (rev 0)
+++ csw/mgar/pkg/pidentd/trunk/Makefile	2012-03-09 12:19:14 UTC (rev 17339)
@@ -0,0 +1,50 @@
+# $Id$
+# TODO (release-critical prefixed with !, non release-critical with *)
+#
+NAME = pidentd
+VERSION = 3.0.19
+GARTYPE = v2
+CATEGORIES = utils
+
+DESCRIPTION = Portable ident daemon
+define BLURB
+endef
+
+MASTER_SITES = ftp://ftp.stack.nl/pub/users/johans/pidentd/
+DISTFILES  = $(DISTNAME).tar.gz
+
+PATCHDIRLEVEL = 0
+
+# From ftp://ftp.stack.nl/pub/users/johans/pidentd/
+PATCHFILES += pidentd-3.0.19-ipv6-20080101.diff.gz
+
+# From http://www.vlakno.cz/~rdivacky/pidentd.diff
+PATCHFILES += pidentd.diff
+
+VENDOR_URL = http://www.lysator.liu.se/~pen/pidentd/
+
+LICENSE = README
+
+PACKAGES += CSWpidentd
+SPKG_DESC_CSWmypkg = Portable ident daemon
+# PKGFILES is catchall
+RUNTIME_DEP_PKGS_CSWpidentd += CSWlibssl0-9-8
+
+REINPLACEMENTS += ignoreisa
+REINPLACE_MATCH_ignoreisa = ISA="
+REINPLACE_WITH_ignoreisa = ISA="IGNORE
+REINPLACE_FILES_ignoreisa += configure
+
+BUILD64 = 1
+ISAEXEC = 1
+
+# There is no testsuite
+TEST_SCRIPTS =
+
+INSTALL_OVERRIDE_VARS += mandir
+INSTALL_OVERRIDE_VAR_mandir = $(DESTDIR)$(mandir)
+INSTALL_OVERRIDE_VARS += sbindir
+INSTALL_OVERRIDE_VAR_sbindir = $(DESTDIR)$(sbindir)
+
+include gar/category.mk
+


Property changes on: csw/mgar/pkg/pidentd/trunk/Makefile
___________________________________________________________________
Added: svn:keywords
   + Id

Added: csw/mgar/pkg/pidentd/trunk/checksums
===================================================================
--- csw/mgar/pkg/pidentd/trunk/checksums	                        (rev 0)
+++ csw/mgar/pkg/pidentd/trunk/checksums	2012-03-09 12:19:14 UTC (rev 17339)
@@ -0,0 +1,2 @@
+887197d0c346b467449917666ee2a7a4  pidentd-3.0.19-ipv6-20080101.diff.gz
+ee8d3608a2590827cf8b55caeb1d7b93  pidentd-3.0.19.tar.gz

Added: csw/mgar/pkg/pidentd/trunk/files/pidentd-3.0.19-ipv6-20080101.diff
===================================================================
--- csw/mgar/pkg/pidentd/trunk/files/pidentd-3.0.19-ipv6-20080101.diff	                        (rev 0)
+++ csw/mgar/pkg/pidentd/trunk/files/pidentd-3.0.19-ipv6-20080101.diff	2012-03-09 12:19:14 UTC (rev 17339)
@@ -0,0 +1,1096 @@
+;; IPv6 patch for pidentd-3.0.18
+;; Sep 27, 2005 by Johan van Selst <johans at stack.nl>
+;; based on an earlier patch
+;; Feb 27, 2004 by Hajimu UMEMOTO <ume at mahoroba.org>
+;;
+--- configure.orig	Tue Sep 27 20:47:40 2005
++++ configure	Tue Sep 27 20:47:42 2005
+@@ -2292,6 +2292,13 @@ case "$host" in
+ 	*-aix4.2* | *-aix4.3*)
+ 		host_os=aix42
+ 		;;
++	*-freebsd2* | *-freebsd3*)
++		host_os=freebsd2
++		;;
++	*-freebsd* )
++		host_os=freebsd2
++		CPPFLAGS="$CPPFLAGS -DHAVE_IPV6=1"
++		;;
+ 	*-irix4*)
+ 		host_os=irix4
+ 		cat >>confdefs.h <<\_ACEOF
+--- src/conf.c.orig	Thu Jan 21 01:00:33 1999
++++ src/conf.c	Tue Sep 27 20:45:52 2005
+@@ -115,15 +115,13 @@
+ 		       path, line, arg);
+ 	}
+ 
+-#if 0 /* Enable when we have a str2addr() */
+ 	else if (strcasecmp(cp, "server:address") == 0)
+ 	{
+-	    if (str2addr(arg, &listen_address) < 0)
++	    if (str2addr(arg, &listen_addr) < 0)
+ 		syslog(LOG_ERR, "%s: %d: invalid address: %s",
+ 		       path, line, arg);
+ 	}
+-#endif
+-	
++
+ 	else if (strcasecmp(cp, "server:user") == 0)
+ 	{
+ 	    if (str2uid(arg, &server_uid, &server_gid) < 0)
+--- src/idecrypt.c.orig	Mon Apr 23 22:40:15 2001
++++ src/idecrypt.c	Tue Sep 27 20:45:52 2005
+@@ -90,14 +90,14 @@
+ 
+ 
+ static char *
+-decrypt_packet(unsigned char *packet)
++decrypt_packet(unsigned char *packet, int len)
+ {
+     union data r;
+-    int i, j;
++    int i, j, count;
+     time_t date_in_sec;
+     char *date_in_ascii;
+     char keybuf[1024+1];
+-    char buf1[32], buf2[32];
++    char buf1[40], buf2[40];
+     struct sockaddr_gen ip_local, ip_remote;
+     int keyfile_fd;
+     des_cblock key_bin;
+@@ -120,32 +120,29 @@
+ 	keybuf[sizeof(keybuf)-1] = '\0';
+ 	des_string_to_key(keybuf, &key_bin);
+ 	des_set_key(&key_bin, sched);
+-	
+-	
+-	for (i = 0, j = 0; i < 24; i += 3, j += 4)
++
++	count = (len == 32) ? 24 : 48;
++	for (i = 0, j = 0; i < count; i += 3, j += 4)
+ 	{
+ 	    r.chars[i  ] = (to_bin[packet[j  ]] << 2) + (to_bin[packet[j+1]] >> 4);
+ 	    r.chars[i+1] = (to_bin[packet[j+1]] << 4) + (to_bin[packet[j+2]] >> 2);
+ 	    r.chars[i+2] = (to_bin[packet[j+2]] << 6) + (to_bin[packet[j+3]]);
+ 	}
+-    
+-	des_ecb_encrypt((des_cblock *)&(r.longs[4]),
+-			(des_cblock *)&(r.longs[4]),
+-			sched, DES_DECRYPT);
+-	r.longs[4] ^= r.longs[2];
+-	r.longs[5] ^= r.longs[3];
+-	
+-	des_ecb_encrypt((des_cblock *)&(r.longs[2]),
+-			(des_cblock *)&(r.longs[2]),
+-			sched, DES_DECRYPT);
+-	
+-	r.longs[2] ^= r.longs[0];
+-	r.longs[3] ^= r.longs[1]; 
++
++	count = (len == 32) ? 2 : 8;
++	for (i = count; i >= 0; i -= 2) {
++	    des_ecb_encrypt((des_cblock *)&(r.longs[i+2]),
++			    (des_cblock *)&(r.longs[i+2]),
++			    sched, DES_DECRYPT);
++	    r.longs[i+2] ^= r.longs[i  ];
++	    r.longs[i+3] ^= r.longs[i+1];
++	}
+ 	des_ecb_encrypt((des_cblock *)&(r.longs[0]),
+ 			(des_cblock *)&(r.longs[0]),
+ 			sched, DES_DECRYPT);
+ 
+-	for (i = 1; i < 6; i++)
++	count = (len == 32) ? 6 : 12;
++	for (i = 1; i < count; i++)
+ 	{
+ 	    r.longs[0] ^= r.longs[i];
+ 	}
+@@ -159,9 +156,37 @@
+   GoodKey:
+     date_in_sec = ntohl(r.fields.date);
+     date_in_ascii = ctime(&date_in_sec);
+-    
++
++#ifdef HAVE_IPV6
++    if (len ==32) {
++	ip_local.sg_family = ip_remote.sg_family = AF_INET;
++#ifdef SIN6_LEN
++	ip_local.sg_sa.sa_len = sizeof(struct sockaddr_in);
++	ip_remote.sg_sa.sa_len = sizeof(struct sockaddr_in);
++#endif
++	ip_local.sg_sin.sin_addr.s_addr = r.fields.ip_local;
++	ip_remote.sg_sin.sin_addr.s_addr = r.fields.ip_remote;
++	ip_local.sg_sin.sin_port = r.fields.port_local;
++	ip_remote.sg_sin.sin_port = r.fields.port_remote;
++    } else {
++	ip_local.sg_family = ip_remote.sg_family = AF_INET6;
++#ifdef SIN6_LEN
++	ip_local.sg_sa.sa_len = sizeof(struct sockaddr_in6);
++	ip_remote.sg_sa.sa_len = sizeof(struct sockaddr_in6);
++#endif
++	memcpy(&ip_local.sg_sin6.sin6_addr, &r.fields6.ip_local,
++	       sizeof(struct in6_addr));
++	memcpy(&ip_remote.sg_sin6.sin6_addr, &r.fields6.ip_remote,
++	       sizeof(struct in6_addr));
++	ip_local.sg_sin6.sin6_port = r.fields6.port_local;
++	ip_remote.sg_sin6.sin6_port = r.fields6.port_remote;
++    }
++#else
+     memcpy(SGADDRP(ip_local), &(r.fields.ip_local), sizeof(ip_local));
+     memcpy(SGADDRP(ip_remote), &(r.fields.ip_remote), sizeof(ip_remote));
++    SGPORT(ip_local) = r.fields.port_local;
++    SGPORT(ip_remote) = r.fields.port_remote;
++#endif
+ 
+     /* FIXME: uid_t isn't necessarily short.  */
+ #ifdef HAVE_SNPRINTF
+@@ -173,10 +198,10 @@
+ 	    date_in_ascii,
+ 	    ntohs(r.fields.uid),
+ 	    s_inet_ntox(&ip_local, buf1, sizeof(buf1)),
+-	    (unsigned) ntohs(r.fields.port_local),
++	    (unsigned) ntohs(SGPORT(ip_local)),
+ 	    s_inet_ntox(&ip_remote, buf2, sizeof(buf2)),
+-	    (unsigned) ntohs(r.fields.port_remote));
+-    
++	    (unsigned) ntohs(SGPORT(ip_remote)));
++
+     close(keyfile_fd);
+     return readable;
+ }
+@@ -187,7 +212,7 @@
+ {
+     int c;
+     int i;
+-    char buf[32];
++    char buf[64];
+     char *result;
+ 
+     
+@@ -204,32 +229,38 @@
+ 	    putchar(c);
+ 	    continue;
+ 	}
+-	
+-	for (i = 0; i < 32; i++)
++
++	for (i = 0; i < 64; i++)
+ 	{
+ 	    c = getc(f);
+ 	    if (c == EOF || c < 0 || c > 255)
+ 		break;
++#ifdef HAVE_IPV6
++	    if (i == 32 && c == ']')	/* `]' is not base64 char */
++		break;
++#else
++	    if (i == 32)
++		break;
++#endif
+ 	    if (!is_base_64[c])
+ 		break;
+ 	    buf[i] = c;
+ 	}
+-	
+-	if (i == 32)
++
++	if (i == 64)
+ 	    c = getc(f);
+-	
+-	if (i < 32 || c != ']')
++
++	if ((i != 32 && i != 64) || c != ']')
+ 	{
+ 	    putchar('[');
+ 	    fwrite(buf, 1, i, stdout);
+ 	    goto Same;
+ 	}
+-	
+-	
+-	if ((result = decrypt_packet((unsigned char *) buf)) == NULL)
++
++	if ((result = decrypt_packet((unsigned char *) buf, i)) == NULL)
+ 	{
+ 	    putchar('[');
+-	    fwrite(buf, 1, 32, stdout);
++	    fwrite(buf, 1, i, stdout);
+ 	    putchar(']');
+ 	}
+ 	else
+--- src/k_freebsd2.c.orig	Tue Sep 27 20:26:06 2005
++++ src/k_freebsd2.c	Tue Sep 27 20:26:06 2005
+@@ -0,0 +1,293 @@
++/*
++** freebsd2.c - FreeBSD kernel access functions.
++**
++** Copyright (c) 1997      Peter Eriksson <pen at lysator.liu.se>
++** Copyright (c) 2000-2004 Hajimu UMEMOTO <ume at mahoroba.org>
++**
++** This program is free software; you can redistribute it and/or
++** modify it as you wish - as long as you don't claim that you wrote
++** it.
++**
++** This program is distributed in the hope that it will be useful,
++** but WITHOUT ANY WARRANTY; without even the implied warranty of
++** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
++*/
++
++#include "config.h"
++
++#include <sys/param.h>
++#include <sys/types.h>
++#include <sys/sysctl.h>
++#include <sys/socket.h>
++#include <sys/user.h>
++#if __FreeBSD_version >= 800000
++# define _WANT_FILE
++# include <sys/file.h>
++#else	/* __FreeBSD < 8 */
++# define _KERNEL
++# include <sys/file.h>
++# undef _KERNEL
++#endif	/* __FreeBSD__ */
++#include <netinet/in.h>
++#include <netinet/in_pcb.h>
++#include <fcntl.h>
++#include <kvm.h>
++#include <nlist.h>
++#include <stdio.h>
++#include <syslog.h>
++#include <string.h>
++
++#include "pidentd.h"
++
++struct kainfo {
++    kvm_t *kd;
++    int nfile;
++    struct nlist nl[3];
++};
++
++static int getbuf(struct kainfo *, u_long, char *, u_int, char *);
++static struct socket *getlist(struct kainfo *, struct inpcbhead *,
++			      struct sockaddr_gen *, struct sockaddr_gen *);
++
++int
++ka_init(void)
++{
++    return 0;
++}
++
++int
++ka_open(void **misc)
++{
++    struct kainfo *kp = s_malloc(sizeof(struct kainfo));
++
++    /*
++    ** Open the kernel memory device
++    */
++    kp->kd = (kvm_t *)kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL);
++    if (kp->kd == NULL)
++    {
++	syslog(LOG_ERR, "kvm_open: %m");
++	s_free(kp);
++	return -1;
++    }
++
++#define N_TCB	0
++#define N_BTEXT	1
++    kp->nl[N_TCB].n_name = "_tcb";
++    kp->nl[N_BTEXT].n_name = "_btext";
++    kp->nl[2].n_name = "";
++    /*
++    ** Extract offsets to the needed variables in the kernel
++    */
++    if (kvm_nlist(kp->kd, kp->nl) < 0)
++    {
++	syslog(LOG_ERR, "kvm_nlist: %m");
++	kvm_close(kp->kd);
++	s_free(kp);
++	return -1;
++    }
++
++    *misc = (void *)kp;
++    return 0;
++}
++
++/*
++** Get a piece of kernel memory with error handling.
++** Returns 1 if call succeeded, else 0 (zero).
++*/
++static int
++getbuf(struct kainfo *kp, unsigned long addr, char *buf, unsigned int len,
++       char *what)
++{
++    if (addr < kp->nl[N_BTEXT].n_value ||		/* Overkill.. */
++	addr >= (unsigned long)0xFFC00000 ||
++	(addr + len) < kp->nl[N_BTEXT].n_value ||
++	(addr + len) >= (unsigned long)0xffc00000)
++    {
++	syslog(LOG_ERR,
++	       "getbuf: bad address (%08x not in %08x-0xFFC00000) - %s",
++	       addr, kp->nl[N_BTEXT].n_value, what);
++	return 0;
++    }
++
++    if (kvm_read(kp->kd, addr, buf, len) < 0)
++    {
++	syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
++	       addr, len, what);
++	return 0;
++    }
++
++    return 1;
++}
++
++/*
++** Traverse the inpcb list until a match is found.
++** Returns NULL if no match.
++*/
++static struct socket *
++getlist(struct kainfo *kp, struct inpcbhead *pcbhead,
++	struct sockaddr_gen *remote, struct sockaddr_gen *local)
++{
++    struct inpcb *head, pcbp;
++    struct sockaddr_gen fsg, lsg;
++    int fam, fport, lport, alen;
++    char *faddr, *laddr, *paddr;
++
++#ifdef HAVE_IPV6
++    if (SGFAM(*remote) == AF_INET6 &&
++	IN6_IS_ADDR_V4MAPPED(&remote->sg_sin6.sin6_addr))
++    {
++	memset(&fsg, 0, sizeof(fsg));
++	fsg.sg_family = AF_INET;
++	fsg.sg_sin.sin_port = remote->sg_sin6.sin6_port;
++	memcpy(&fsg.sg_sin.sin_addr, &remote->sg_sin6.sin6_addr.s6_addr[12],
++	       sizeof(fsg.sg_sin.sin_addr));
++	remote = &fsg;
++    }
++    if (SGFAM(*local) == AF_INET6 &&
++	IN6_IS_ADDR_V4MAPPED(&local->sg_sin6.sin6_addr))
++    {
++	memset(&lsg, 0, sizeof(fsg));
++	lsg.sg_family = AF_INET;
++	lsg.sg_sin.sin_port = local->sg_sin6.sin6_port;
++	memcpy(&lsg.sg_sin.sin_addr, &local->sg_sin6.sin6_addr.s6_addr[12],
++	       sizeof(lsg.sg_sin.sin_addr));
++	local = &lsg;
++    }
++    if ((fam = SGFAM(*remote)) != SGFAM(*local))
++	return NULL;
++#endif
++    faddr = (char *)SGADDRP(*remote);
++    laddr = (char *)SGADDRP(*local);
++    fport = SGPORT(*remote);
++    lport = SGPORT(*local);
++
++    for (head = pcbhead->lh_first; head != NULL;
++	 head = pcbp.inp_list.le_next)
++    {
++	if (!getbuf(kp, (u_long)head, (char *)&pcbp, sizeof(struct inpcb),
++		    "tcblist"))
++	    break;
++#ifdef HAVE_IPV6
++	if (pcbp.inp_vflag & INP_IPV4)
++	{
++	    if (fam != AF_INET)
++		continue;
++	    paddr = (char *)&pcbp.inp_faddr;
++	    alen = sizeof(struct in_addr);
++	}
++	else if (pcbp.inp_vflag & INP_IPV6)
++	{
++	    if (fam != AF_INET6)
++		continue;
++	    paddr = (char *)&pcbp.in6p_faddr;
++	    alen = sizeof(struct in6_addr);
++	}
++	else
++	    continue;
++#else
++	paddr = (char *)&pcbp.inp_faddr;
++	alen = sizeof(struct in_addr);
++#endif
++	if (memcmp(paddr, faddr, alen) == 0 && pcbp.inp_fport == fport &&
++	    pcbp.inp_lport == lport)
++	    return pcbp.inp_socket;
++    }
++
++    return NULL;
++}
++
++#if __FreeBSD_version < 500000
++#define ki_fd		kp_proc.p_fd
++#define ki_ruid		kp_eproc.e_pcred.p_ruid
++#define ki_uid		kp_eproc.e_ucred.cr_uid
++#endif
++
++/*
++** Return the user number for the connection owner
++*/
++int
++ka_lookup(void *vp, struct kernel *kp)
++{
++    struct inpcbhead tcb;
++    struct socket *sockp;
++    struct kinfo_proc *kgp;
++    int i, nentries;
++    struct kainfo *kip = vp;
++
++    kgp = kvm_getprocs(kip->kd, KERN_PROC_ALL, 0, &nentries);
++    if (kgp == NULL)
++    {
++	syslog(LOG_ERR, "kvm_getprocs: %m");
++	return -1;
++    }
++
++    /* -------------------- TCP PCB LIST -------------------- */
++    if (!getbuf(kip, kip->nl[N_TCB].n_value, (char*)&tcb, sizeof(tcb), "tcb"))
++	return -1;
++
++    if ((sockp = getlist(kip, &tcb, &kp->remote, &kp->local)) == NULL)
++	return 0;
++
++    /*
++    ** Locate the file descriptor that has the socket in question
++    ** open so that we can get the 'ucred' information
++    */
++    for (i = 0; i < nentries; i++)
++    {
++	if (kgp[i].ki_fd != NULL)
++	{
++	    struct filedesc	pfd;
++	    struct file **ofiles, ofile;
++	    int j;
++
++	    if (!getbuf(kip, (u_long)kgp[i].ki_fd, (char *)&pfd, sizeof(pfd),
++			"pfd"))
++		return -1;
++
++	    ofiles = (struct file **)s_malloc(pfd.fd_nfiles *
++					      sizeof(struct file *));
++	    if (!ofiles)
++	    {
++		syslog(LOG_ERR, "s_malloc failed");
++		return -1;
++	    }
++
++	    if (!getbuf(kip, (u_long)pfd.fd_ofiles, (char *)ofiles,
++			pfd.fd_nfiles * sizeof(struct file *), "ofiles"))
++	    {
++		s_free(ofiles);
++		return -1;
++	    }
++
++	    for (j = 0; j < pfd.fd_nfiles; j++)
++	    {
++		if (!ofiles[j])	/* might be sparse */
++		    continue;
++
++		if (!getbuf(kip, (u_long)ofiles[j], (char *)&ofile,
++			    sizeof(struct file), "ofile"))
++		{
++		    s_free(ofiles);
++		    return -1;
++		}
++
++		if (ofile.f_count == 0)
++		    continue;
++
++		if (ofile.f_type == DTYPE_SOCKET &&
++		    (struct socket *)ofile.f_data == sockp)
++		{
++		    kp->ruid = kgp[i].ki_ruid;
++		    kp->euid = kgp[i].ki_uid;
++		    s_free(ofiles);
++		    return 1;
++		}
++	    }
++
++	    s_free(ofiles);
++	}
++    }
++
++    return -1;
++}
+--- src/kernel.c.orig	Sun Jun 13 09:47:52 2004
++++ src/kernel.c	Tue Sep 27 20:45:52 2005
+@@ -81,7 +81,7 @@
+ {
+     struct kernel *kp;
+     int attempt;
+-    char buf1[32];
++    char buf1[40];
+ 
+     
+     if (debug)
+--- src/main.c.orig	Wed Jan  8 22:57:05 2003
++++ src/main.c	Tue Sep 27 20:45:52 2005
+@@ -133,6 +133,8 @@
+     int log_header = 0;
+     
+ 
++    SGINIT(listen_addr);
++
+     if (argv[0] != NULL)
+     {
+ 	char *cp;
+@@ -166,7 +168,7 @@
+     conf_parse(PATH_CFGFILE, 1);
+ 
+     
+-    while ((c = getopt(argc, argv, "lNVEdhbwiIemnop:u:g:t:C:P:K:L:")) != -1)
++    while ((c = getopt(argc, argv, "lNVEdhbwiIemnop:a:u:g:t:C:P:K:L:")) != -1)
+ 	switch (c)
+ 	{
+ #ifdef HAVE_LIBDES
+@@ -231,6 +233,13 @@
+ 	    }
+ 	    break;
+ 
++	case 'a':
++	    if (str2addr(optarg, &listen_addr) < 0)
++		return EXIT_FAILURE;
++	    if (SGPORT(listen_addr) != 0)
++		listen_port = ntohs(SGPORT(listen_addr));
++	    break;
++
+ 	  case 't':
+ 	    if (str2int(optarg, &request_timeout) < 0)
+ 	    {
+@@ -324,6 +333,9 @@
+ 	    
+ 	    return EXIT_FAILURE;
+ 	}
++
++    if (SGFAM(listen_addr) != AF_UNSPEC)
++	SGPORT(listen_addr) = htons(listen_port);
+ 
+     if (debug)
+ 	program_header(stderr);
+--- src/pdes.c.orig	Sun May 21 21:07:05 2000
++++ src/pdes.c	Tue Sep 27 20:45:52 2005
+@@ -109,13 +109,14 @@
+ 
+ 
+ int
+-pdes_encrypt(struct kernel *kp,
+-	     char result[33])
++pdes_encrypt(struct kernel *kp, char result[PDES_BUFSIZ])
+ {
+     union data r;
+     int i, j;
+     time_t bt;
+-    
++    int family = AF_INET;
++    int count;
++
+ 
+     r.fields.random = s_random();
+     /* FIXME: uid_t isn't necessarily short.  */
+@@ -126,39 +127,62 @@
+ 
+     time(&bt);
+     r.fields.date = htonl(bt);
+-       
++
++#ifdef HAVE_IPV6
++    if (SGFAM(kp->remote) == AF_INET) {
++	r.fields.ip_local    = kp->local.sg_sin.sin_addr.s_addr;
++	r.fields.ip_remote   = kp->remote.sg_sin.sin_addr.s_addr;
++	r.fields.port_local  = kp->local.sg_sin.sin_port;
++	r.fields.port_remote = kp->remote.sg_sin.sin_port;
++    } else if (IN6_IS_ADDR_V4MAPPED(&kp->remote.sg_sin6.sin6_addr)) {
++	memcpy(&r.fields.ip_local, &kp->local.sg_sin6.sin6_addr.s6_addr[12],
++	       sizeof(r.fields.ip_local));
++	memcpy(&r.fields.ip_remote, &kp->remote.sg_sin6.sin6_addr.s6_addr[12],
++	       sizeof(r.fields.ip_remote));
++	r.fields.port_local  = kp->local.sg_sin6.sin6_port;
++	r.fields.port_remote = kp->remote.sg_sin6.sin6_port;
++    } else {
++	family = AF_INET6;
++	memcpy(r.fields6.ip_local, &kp->local.sg_sin6.sin6_addr,
++	       sizeof(r.fields6.ip_local));
++	memcpy(r.fields6.ip_remote, &kp->remote.sg_sin6.sin6_addr,
++	       sizeof(r.fields6.ip_remote));
++	r.fields6.port_local  = kp->local.sg_sin6.sin6_port;
++	r.fields6.port_remote = kp->remote.sg_sin6.sin6_port;
++    }
++#else
+     r.fields.ip_local    = kp->local.sin_addr.s_addr;
+     r.fields.ip_remote   = kp->remote.sin_addr.s_addr;
+     r.fields.port_local  = kp->local.sin_port;
+     r.fields.port_remote = kp->remote.sin_port;
++#endif
+ 
+     r.fields.checksum = 0;
+-    for (i = 1; i < 6; i++)
++    count = (family == AF_INET) ? 6 : 12;
++    for (i = 1; i < count; i++)
+ 	r.longs[0] ^= r.longs[i];
+ 
+     des_ecb_encrypt((des_cblock *)&(r.longs[0]), (des_cblock *)&(r.longs[0]),
+ 		    sched, DES_ENCRYPT);
+-    
+-    r.longs[2] ^= r.longs[0];
+-    r.longs[3] ^= r.longs[1];
+-    
+-    des_ecb_encrypt((des_cblock *)&(r.longs[2]), (des_cblock *)&(r.longs[2]),
+-		    sched, DES_ENCRYPT);
+-    
+-    r.longs[4] ^= r.longs[2];
+-    r.longs[5] ^= r.longs[3];
+-    
+-    des_ecb_encrypt((des_cblock *)&(r.longs[4]), (des_cblock *)&(r.longs[4]),
+-		    sched, DES_ENCRYPT);
+ 
+-    for (i = 0, j = 0; i < 24; i+=3, j+=4)
++    count = (family == AF_INET) ? 4 : 10;
++    for (i = 0; i < count; i += 2) {
++	r.longs[i+2] ^= r.longs[i  ];
++	r.longs[i+3] ^= r.longs[i+1];
++
++	des_ecb_encrypt((des_cblock *)&(r.longs[i+2]),
++			(des_cblock *)&(r.longs[i+2]), sched, DES_ENCRYPT);
++    }
++
++    count = (family == AF_INET) ? 24 : 48;
++    for (i = 0, j = 0; i < count; i+=3, j+=4)
+     {
+ 	result[j  ] = to_asc[63 & (r.chars[i  ] >> 2)];
+ 	result[j+1] = to_asc[63 & ((r.chars[i  ] << 4) + (r.chars[i+1] >> 4))];
+ 	result[j+2] = to_asc[63 & ((r.chars[i+1] << 2) + (r.chars[i+2] >> 6))];
+ 	result[j+3] = to_asc[63 & (r.chars[i+2])];
+     }
+-    result[32] = '\0';
++    result[(family == AF_INET) ? 32 : 64] = '\0';
+ 
+     return 0;
+ }
+--- src/pdes.h.orig	Thu Jan 21 00:59:26 1999
++++ src/pdes.h	Tue Sep 27 20:45:52 2005
+@@ -28,17 +28,44 @@
+     uint16_t port_remote;
+ };
+ 
++#ifdef HAVE_IPV6
++struct info6
++{
++    uint32_t checksum;
++    uint16_t random;
++    /* FIXME: uid_t isn't necessarily short.  */
++    uint16_t uid;
++    uint32_t date;
++    uint32_t ip_local[4];
++    uint32_t ip_remote[4];
++    uint16_t port_local;
++    uint16_t port_remote;
++};
++#endif
++
+ typedef union data
+ {
+     struct info   fields;
++#ifdef HAVE_IPV6
++    struct info6  fields6;
++    uint32_t        longs[12];
++    unsigned char chars[48];
++#else
+     uint32_t        longs[6];
+     unsigned char chars[24];
++#endif
+ } data;
+ 
++#ifdef HAVE_IPV6
++#define PDES_BUFSIZ	65
++#else
++#define PDES_BUFSIZ	33
++#endif
++
+ struct kernel;
+ 
+ extern int pdes_init(char *keyfile);
+-extern int pdes_encrypt(struct kernel *kp, char buffer[33]);
++extern int pdes_encrypt(struct kernel *kp, char buffer[PDES_BUFSIZ]);
+ extern int pdes_decrypt(void);
+      
+ #endif
+--- src/send.c.orig	Mon Nov 25 08:46:11 2002
++++ src/send.c	Tue Sep 27 20:45:52 2005
+@@ -67,7 +67,7 @@
+ 	   struct sockaddr_gen *remote_addr)
+ {
+     char buf[1024];
+-    char buf2[32];
++    char buf2[40];
+ 
+     
+     s_snprintf(buf, sizeof(buf),
+@@ -86,7 +86,7 @@
+ send_result(int fd,
+ 	    struct kernel *kp)
+ {
+-    char buf[2048], pbuf[2048], buf2[32];
++    char buf[2048], pbuf[2048], buf2[40];
+     struct passwd pwb, *pp = NULL;
+     uid_t uid;
+ 
+@@ -118,7 +118,7 @@
+ #ifdef HAVE_LIBDES
+     if (encrypt_flag)
+     {
+-	char buffer[33];
++	char buffer[PDES_BUFSIZ];
+ 
+ 	pdes_encrypt(kp, buffer);
+ 	s_snprintf(buf, sizeof(buf),
+@@ -167,7 +167,7 @@
+ send_version(int fd,
+ 	     struct sockaddr_gen *remote_addr)
+ {
+-    char buf[1024], buf2[32];
++    char buf[1024], buf2[40];
+     
+     s_snprintf(buf, sizeof(buf),
+ 	     "0 , 0 : X-VERSION : pidentd %s for %s (%s %s)\r\n",
+--- src/server.c.orig	Fri Mar 22 22:42:33 2002
++++ src/server.c	Tue Sep 27 20:45:52 2005
+@@ -25,11 +25,13 @@
+ 
+ 
+ 
+-int listen_sock = -1;
++int listen_sock;
+ int listen_port = IPPORT_IDENT;
+-int listen_addr = INADDR_ANY;
++struct sockaddr_gen listen_addr;
+ int listen_backlog = 256;
+ 
++static int listen_fd[2] = { -1, -1 };
++static int listen_nfds = 0;
+ 
+ static int
+ unlimit_nofile(void)
+@@ -58,14 +60,49 @@
+ }
+ 
+ 
++static int
++server_socket(void)
++{
++    static int one = 1;
++
++
++    listen_fd[listen_nfds] = socket(SGFAM(listen_addr), SOCK_STREAM, 0);
++    if (listen_fd[listen_nfds] < 0)
++    {
++	syslog(LOG_DEBUG, "socket(AF_INET, SOCK_STREAM) failed: %m");
++	return -1;
++    }
++
++    (void) setsockopt(listen_fd[listen_nfds], SOL_SOCKET, SO_REUSEADDR,
++		      (void *) &one, sizeof(one));
++#ifdef IPV6_V6ONLY
++    if (SGFAM(listen_addr) == AF_INET6)
++	(void) setsockopt(listen_fd[listen_nfds], IPPROTO_IPV6, IPV6_V6ONLY,
++			  (void *) &one, sizeof(one));
++#endif
++
++    if (bind(listen_fd[listen_nfds], (struct sockaddr *) &listen_addr,
++	     SGSOCKSIZE(listen_addr)) < 0)
++    {
++	syslog(LOG_DEBUG, "bind(port=%d) failed: %m",
++	       ntohs(SGPORT(listen_addr)));
++	s_close(listen_fd[listen_nfds]);
++	listen_fd[listen_nfds] = -1;
++	return -1;
++    }
++
++    listen_nfds++;
++
++    return 0;
++}
++
++
+ int
+ server_init(void)
+ {
+-    static int one = 1;
+-    int nofile;
+-    struct sockaddr_in sin;
+-    
+-    
++    int nofile, i, err = 1;
++
++
+     /*
+     ** Increase the number of available file descriptors
+     ** to the maximum possible.
+@@ -77,34 +114,49 @@
+ 
+     if (listen_sock < 0)
+     {
+-	listen_sock = socket(AF_INET, SOCK_STREAM, 0);
+-	if (listen_sock < 0)
++	if (SGFAM(listen_addr) == AF_UNSPEC)
+ 	{
+-	    syslog(LOG_ERR, "socket(AF_INET, SOCK_STREAM) failed: %m");
+-	    return -1;
++#ifdef HAVE_IPV6
++	    SGFAM(listen_addr) = AF_INET6;
++	    SGPORT(listen_addr) = htons(listen_port);
++	    SGSETLEN(listen_addr);
++	    err = (server_socket() < 0);
++	    SGINIT(listen_addr);
++#endif
++	    SGFAM(listen_addr) = AF_INET;
++	    SGPORT(listen_addr) = htons(listen_port);
++	    SGSETLEN(listen_addr);
++	    err = (server_socket() < 0 && err);
+ 	}
+-
+-	(void) setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
+-		   (void *) &one, sizeof(one));
+-	
+-	memset(&sin, 0, sizeof(sin));
+-	sin.sin_family = AF_INET;
+-	sin.sin_addr.s_addr = htonl(listen_addr);
+-	sin.sin_port = htons(listen_port);
+-
+-	if (bind(listen_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0)
+-	{
+-	    syslog(LOG_ERR, "bind(port=%d) failed: %m",
+-		   listen_port);
++	else
++	    err = (server_socket() < 0);
++	if (err) {
++	    syslog(LOG_ERR, "server_init: no socket is available");
+ 	    return -1;
+ 	}
+     }
++    else
++    {
++	listen_fd[0] = listen_sock;
++	listen_nfds++;
++    }
+ 
+     /* We do this outside of the 'if' statement to support
+        some broken 'inetd' daemons... */
+-    if (listen(listen_sock, listen_backlog) < 0)
++    err = 1;
++    for (i = 0; i < listen_nfds; i++)
+     {
+-	syslog(LOG_ERR, "listen(backlog=%d) failed: %m", listen_backlog);
++	if (listen(listen_fd[i], listen_backlog) < 0)
++	{
++	    syslog(LOG_DEBUG, "listen(backlog=%d) failed: %m", listen_backlog);
++	    s_close(listen_fd[i]);
++	    listen_fd[i] = -1;
++	}
++	else
++	    err = 0;
++    }
++    if (err) {
++	syslog(LOG_ERR, "server_init: failed to listen socket");
+ 	return -1;
+     }
+ 
+@@ -115,28 +167,54 @@
+ int
+ server_run(void)
+ {
+-    int fd;
+-    
++    fd_set readfds;
++    int fd, nfds, maxfd = -1, i;
++
++    for (i = 0; i < listen_nfds; i++)
++	if (listen_fd[i] >= 0)
++	    if (maxfd < listen_fd[i])
++		maxfd = listen_fd[i];
++    if (maxfd < 0)
++	return -1;
++
+     while (1)
+     {
+-	fd = s_accept(listen_sock, NULL, NULL);
+-	if (fd < 0)
+-	{
+-	    syslog(LOG_ERR, "accept() failed: %m");
+-	    
+-	    switch (errno)
+-	    {
+-	      case EBADF:
+-	      case EMFILE:
+-	      case ENODEV:
+-	      case ENOMEM:
+-	      case ENOTSOCK:
+-	      case EOPNOTSUPP:
+-	      case EWOULDBLOCK:
++	FD_ZERO(&readfds);
++	for (i = 0; i < listen_nfds; i++)
++	    if (listen_fd[i] >= 0)
++		FD_SET(listen_fd[i], &readfds);
++	if (maxfd < 0)
++	    return -1;
++	nfds = select(maxfd + 1, &readfds, NULL, NULL, NULL);
++	if (listen_nfds <= 0) {
++	    if (nfds < 0 && errno != EINTR) {
++		syslog(LOG_ERR, "select() failed: %m");
+ 		return -1;
+ 	    }
++	    continue;
+ 	}
++	for (i = 0; i < listen_nfds; i++) {
++	    if (FD_ISSET(listen_fd[i], &readfds)) {
++		fd = s_accept(listen_fd[i], NULL, NULL);
++		if (fd < 0)
++		{
++		    syslog(LOG_ERR, "accept() failed: %m");
++
++		    switch (errno)
++		    {
++		    case EBADF:
++		    case EMFILE:
++		    case ENODEV:
++		    case ENOMEM:
++		    case ENOTSOCK:
++		    case EOPNOTSUPP:
++		    case EWOULDBLOCK:
++			return -1;
++		    }
++		}
+ 
+-	request_run(fd, 0);
++		request_run(fd, 0);
++	    }
++	}
+     }
+ }
+--- src/server.h.orig	Thu Jan 21 00:59:27 1999
++++ src/server.h	Tue Sep 27 20:26:06 2005
+@@ -17,7 +17,7 @@
+ 
+ extern int listen_sock;
+ extern int listen_port;
+-extern int listen_addr;
++extern struct sockaddr_gen listen_addr;
+ extern int listen_backlog;
+ 
+ 
+--- src/sockaddr.h.orig	Fri Jan 14 23:46:31 2000
++++ src/sockaddr.h	Tue Sep 27 20:45:52 2005
+@@ -48,6 +48,14 @@
+ #define SGADDRP(sag)	((SGFAM(sag) == AF_INET6 ? \
+                             (char *) &(sag).sg_sin6.sin6_addr : \
+ 			    (char *) &(sag).sg_sin.sin_addr))
++
++#define SGINIT(sag)	(memset(&(sag), 0, sizeof((sag))), \
++			((sag).sg_family = AF_UNSPEC))
++#ifdef SIN6_LEN
++#define SGSETLEN(sag)	((sag).sg_sa.sa_len = SGSOCKSIZE(sag))
++#else
++#define SGSETLEN(sag)
++#endif
+ #else /* !HAVE_IPV6 */
+ 
+ #define	sockaddr_gen	sockaddr_in
+@@ -56,6 +64,10 @@
+ #define SGSOCKSIZE(sag)	sizeof(struct sockaddr_in)
+ #define SGPORT(sag)	((sag).sin_port)
+ #define SGADDRP(sag)	((char *) &(sag).sin_addr)
++
++#define SGINIT(sag)	(memset(&(sag), 0, sizeof((sag))), \
++			((sag).sin_family = AF_INET))
++#define SGSETLEN(sag)
+ 
+ #endif /* HAVE_IPV6 */
+ #endif
+--- src/str2.c.orig	Thu Jan 21 00:59:26 1999
++++ src/str2.c	Tue Sep 27 20:45:52 2005
+@@ -155,6 +155,75 @@
+ 
+ 
+ 
++/* XXX: Todo: Support hostnames and not just numbers */
++int
++str2addr(const char *str,
++	 struct sockaddr_gen *sg)
++{
++    char *buf, *cp, *pp = NULL;
++
++
++    SGINIT(*sg);
++
++    buf = s_strdup(str);
++    cp = buf;
++
++#ifdef HAVE_IPV6
++    if (*cp == '[')
++    {
++	/* IPv6 ala RFC 2732 */
++
++	++cp;
++	pp = strchr(cp, ']');
++	if (pp == NULL)
++	    return -1;
++
++	*pp++ = '\0';
++	if (*pp == ':')
++	    ++pp;
++	else
++	    pp = NULL;
++
++	SGFAM(*sg) = AF_INET6;
++    }
++    else
++    {
++	/* IPv4 */
++	pp = strrchr(cp, ':');
++	if (pp)
++	    *pp++ = '\0';
++
++	SGFAM(*sg) = AF_INET;
++    }
++
++    if (inet_pton(SGFAM(*sg), cp, SGADDRP(*sg)) != 1)
++    {
++	s_free(buf);
++	return -1;
++    }
++
++#else
++
++    /* Locate port part */
++    pp = strrchr(cp, ':');
++    if (pp)
++	*pp++ = '\0';
++
++    SGFAM(*sg) = AF_INET;
++    *(unsigned long *) SGADDRP(*sg) = inet_addr(cp);
++
++#endif
++
++    if (pp)
++	SGPORT(*sg) = htons(atoi(pp));
++    SGSETLEN(*sg);
++
++    s_free(buf);
++    return 0;
++}
++
++
++
+ int
+ str2gid(const char *str, gid_t *out)
+ {
+--- src/str2.h.orig	Thu Jan 21 00:59:26 1999
++++ src/str2.h	Tue Sep 27 20:45:52 2005
+@@ -21,6 +21,7 @@
+ extern int str2str(char *buf, char **out);
+ extern int str2bool(const char *buf, int *out);
+ extern int str2port(const char *str, int *out);
++extern int str2addr(const char *str, struct sockaddr_gen *sg);
+ extern int str2gid(const char *str, gid_t *out);
+ extern int str2uid(const char *str, uid_t *uid, gid_t *gid);
+ 

Added: csw/mgar/pkg/pidentd/trunk/files/pidentd.diff
===================================================================
--- csw/mgar/pkg/pidentd/trunk/files/pidentd.diff	                        (rev 0)
+++ csw/mgar/pkg/pidentd/trunk/files/pidentd.diff	2012-03-09 12:19:14 UTC (rev 17339)
@@ -0,0 +1,779 @@
+diff -druN src/ip_stack.h src/ip_stack.h
+--- src/ip_stack.h	1970-01-01 01:00:00.000000000 +0100
++++ src/ip_stack.h	2007-11-21 10:37:32.054244000 +0100
+@@ -0,0 +1,441 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License (the "License").
++ * You may not use this file except in compliance with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++
++/*
++ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
++ * Use is subject to license terms.
++ */
++
++#ifndef	_INET_IP_STACK_H
++#define	_INET_IP_STACK_H
++
++#pragma ident	"@(#)ip_stack.h	1.7	07/09/25 SMI"
++
++#ifdef	__cplusplus
++extern "C" {
++#endif
++
++#include <sys/isa_defs.h>
++#include <sys/md5.h>
++#include <sys/types.h>
++#include <inet/nd.h>
++#include <sys/atomic.h>
++#include <sys/socket.h>
++#include "netstack.h"
++#include <net/if_dl.h>
++#include <net/if.h>
++#include <netinet/ip.h>
++#include <netinet/igmp_var.h>
++#include <inet/ip.h>
++#include <sys/taskq.h>
++
++#ifdef _KERNEL
++#include <netinet/ip6.h>
++#include <sys/avl.h>
++#include <sys/vmem.h>
++#include <sys/squeue.h>
++#endif	/* _KERNEL */
++
++#ifdef _KERNEL
++
++
++/*
++ * IP statistics.
++ */
++#define	IP_STAT(ipst, x)	((ipst)->ips_ip_statistics.x.value.ui64++)
++#define	IP_STAT_UPDATE(ipst, x, n) \
++		((ipst)->ips_ip_statistics.x.value.ui64 += (n))
++
++/*
++ * Named statistics.
++ *
++ * List of arbitrary name=value statistics.
++ */
++
++#if 0
++typedef struct kstat_named {
++	char	name[KSTAT_STRLEN];	/* name of counter */
++	uchar_t	data_type;		/* data type */
++	union {
++		char		c[16];	/* enough for 128-bit ints */
++		int32_t		i32;
++		uint32_t	ui32;
++		struct {
++			union {
++				char 		*ptr;	/* NULL-term string */
++#if defined(_KERNEL) && defined(_MULTI_DATAMODEL)
++				caddr32_t	ptr32;
++#endif
++				char 		__pad[8]; /* 64-bit padding */
++			} addr;
++			uint32_t	len;	/* # bytes for strlen + '\0' */
++		} str;
++/*
++ * The int64_t and uint64_t types are not valid for a maximally conformant
++ * 32-bit compilation environment (cc -Xc) using compilers prior to the
++ * introduction of C99 conforming compiler (reference ISO/IEC 9899:1990).
++ * In these cases, the visibility of i64 and ui64 is only permitted for
++ * 64-bit compilation environments or 32-bit non-maximally conformant
++ * C89 or C90 ANSI C compilation environments (cc -Xt and cc -Xa). In the
++ * C99 ANSI C compilation environment, the long long type is supported.
++ * The _INT64_TYPE is defined by the implementation (see sys/int_types.h).
++ */
++#if defined(_INT64_TYPE)
++		int64_t		i64;
++		uint64_t	ui64;
++#endif
++		long		l;
++		ulong_t		ul;
++
++		/* These structure members are obsolete */
++
++		longlong_t	ll;
++		u_longlong_t	ull;
++		float		f;
++		double		d;
++	} value;			/* value of counter */
++} kstat_named_t;
++#endif
++
++   
++typedef struct ip_stat {
++	kstat_named_t	ipsec_fanout_proto;
++	kstat_named_t	ip_udp_fannorm;
++	kstat_named_t	ip_udp_fanmb;
++	kstat_named_t	ip_udp_fanothers;
++	kstat_named_t	ip_udp_fast_path;
++	kstat_named_t	ip_udp_slow_path;
++	kstat_named_t	ip_udp_input_err;
++	kstat_named_t	ip_tcppullup;
++	kstat_named_t	ip_tcpoptions;
++	kstat_named_t	ip_multipkttcp;
++	kstat_named_t	ip_tcp_fast_path;
++	kstat_named_t	ip_tcp_slow_path;
++	kstat_named_t	ip_tcp_input_error;
++	kstat_named_t	ip_db_ref;
++	kstat_named_t	ip_notaligned1;
++	kstat_named_t	ip_notaligned2;
++	kstat_named_t	ip_multimblk3;
++	kstat_named_t	ip_multimblk4;
++	kstat_named_t	ip_ipoptions;
++	kstat_named_t	ip_classify_fail;
++	kstat_named_t	ip_opt;
++	kstat_named_t	ip_udp_rput_local;
++	kstat_named_t	ipsec_proto_ahesp;
++	kstat_named_t	ip_conn_flputbq;
++	kstat_named_t	ip_conn_walk_drain;
++	kstat_named_t   ip_out_sw_cksum;
++	kstat_named_t   ip_in_sw_cksum;
++	kstat_named_t   ip_trash_ire_reclaim_calls;
++	kstat_named_t   ip_trash_ire_reclaim_success;
++	kstat_named_t   ip_ire_arp_timer_expired;
++	kstat_named_t   ip_ire_redirect_timer_expired;
++	kstat_named_t	ip_ire_pmtu_timer_expired;
++	kstat_named_t	ip_input_multi_squeue;
++	kstat_named_t	ip_tcp_in_full_hw_cksum_err;
++	kstat_named_t	ip_tcp_in_part_hw_cksum_err;
++	kstat_named_t	ip_tcp_in_sw_cksum_err;
++	kstat_named_t	ip_tcp_out_sw_cksum_bytes;
++	kstat_named_t	ip_udp_in_full_hw_cksum_err;
++	kstat_named_t	ip_udp_in_part_hw_cksum_err;
++	kstat_named_t	ip_udp_in_sw_cksum_err;
++	kstat_named_t	ip_udp_out_sw_cksum_bytes;
++	kstat_named_t	ip_frag_mdt_pkt_out;
++	kstat_named_t	ip_frag_mdt_discarded;
++	kstat_named_t	ip_frag_mdt_allocfail;
++	kstat_named_t	ip_frag_mdt_addpdescfail;
++	kstat_named_t	ip_frag_mdt_allocd;
++} ip_stat_t;
++
++
++/*
++ * IP6 statistics.
++ */
++#define	IP6_STAT(ipst, x)	((ipst)->ips_ip6_statistics.x.value.ui64++)
++#define	IP6_STAT_UPDATE(ipst, x, n)	\
++	((ipst)->ips_ip6_statistics.x.value.ui64 += (n))
++
++typedef struct ip6_stat {
++	kstat_named_t	ip6_udp_fast_path;
++	kstat_named_t	ip6_udp_slow_path;
++	kstat_named_t	ip6_udp_fannorm;
++	kstat_named_t	ip6_udp_fanmb;
++	kstat_named_t   ip6_out_sw_cksum;
++	kstat_named_t   ip6_in_sw_cksum;
++	kstat_named_t	ip6_tcp_in_full_hw_cksum_err;
++	kstat_named_t	ip6_tcp_in_part_hw_cksum_err;
++	kstat_named_t	ip6_tcp_in_sw_cksum_err;
++	kstat_named_t	ip6_tcp_out_sw_cksum_bytes;
++	kstat_named_t	ip6_udp_in_full_hw_cksum_err;
++	kstat_named_t	ip6_udp_in_part_hw_cksum_err;
++	kstat_named_t	ip6_udp_in_sw_cksum_err;
++	kstat_named_t	ip6_udp_out_sw_cksum_bytes;
++	kstat_named_t	ip6_frag_mdt_pkt_out;
++	kstat_named_t	ip6_frag_mdt_discarded;
++	kstat_named_t	ip6_frag_mdt_allocfail;
++	kstat_named_t	ip6_frag_mdt_addpdescfail;
++	kstat_named_t	ip6_frag_mdt_allocd;
++} ip6_stat_t;
++
++typedef struct ire_stats {
++	uint64_t ire_stats_alloced;	/* # of ires alloced */
++	uint64_t ire_stats_freed;	/* # of ires freed */
++	uint64_t ire_stats_inserted;	/* # of ires inserted in the bucket */
++	uint64_t ire_stats_deleted;	/* # of ires deleted from the bucket */
++} ire_stats_t;
++
++typedef struct mib2_ipIfStatsEntry {
++
++	/* Local ifindex to identify the interface */
++	DeviceIndex	ipIfStatsIfIndex;
++
++	/* forwarder?  1 gateway, 2 NOT gateway	{ ipv6MIBObjects 1} RW */
++	int	ipIfStatsForwarding;
++	/* default Hoplimit for IPv6		{ ipv6MIBObjects 2} RW */
++	int	ipIfStatsDefaultHopLimit;
++#define	ipIfStatsDefaultTTL	ipIfStatsDefaultHopLimit
++
++	int	ipIfStatsEntrySize;
++	int	ipIfStatsAddrEntrySize;
++	int	ipIfStatsRouteEntrySize;
++	int	ipIfStatsNetToMediaEntrySize;
++	int	ipIfStatsMemberEntrySize;
++	int	ipIfStatsGroupSourceEntrySize;
++
++	/* # input datagrams (incl errors)	{ ipIfStatsEntry 3 } */
++	Counter	ipIfStatsInReceives;
++	/* # errors in IP headers and options	{ ipIfStatsEntry 7 } */
++	Counter	ipIfStatsInHdrErrors;
++	/* # exceeds outgoing link MTU(v6 only)	{ ipv6IfStatsEntry 3 } */
++	Counter	ipIfStatsInTooBigErrors;
++	/* # discarded due to no route to dest 	{ ipIfStatsEntry 8 } */
++	Counter	ipIfStatsInNoRoutes;
++	/* # invalid or unsupported addresses	{ ipIfStatsEntry 9 } */
++	Counter	ipIfStatsInAddrErrors;
++	/* # unknown next header 		{ ipIfStatsEntry 10 } */
++	Counter	ipIfStatsInUnknownProtos;
++	/* # too short packets			{ ipIfStatsEntry 11 } */
++	Counter	ipIfStatsInTruncatedPkts;
++	/* # discarded e.g. due to no buffers	{ ipIfStatsEntry 17 } */
++	Counter	ipIfStatsInDiscards;
++	/* # delivered to upper layer protocols	{ ipIfStatsEntry 18 } */
++	Counter	ipIfStatsInDelivers;
++	/* # forwarded out interface		{ ipIfStatsEntry 23 } */
++	Counter	ipIfStatsOutForwDatagrams;
++	/* # originated out interface		{ ipIfStatsEntry 20 } */
++	Counter	ipIfStatsOutRequests;
++	/* # discarded e.g. due to no buffers	{ ipIfStatsEntry 25 } */
++	Counter	ipIfStatsOutDiscards;
++	/* # sucessfully fragmented packets	{ ipIfStatsEntry 27 } */
++	Counter	ipIfStatsOutFragOKs;
++	/* # fragmentation failed		{ ipIfStatsEntry 28 } */
++	Counter	ipIfStatsOutFragFails;
++	/* # fragments created			{ ipIfStatsEntry 29 } */
++	Counter	ipIfStatsOutFragCreates;
++	/* # fragments to reassemble		{ ipIfStatsEntry 14 } */
++	Counter	ipIfStatsReasmReqds;
++	/* # packets after reassembly		{ ipIfStatsEntry 15 } */
++	Counter	ipIfStatsReasmOKs;
++	/* # reassembly failed			{ ipIfStatsEntry 16 } */
++	Counter	ipIfStatsReasmFails;
++	/* # received multicast packets		{ ipIfStatsEntry 34 } */
++	Counter	ipIfStatsInMcastPkts;
++	/* # transmitted multicast packets	{ ipIfStatsEntry 38 } */
++	Counter	ipIfStatsOutMcastPkts;
++
++	/*
++	 * In addition to defined MIBs
++	 */
++
++	/* # discarded due to no route to dest 	{ ipSystemStatsEntry 22 } */
++	Counter	ipIfStatsOutNoRoutes;
++	/* # of complete duplicates in reassembly */
++	Counter	ipIfStatsReasmDuplicates;
++	/* # of partial duplicates in reassembly */
++	Counter	ipIfStatsReasmPartDups;
++	/* # of packets not forwarded due to adminstrative reasons */
++	Counter	ipIfStatsForwProhibits;
++	/* # of UDP packets with bad UDP checksums */
++	Counter udpInCksumErrs;
++#define	udpIfStatsInCksumErrs	udpInCksumErrs
++	/* # of UDP packets droped due to queue overflow */
++	Counter udpInOverflows;
++#define	udpIfStatsInOverflows	udpInOverflows
++	/*
++	 * # of RAW IP packets (all IP protocols except UDP, TCP
++	 * and ICMP) droped due to queue overflow
++	 */
++	Counter rawipInOverflows;
++#define	rawipIfStatsInOverflows	rawipInOverflows
++
++	/*
++	 * # of IP packets received with the wrong version (i.e., not equal
++	 * to ipIfStatsIPVersion) and that were dropped.
++	 */
++	Counter ipIfStatsInWrongIPVersion;
++	/*
++	 * Depending on the value of ipIfStatsIPVersion, this counter tracks
++	 * v4: # of IPv6 packets transmitted by ip_wput or,
++	 * v6: # of IPv4 packets transmitted by ip_wput_v6.
++	 */
++	Counter ipIfStatsOutWrongIPVersion;
++	/*
++	 * Depending on the value of ipIfStatsIPVersion, this counter tracks
++	 * # of times ip_wput has switched to become ip_wput_v6, or vice versa.
++	 */
++	Counter ipIfStatsOutSwitchIPVersion;
++
++	/*
++	 * Fields defined in RFC 4293
++	 */
++
++	/* ip version				{ ipIfStatsEntry 1 } */
++	int		ipIfStatsIPVersion;
++	/* # input datagrams (incl errors)	{ ipIfStatsEntry 4 } */
++	Counter64	ipIfStatsHCInReceives;
++	/* # input octets (incl errors)		{ ipIfStatsEntry 6 } */
++	Counter64	ipIfStatsHCInOctets;
++	/*
++	 *					{ ipIfStatsEntry 13 }
++	 * # input datagrams for which a forwarding attempt was made
++	 */
++	Counter64	ipIfStatsHCInForwDatagrams;
++	/* # delivered to upper layer protocols	{ ipIfStatsEntry 19 } */
++	Counter64	ipIfStatsHCInDelivers;
++	/* # originated out interface		{ ipIfStatsEntry 21 } */
++	Counter64	ipIfStatsHCOutRequests;
++	/* # forwarded out interface		{ ipIfStatsEntry 23 } */
++	Counter64	ipIfStatsHCOutForwDatagrams;
++	/* # dg's requiring fragmentation 	{ ipIfStatsEntry 26 } */
++	Counter		ipIfStatsOutFragReqds;
++	/* # output datagrams			{ ipIfStatsEntry 31 } */
++	Counter64	ipIfStatsHCOutTransmits;
++	/* # output octets			{ ipIfStatsEntry 33 } */
++	Counter64	ipIfStatsHCOutOctets;
++	/* # received multicast datagrams	{ ipIfStatsEntry 35 } */
++	Counter64	ipIfStatsHCInMcastPkts;
++	/* # received multicast octets		{ ipIfStatsEntry 37 } */
++	Counter64	ipIfStatsHCInMcastOctets;
++	/* # transmitted multicast datagrams	{ ipIfStatsEntry 39 } */
++	Counter64	ipIfStatsHCOutMcastPkts;
++	/* # transmitted multicast octets	{ ipIfStatsEntry 41 } */
++	Counter64	ipIfStatsHCOutMcastOctets;
++	/* # received broadcast datagrams	{ ipIfStatsEntry 43 } */
++	Counter64	ipIfStatsHCInBcastPkts;
++	/* # transmitted broadcast datagrams	{ ipIfStatsEntry 45 } */
++	Counter64	ipIfStatsHCOutBcastPkts;
++
++	/*
++	 * Fields defined in mib2_ip_t
++	 */
++
++	/* # of incoming packets that succeeded policy checks */
++	Counter		ipsecInSucceeded;
++#define	ipsecIfStatsInSucceeded	ipsecInSucceeded
++	/* # of incoming packets that failed policy checks */
++	Counter		ipsecInFailed;
++#define	ipsecIfStatsInFailed	ipsecInFailed
++	/* # of bad IP header checksums */
++	Counter		ipInCksumErrs;
++#define	ipIfStatsInCksumErrs	ipInCksumErrs
++	/* total # of segments recv'd with error	{ tcp 14 } */
++	Counter		tcpInErrs;
++#define	tcpIfStatsInErrs	tcpInErrs
++	/* # of recv'd dg's not deliverable (no appl.)	{ udp 2 } */
++	Counter		udpNoPorts;
++#define	udpIfStatsNoPorts	udpNoPorts
++} mib2_ipIfStatsEntry_t;
++
++/*
++ * IP stack instances
++ */
++struct ip_stack {
++	netstack_t	*ips_netstack;	/* Common netstack */
++
++	struct ipparam_s	*ips_param_arr; 	/* ndd variable table */
++	void			*ips_ndp_arr;
++
++	mib2_ipIfStatsEntry_t	ips_ip_mib;	/* SNMP fixed size info */
++	mib2_icmp_t	ips_icmp_mib;
++	/*
++	 * IPv6 mibs when the interface (ill) is not known.
++	 * When the ill is known the per-interface mib in the ill is used.
++	 */
++	mib2_ipIfStatsEntry_t	ips_ip6_mib;
++	mib2_ipv6IfIcmpEntry_t	ips_icmp6_mib;
++
++	struct igmpstat		ips_igmpstat;
++
++	kstat_t		*ips_ip_mibkp;	/* kstat exporting ip_mib data */
++	kstat_t		*ips_icmp_mibkp; /* kstat exporting icmp_mib data */
++	kstat_t		*ips_ip_kstat;
++	ip_stat_t	ips_ip_statistics;
++	kstat_t		*ips_ip6_kstat;
++	ip6_stat_t	ips_ip6_statistics;
++
++/* ip.c */
++	krwlock_t	ips_ip_g_nd_lock;
++	kmutex_t	ips_igmp_timer_lock;
++	kmutex_t	ips_mld_timer_lock;
++	kmutex_t	ips_ip_mi_lock;
++	kmutex_t	ips_ip_addr_avail_lock;
++	krwlock_t	ips_ill_g_lock;
++	krwlock_t	ips_ipsec_capab_ills_lock;
++				/* protects the list of IPsec capable ills */
++	void	*ips_ipsec_capab_ills_ah;
++	void	*ips_ipsec_capab_ills_esp;
++
++	krwlock_t	ips_ill_g_usesrc_lock;
++
++	void	*ips_illgrp_head_v4;	/* Head of IPv4 ill groups */
++	void	*ips_illgrp_head_v6;	/* Head of IPv6 ill groups */
++
++/* ipclassifier.c - keep in ip_stack_t */
++	/* ipclassifier hash tables */
++	void	*ips_rts_clients;
++	void	*ips_ipcl_conn_fanout;
++	void	*ips_ipcl_bind_fanout;
++	void	*ips_ipcl_proto_fanout;
++	void	*ips_ipcl_proto_fanout_v6;
++	void	*ips_ipcl_udp_fanout;
++	void	*ips_ipcl_raw_fanout;
++	uint_t		ips_ipcl_conn_fanout_size;
++	uint_t		ips_ipcl_bind_fanout_size;
++	uint_t		ips_ipcl_udp_fanout_size;
++	uint_t		ips_ipcl_raw_fanout_size;
++	void	*ips_ipcl_globalhash_fanout;
++	int		ips_conn_g_index;
++};
++typedef struct ip_stack ip_stack_t;
++
++/* Finding an ip_stack_t */
++#define	CONNQ_TO_IPST(_q)	(Q_TO_CONN(_q)->conn_netstack->netstack_ip)
++#define	ILLQ_TO_IPST(_q)	(((ill_t *)(_q)->q_ptr)->ill_ipst)
++
++#else /* _KERNEL */
++typedef int ip_stack_t;
++#endif /* _KERNEL */
++
++#ifdef	__cplusplus
++}
++#endif
++
++#endif	/* _INET_IP_STACK_H */
+diff -druN src/k_sunos510.c src/k_sunos510.c
+--- src/k_sunos510.c	2005-10-18 11:22:04.000000000 +0200
++++ src/k_sunos510.c	2007-11-21 12:47:00.717975000 +0100
+@@ -64,6 +64,9 @@
+ #include <netinet/ip6.h>
+ #include <net/if.h>
+ 
++#include "netstack.h"
++#include "ip_stack.h"
++
+ uint_t   ipcl_conn_fanout_size;
+ 
+ #if   !defined(IN6_V4_MAPPED_TO_INADDR)
+@@ -154,7 +157,10 @@
+ ka_open(void **misc)
+ {
+     struct kainfo *kp;
+-
++    netstack_t netstack_head;
++    struct ip_stack ip_stack;
++    struct connf_s  *ipcl_conn_fanout;
++    netstack_t *netstack_head_ptr;
+ 
+     kp = s_malloc(sizeof(*kp));
+     
+@@ -168,10 +174,8 @@
+ 	return -1;
+     }
+     
+-    
+-    kp->nl[0].n_name = "ipcl_conn_fanout";
+-    kp->nl[1].n_name = "ipcl_conn_fanout_size";
+-    kp->nl[2].n_name = NULL;
++    kp->nl[0].n_name = "netstack_head";
++    kp->nl[1].n_name = NULL;
+     
+     /*
+     ** Extract offsets to the needed variables in the kernel
+@@ -184,6 +188,39 @@
+ 	return -1;
+     }
+ 
++    if (!getbuf(kp->kd, kp->nl[0].n_value, (char *) &netstack_head_ptr,
++	     sizeof(netstack_head_ptr), "netstack_head_ptr")) {
++       kvm_close(kp->kd);
++       s_free(kp);
++       syslog(LOG_ERR, "getbuf: can't get netstack_head_ptr");
++       return -1;
++    }
++
++    /* load netstack_head */
++    if (!getbuf(kp->kd, netstack_head_ptr, (char *) &netstack_head,
++	     sizeof(netstack_head), "netstack_head")) {
++       kvm_close(kp->kd);
++       s_free(kp);
++       syslog(LOG_ERR, "getbuf: can't get netstack_head ");
++       return -1;
++    }
++
++    /* get ip_stack */
++    if (!getbuf(kp->kd, netstack_head.netstack_ip, (char *) &ip_stack,
++	     sizeof(ip_stack), "ip_stack")) {
++       kvm_close(kp->kd);
++       s_free(kp);
++       syslog(LOG_ERR, "getbuf: can't get ip_stack");
++       return -1;
++    }
++    
++    kp->nl[0].n_name = "ipcl_conn_fanout";
++    kp->nl[0].n_value = (long) ip_stack.ips_ipcl_conn_fanout;
++    kp->nl[1].n_name = "ipcl_conn_fanout_size";
++    kp->nl[1].n_value = (long) ip_stack.ips_ipcl_conn_fanout_size;
++    kp->nl[2].n_name = NULL;
++
++#if 0
+     /*
+      * Read the two kernel values we need but won't change
+      */
+@@ -196,6 +233,9 @@
+ 	    syslog(LOG_ERR, "getbuf: can't get needed symbols");
+ 	    return -1;
+     }
++#endif
++    kp->hash_size = ip_stack.ips_ipcl_conn_fanout_size;
++    kp->hash_table = ip_stack.ips_ipcl_conn_fanout;
+ 
+     *misc = (void *) kp;
+     return 0;
+diff -druN src/netstack.h src/netstack.h
+--- src/netstack.h	1970-01-01 01:00:00.000000000 +0100
++++ src/netstack.h	2007-11-21 09:59:05.237496000 +0100
+@@ -0,0 +1,242 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License (the "License").
++ * You may not use this file except in compliance with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++
++/*
++ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
++ * Use is subject to license terms.
++ */
++#ifndef _SYS_NETSTACK_H
++#define	_SYS_NETSTACK_H
++
++#pragma ident	"@(#)netstack.h	1.3	07/05/17 SMI"
++
++#include <sys/kstat.h>
++
++#ifdef	__cplusplus
++extern "C" {
++#endif
++
++/*
++ * This allows various pieces in and around IP to have a separate instance
++ * for each instance of IP. This is used to support zones that have an
++ * exclusive stack.
++ * Pieces of software far removed from IP (e.g., kernel software
++ * sitting on top of TCP or UDP) probably should not use the netstack
++ * support; if such software wants to support separate zones it
++ * can do that using the zones framework (zone_key_create() etc)
++ * whether there is a shared IP stack or and exclusive IP stack underneath.
++ */
++
++/*
++ * Each netstack has an identifier. We reuse the zoneid allocation for
++ * this but have a separate typedef. Thus the shared stack (used by
++ * the global zone and other shared stack zones) have a zero ID, and
++ * the exclusive stacks have a netstackid that is the same as their zoneid.
++ */
++typedef id_t	netstackid_t;
++
++#define	GLOBAL_NETSTACKID	0
++
++/*
++ * One for each module which uses netstack support.
++ * Used in netstack_register().
++ *
++ * The order of these is important for some modules both for
++ * the creation (which done in ascending order) and destruction (which is
++ * done ine in decending order).
++ */
++#define	NS_ALL		-1	/* Match all */
++#define	NS_HOOK		0
++#define	NS_NETI		1
++#define	NS_ARP		2
++#define	NS_IP		3
++#define	NS_ICMP		4
++#define	NS_UDP		5
++#define	NS_TCP		6
++#define	NS_SCTP		7
++#define	NS_RTS		8
++#define	NS_IPSEC	9
++#define	NS_KEYSOCK	10
++#define	NS_SPDSOCK	11
++#define	NS_IPSECAH	12
++#define	NS_IPSECESP	13
++#define	NS_TUN		14
++#define	NS_IPF		15
++#define	NS_STR		16	/* autopush list etc */
++#define	NS_MAX		(NS_STR+1)
++
++/*
++ * One for every netstack in the system.
++ * We use a union so that the compilar and lint can provide type checking -
++ * in principle we could have
++ * #define	netstack_arp		netstack_modules[NS_ARP]
++ * etc, but that would imply void * types hence no type checking by the
++ * compiler.
++ *
++ * All the fields in netstack_t except netstack_next are protected by
++ * netstack_lock. netstack_next is protected by netstack_g_lock.
++ */
++struct netstack {
++	union {
++		void	*nu_modules[NS_MAX];
++		struct {
++			struct hook_stack	*nu_hook;
++			struct neti_stack	*nu_neti;
++			struct arp_stack	*nu_arp;
++			struct ip_stack		*nu_ip;
++			struct icmp_stack	*nu_icmp;
++			struct udp_stack	*nu_udp;
++			struct tcp_stack	*nu_tcp;
++			struct sctp_stack	*nu_sctp;
++			struct rts_stack	*nu_rts;
++			struct ipsec_stack	*nu_ipsec;
++			struct keysock_stack	*nu_keysock;
++			struct spd_stack	*nu_spdsock;
++			struct ipsecah_stack	*nu_ipsecah;
++			struct ipsecesp_stack	*nu_ipsecesp;
++			struct tun_stack	*nu_tun;
++			struct ipf_stack	*nu_ipf;
++			struct str_stack	*nu_str;
++		} nu_s;
++	} netstack_u;
++#define	netstack_modules	netstack_u.nu_modules
++#define	netstack_hook		netstack_u.nu_s.nu_hook
++#define	netstack_neti		netstack_u.nu_s.nu_neti
++#define	netstack_arp		netstack_u.nu_s.nu_arp
++#define	netstack_ip		netstack_u.nu_s.nu_ip
++#define	netstack_icmp		netstack_u.nu_s.nu_icmp
++#define	netstack_udp		netstack_u.nu_s.nu_udp
++#define	netstack_tcp		netstack_u.nu_s.nu_tcp
++#define	netstack_sctp		netstack_u.nu_s.nu_sctp
++#define	netstack_rts		netstack_u.nu_s.nu_rts
++#define	netstack_ipsec		netstack_u.nu_s.nu_ipsec
++#define	netstack_keysock	netstack_u.nu_s.nu_keysock
++#define	netstack_spdsock	netstack_u.nu_s.nu_spdsock
++#define	netstack_ipsecah	netstack_u.nu_s.nu_ipsecah
++#define	netstack_ipsecesp	netstack_u.nu_s.nu_ipsecesp
++#define	netstack_tun		netstack_u.nu_s.nu_tun
++#define	netstack_ipf		netstack_u.nu_s.nu_ipf
++#define	netstack_str		netstack_u.nu_s.nu_str
++
++	uint16_t	netstack_m_state[NS_MAX]; /* module state */
++
++	kmutex_t	netstack_lock;
++	struct netstack *netstack_next;
++	netstackid_t	netstack_stackid;
++	int		netstack_numzones;	/* Number of zones using this */
++	int		netstack_refcnt;	/* Number of hold-rele */
++	int		netstack_flags;	/* See below */
++};
++typedef struct netstack netstack_t;
++
++/* netstack_flags values */
++#define	NSF_UNINIT	0x01		/* Not initialized */
++#define	NSF_CLOSING	0x02		/* Going away */
++
++/*
++ * State for each module for each stack - netstack_m_state[moduleid]
++ * Keeps track of pending actions to avoid holding looks when
++ * calling into the create/shutdown/destroy functions in the module.
++ */
++#define	NSS_CREATE_NEEDED	0x0001
++#define	NSS_CREATE_INPROGRESS	0x0002
++#define	NSS_CREATE_COMPLETED	0x0004
++#define	NSS_SHUTDOWN_NEEDED	0x0010
++#define	NSS_SHUTDOWN_INPROGRESS	0x0020
++#define	NSS_SHUTDOWN_COMPLETED	0x0040
++#define	NSS_DESTROY_NEEDED	0x0100
++#define	NSS_DESTROY_INPROGRESS	0x0200
++#define	NSS_DESTROY_COMPLETED	0x0400
++
++#define	NSS_CREATE_ALL	\
++	(NSS_CREATE_NEEDED|NSS_CREATE_INPROGRESS|NSS_CREATE_COMPLETED)
++#define	NSS_SHUTDOWN_ALL	\
++	(NSS_SHUTDOWN_NEEDED|NSS_SHUTDOWN_INPROGRESS|NSS_SHUTDOWN_COMPLETED)
++#define	NSS_DESTROY_ALL	\
++	(NSS_DESTROY_NEEDED|NSS_DESTROY_INPROGRESS|NSS_DESTROY_COMPLETED)
++
++/*
++ * One for each of the NS_* values.
++ */
++struct netstack_registry {
++	int		nr_flags;	/* 0 if nothing registered */
++	void		*(*nr_create)(netstackid_t, netstack_t *);
++	void		(*nr_shutdown)(netstackid_t, void *);
++	void		(*nr_destroy)(netstackid_t, void *);
++};
++
++/* nr_flags values */
++#define	NRF_REGISTERED	0x01
++
++/*
++ * To support kstat_create_netstack() using kstat_add_zone we need
++ * to track both
++ *  - all zoneids that use the global/shared stack
++ *  - all kstats that have been added for the shared stack
++ */
++
++extern void netstack_init(void);
++extern void netstack_hold(netstack_t *);
++extern void netstack_rele(netstack_t *);
++extern netstack_t *netstack_find_by_cred(const cred_t *);
++extern netstack_t *netstack_find_by_stackid(netstackid_t);
++extern netstack_t *netstack_find_by_zoneid(zoneid_t);
++
++extern zoneid_t netstackid_to_zoneid(netstackid_t);
++extern netstackid_t zoneid_to_netstackid(zoneid_t);
++
++extern netstack_t *netstack_get_current(void);
++
++/*
++ * Register interest in changes to the set of netstacks.
++ * The createfn and destroyfn are required, but the shutdownfn can be
++ * NULL.
++ * Note that due to the current zsd implementation, when the create
++ * function is called the zone isn't fully present, thus functions
++ * like zone_find_by_* will fail, hence the create function can not
++ * use many zones kernel functions including zcmn_err().
++ */
++extern void	netstack_register(int,
++    void *(*)(netstackid_t, netstack_t *),
++    void (*)(netstackid_t, void *),
++    void (*)(netstackid_t, void *));
++extern void	netstack_unregister(int);
++extern kstat_t	*kstat_create_netstack(char *, int, char *, char *, uchar_t,
++    uint_t, uchar_t, netstackid_t);
++extern void	kstat_delete_netstack(kstat_t *, netstackid_t);
++
++/*
++ * Simple support for walking all the netstacks.
++ * The caller of netstack_next() needs to call netstack_rele() when
++ * done with a netstack.
++ */
++typedef	int	netstack_handle_t;
++
++extern void	netstack_next_init(netstack_handle_t *);
++extern void	netstack_next_fini(netstack_handle_t *);
++extern netstack_t	*netstack_next(netstack_handle_t *);
++
++#ifdef	__cplusplus
++}
++#endif
++
++
++#endif	/* _SYS_NETSTACK_H */

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the devel mailing list