[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Making pidentd ipv6-enabled



package pidentd
tags 192538 + patch
thanks


Hello,

may I suggest a patch that makes pidentd able to use IPv6.
It is probably not the final version but it is capable
within the tested limits.

I have tested the resulting package using IPv4 as well as
IPv6 and it works charmingly well. Two cases are unchecked

   1. The function of the compiled package on an machine without
      IPv6 enabled in the network stack at all

   2. The function of the DES-encrypting parts of the service.

Regards,
-- 
Mats Erik Andersson, fil. dr
<debian@gisladisker.se>

Abbonerar på: debian-mentors, debian-devel-games, debian-perl, debian-ipv6
diff -u pidentd-3.0.19.ds1/src/server.c pidentd-3.0.19.ds1/src/server.c
--- pidentd-3.0.19.ds1/src/server.c
+++ pidentd-3.0.19.ds1/src/server.c
@@ -28,9 +28,10 @@
 
 
 
+int listen_addrfam = AF_INET6;
 int listen_sock = -1;
 int listen_port = IPPORT_IDENT;
-int listen_addr = INADDR_ANY;
+char listen_addr[INET6_ADDRSTRLEN] = "::";
 int listen_backlog = 256;
 
 
@@ -66,7 +67,9 @@
 {
     static int one = 1;
     int nofile;
-    struct sockaddr_in sin;
+    struct sockaddr_storage sin;
+    struct sockaddr_in * sa4 = (struct sockaddr_in *) &sin;
+    struct sockaddr_in6 * sa6 = (struct sockaddr_in6 *) &sin;
     
     
     /*
@@ -80,20 +83,43 @@
 
     if (listen_sock < 0)
     {
-	listen_sock = socket(AF_INET, SOCK_STREAM, 0);
+	listen_sock = socket(listen_addrfam, SOCK_STREAM, 0);
 	if (listen_sock < 0)
 	{
-	    syslog(LOG_ERR, "socket(AF_INET, SOCK_STREAM) failed: %m");
-	    return -1;
+	    /* Fall back on the other address family. */
+	    listen_addrfam = (listen_addrfam == AF_INET6
+					? AF_INET : AF_INET6);
+	    listen_sock = socket(listen_addrfam, SOCK_STREAM, 0);
+	    if (listen_sock < 0) {
+		syslog(LOG_ERR, "socket(AF_INET, SOCK_STREAM) failed: %m");
+		return -1;
+	    }
 	}
 
 	(void) setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
 		   (void *) &one, sizeof(one));
-	
+	if (listen_addrfam == AF_INET6) {
+	    int null = 0;
+	    (void) setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY,
+					&null, sizeof(null));
+	}
+
 	memset(&sin, 0, sizeof(sin));
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = htonl(listen_addr);
-	sin.sin_port = htons(listen_port);
+	sin.ss_family = listen_addrfam;
+	switch (sin.ss_family) {
+	    case AF_INET6:
+		inet_pton(sin.ss_family, listen_addr, &(sa6->sin6_addr));
+		sa6->sin6_port = htons(listen_port);
+		break;
+	    case AF_INET:
+	    default:
+		if ( strchr(listen_addr, ':') )
+		    /* Invalid IPv4-string. Use the wildcard address. */
+		    strcpy(listen_addr, "0.0.0.0");
+
+		inet_pton(sin.ss_family, listen_addr, &(sa4->sin_addr));
+		sa4->sin_port = htons(listen_port);
+	}
 
 	if (bind(listen_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0)
 	{
diff -u pidentd-3.0.19.ds1/src/k_linux.c pidentd-3.0.19.ds1/src/k_linux.c
--- pidentd-3.0.19.ds1/src/k_linux.c
+++ pidentd-3.0.19.ds1/src/k_linux.c
@@ -18,6 +18,7 @@
 #include <syslog.h>
 #include <errno.h>
 #include <unistd.h>
+#include <string.h>
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -88,18 +89,38 @@
 	} u;
     } buf;
     struct sockaddr_nl addr;
+    struct in6_addr remote_in6addr = kp->remote.sg_sin6.sin6_addr;
+    struct in6_addr local_in6addr = kp->local.sg_sin6.sin6_addr;
 
     memset(&buf, 0, sizeof(buf));
     buf.nlh.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(buf.u.req)));
     buf.nlh.nlmsg_type = TCPDIAG_GETSOCK;
     buf.nlh.nlmsg_flags = NLM_F_REQUEST;
     buf.nlh.nlmsg_seq = ++kip->seq;
-    buf.u.req.idiag_family = AF_INET;
 
-    buf.u.req.id.idiag_dport = kp->remote.sin_port;
-    buf.u.req.id.idiag_sport = kp->local.sin_port;
-    buf.u.req.id.idiag_dst[0] = kp->remote.sin_addr.s_addr;
-    buf.u.req.id.idiag_src[0] = kp->local.sin_addr.s_addr;
+    buf.u.req.id.idiag_dport = SGPORT(kp->remote);
+    buf.u.req.id.idiag_sport = SGPORT(kp->local);
+
+    switch (buf.u.req.idiag_family) {
+	case AF_INET:
+	    buf.u.req.id.idiag_dst[0] = kp->remote.sg_sin.sin_addr.s_addr;
+	    buf.u.req.id.idiag_src[0] = kp->local.sg_sin.sin_addr.s_addr;
+	    break;
+	case AF_INET6:
+	default:
+	    if ( IN6_IS_ADDR_V4MAPPED(SGADDRP(kp->remote)) ) {
+		buf.u.req.idiag_family = AF_INET;
+		buf.u.req.id.idiag_dst[0] = remote_in6addr.s6_addr32[3];
+		buf.u.req.id.idiag_src[0] = local_in6addr.s6_addr32[3];
+	    }
+	    else {
+		buf.u.req.idiag_family = AF_INET6;
+		memcpy(buf.u.req.id.idiag_dst, SGADDRP(kp->remote),
+				sizeof(buf.u.req.id.idiag_dst));
+		memcpy(buf.u.req.id.idiag_src, SGADDRP(kp->local),
+				sizeof(buf.u.req.id.idiag_src));
+	    }
+    }
     buf.u.req.id.idiag_cookie[0] = INET_DIAG_NOCOOKIE;
     buf.u.req.id.idiag_cookie[1] = INET_DIAG_NOCOOKIE;
 
@@ -137,7 +158,7 @@
     FILE *fp;
     long dummy;
     char buf[512];
-    long r_laddr, r_raddr, myladdr, myraddr;
+    uint32_t r_laddr[4], r_raddr[4], myladdr[4], myraddr[4];
     int r_lport, r_rport, mylport, myrport;
     int euid;
     int nra;
@@ -180,10 +201,10 @@
     if (kip->nlfd >= 0)
 	return netlink_lookup(kip, kp);
 
-    r_rport = ntohs(kp->remote.sin_port);
-    r_lport = ntohs(kp->local.sin_port);
-    r_raddr = kp->remote.sin_addr.s_addr;
-    r_laddr = kp->local.sin_addr.s_addr;
+    r_rport = ntohs(SGPORT(kp->remote));
+    r_lport = ntohs(SGPORT(kp->local));
+    memcpy(r_raddr, SGADDRP(kp->remote), sizeof(r_raddr));
+    memcpy(r_laddr, SGADDRP(kp->local), sizeof(r_laddr));
 
     fp = kip->proc_net_tcp;
 
diff -u pidentd-3.0.19.ds1/debian/rules pidentd-3.0.19.ds1/debian/rules
--- pidentd-3.0.19.ds1/debian/rules
+++ pidentd-3.0.19.ds1/debian/rules
@@ -33,7 +33,8 @@
 	./configure --with-des \
 		    --with-des-includes=/usr/include/openssl \
 		    --mandir='$${prefix}/share/man' \
-		    --sysconfdir=/etc
+		    --sysconfdir=/etc \
+		    CPPFLAGS="-DHAVE_IPV6=1"
 
 	touch configure-stamp
 
diff -u pidentd-3.0.19.ds1/debian/changelog pidentd-3.0.19.ds1/debian/changelog
--- pidentd-3.0.19.ds1/debian/changelog
+++ pidentd-3.0.19.ds1/debian/changelog
@@ -1,3 +1,10 @@
+pidentd (3.0.19.ds1-5.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Implement IPv6-support.
+
+ -- Mats Erik Andersson <mats.andersson@gisladisker.se>  Tue, 16 Feb 2010 19:24:37 +0100
+
 pidentd (3.0.19.ds1-5) unstable; urgency=low
 
   * Priority is optional; closes: #416570, #492060
only in patch2:
unchanged:
--- pidentd-3.0.19.ds1.orig/src/support.c
+++ pidentd-3.0.19.ds1/src/support.c
@@ -63,7 +63,7 @@
 int
 socktype(int fd)
 {
-    struct sockaddr_in remote_sin, local_sin;
+    struct sockaddr_storage remote_sin, local_sin;
     socklen_t len;
     int code;
 
only in patch2:
unchanged:
--- pidentd-3.0.19.ds1.orig/src/pdes.c
+++ pidentd-3.0.19.ds1/src/pdes.c
@@ -127,10 +127,10 @@
     time(&bt);
     r.fields.date = htonl(bt);
        
-    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;
+    memcpy(r.fields.ip_local, SGADDRP(kp->local), sizeof(r.fields.ip_local));
+    memcpy(r.fields.ip_remote, SGADDRP(kp->remote), sizeof(r.fields.ip_remote));
+    r.fields.port_local  = SGPORT(kp->local);
+    r.fields.port_remote = SGPORT(kp->remote);
 
     r.fields.checksum = 0;
     for (i = 1; i < 6; i++)
only in patch2:
unchanged:
--- pidentd-3.0.19.ds1.orig/src/pdes.h
+++ pidentd-3.0.19.ds1/src/pdes.h
@@ -22,8 +22,8 @@
     /* FIXME: uid_t isn't necessarily short.  */
     uint16_t uid;
     uint32_t date;
-    uint32_t ip_local;
-    uint32_t ip_remote;
+    uint32_t ip_local[4];
+    uint32_t ip_remote[4];
     uint16_t port_local;
     uint16_t port_remote;
 };
only in patch2:
unchanged:
--- pidentd-3.0.19.ds1.orig/src/server.h
+++ pidentd-3.0.19.ds1/src/server.h
@@ -15,9 +15,10 @@
 #ifndef PIDENTD_SERVER_H
 #define PIDENTD_SERVER_H
 
+extern int listen_addrfam;
 extern int listen_sock;
 extern int listen_port;
-extern int listen_addr;
+extern char listen_addr[];
 extern int listen_backlog;
 
 
only in patch2:
unchanged:
--- pidentd-3.0.19.ds1.orig/src/idecrypt.c
+++ pidentd-3.0.19.ds1/src/idecrypt.c
@@ -160,8 +160,8 @@
     date_in_sec = ntohl(r.fields.date);
     date_in_ascii = ctime(&date_in_sec);
     
-    memcpy(SGADDRP(ip_local), &(r.fields.ip_local), sizeof(ip_local));
-    memcpy(SGADDRP(ip_remote), &(r.fields.ip_remote), sizeof(ip_remote));
+    memcpy(SGADDRP(ip_local), r.fields.ip_local, sizeof(ip_local));
+    memcpy(SGADDRP(ip_remote), r.fields.ip_remote, sizeof(ip_remote));
 
     /* FIXME: uid_t isn't necessarily short.  */
 #ifdef HAVE_SNPRINTF

Attachment: signature.asc
Description: Digital signature


Reply to: