summary refs log tree commit diff stats
path: root/src/common/identd.c
diff options
context:
space:
mode:
authorBerke Viktor <berkeviktor@aol.com>2012-02-01 18:09:27 +0100
committerBerke Viktor <berkeviktor@aol.com>2012-02-01 18:09:27 +0100
commit99b9c1f0b20d2ed896cb930c0213e0d6f28a5b10 (patch)
treef0e8e16d0f418c3fe8d9877a5cda750681ef46ca /src/common/identd.c
parent7aecdd300972acbe86c7a01b5f1ed80a7a26123a (diff)
IPv6 support for XChat (Olipro)
Diffstat (limited to 'src/common/identd.c')
-rw-r--r--src/common/identd.c100
1 files changed, 98 insertions, 2 deletions
diff --git a/src/common/identd.c b/src/common/identd.c
index 919282ea..430c7e8f 100644
--- a/src/common/identd.c
+++ b/src/common/identd.c
@@ -1,8 +1,13 @@
 /* simple identd server for xchat under win32 */
 
+#include "inet.h"
+#include "xchat.h"
+#include "xchatc.h"
 
 static int identd_is_running = FALSE;
-
+#ifdef USE_IPV6
+static int identd_ipv6_is_running = FALSE;
+#endif
 
 static int
 identd (char *username)
@@ -75,11 +80,102 @@ identd (char *username)
 	return 0;
 }
 
-static void
+#ifdef USE_IPV6
+static int
+identd_ipv6 (char *username)
+{
+	int sok, read_sok, len;
+	char *p;
+	char buf[256];
+	char outbuf[256];
+	char ipv6buf[60];
+	DWORD ipv6buflen = sizeof (ipv6buf);
+	struct sockaddr_in6 addr;
+
+	sok = socket (AF_INET6, SOCK_STREAM, 0);
+
+	if (sok == INVALID_SOCKET)
+	{
+		free (username);
+		return 0;
+	}
+
+	len = 1;
+	setsockopt (sok, SOL_SOCKET, SO_REUSEADDR, (char *) &len, sizeof (len));
+
+	memset (&addr, 0, sizeof (addr));
+	addr.sin6_family = AF_INET6;
+	addr.sin6_port = htons (113);
+
+	if (bind (sok, (struct sockaddr *) &addr, sizeof (addr)) == SOCKET_ERROR)
+	{
+		closesocket (sok);
+		free (username);
+		return 0;
+	}
+
+	if (listen (sok, 1) == SOCKET_ERROR)
+	{
+		closesocket (sok);
+		free (username);
+		return 0;
+	}
+
+	len = sizeof (addr);
+	read_sok = accept (sok, (struct sockaddr *) &addr, &len);
+	closesocket (sok);
+
+	if (read_sok == INVALID_SOCKET)
+	{
+		free (username);
+		return 0;
+	}
+
+	identd_ipv6_is_running = FALSE;
+
+	if (WSAAddressToString ((struct sockaddr *) &addr, sizeof (addr), NULL, &ipv6buf, &ipv6buflen) == SOCKET_ERROR)
+	{
+		snprintf (ipv6buf, sizeof (ipv6buf) - 1, "[SOCKET ERROR: 0x%X]", WSAGetLastError ());
+	}
+
+	snprintf (outbuf, sizeof (outbuf), "%%\tServicing ident request from %s\n", ipv6buf);
+	PrintText (current_sess, outbuf);
+
+	recv (read_sok, buf, sizeof (buf) - 1, 0);
+	buf[sizeof (buf) - 1] = 0;	  /* ensure null termination */
+
+	p = strchr (buf, ',');
+
+	if (p)
+	{
+		snprintf (outbuf, sizeof (outbuf) - 1, "%d, %d : USERID : UNIX : %s\r\n", atoi (buf), atoi (p + 1), username);
+		outbuf[sizeof (outbuf) - 1] = 0;	/* ensure null termination */
+		send (read_sok, outbuf, strlen (outbuf), 0);
+	}
+
+	sleep (1);
+	closesocket (read_sok);
+	free (username);
+
+	return 0;
+}
+#endif
+
+void
 identd_start (char *username)
 {
 	DWORD tid;
 
+#ifdef USE_IPV6
+	DWORD tidv6;
+	if (identd_ipv6_is_running == FALSE)
+	{
+		identd_ipv6_is_running = TRUE;
+		CloseHandle (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) identd_ipv6,
+						 strdup (username), 0, &tidv6));
+	}
+#endif
+
 	if (identd_is_running == FALSE)
 	{
 		identd_is_running = TRUE;