소스 검색

Eggdrop 1.6.12 IPv6 Patch

Sascha Bielski 24 년 전
부모
커밋
6511796ff5
16개의 변경된 파일306개의 추가작업 그리고 55개의 파일을 삭제
  1. 3 0
      config.h.in
  2. 3 3
      src/botnet.c
  3. 2 0
      src/chanprog.c
  4. 1 1
      src/dcc.c
  5. 1 0
      src/eggdrop.h
  6. 4 4
      src/main.c
  7. 12 11
      src/mod/module.h
  8. 1 1
      src/mod/server.mod/server.c
  9. 2 2
      src/mod/server.mod/servmsg.c
  10. 2 2
      src/mod/share.mod/share.c
  11. 4 3
      src/modules.c
  12. 248 22
      src/net.c
  13. 4 3
      src/proto.h
  14. 4 2
      src/tcl.c
  15. 1 1
      src/tcldcc.c
  16. 14 0
      src/tclmisc.c

+ 3 - 0
config.h.in

@@ -72,6 +72,9 @@
 /* Define if you have the `fsync' function. */
 #undef HAVE_FSYNC
 
+/* Define if you have the `ipv6' support. */
+#define IPV6
+
 /* Define if you have the `getdtablesize' function. */
 #undef HAVE_GETDTABLESIZE
 

+ 3 - 3
src/botnet.c

@@ -1061,7 +1061,7 @@ static void botlink_resolve_success(int i)
   strcpy(dcc[i].u.bot->version, "(primitive bot)");
   dcc[i].u.bot->numver = idx;
   dcc[i].u.bot->port = dcc[i].port;		/* Remember where i started */
-  dcc[i].sock = getsock(SOCK_STRONGCONN);
+  dcc[i].sock =  getsock(SOCK_STRONGCONN,getprotocol(dcc[i].host));
   nfree(linker);
   if (dcc[i].sock < 0 ||
       open_telnet_raw(dcc[i].sock, iptostr(htonl(dcc[i].addr)),
@@ -1097,7 +1097,7 @@ static void failed_tandem_relay(int idx)
     return;
   }
   killsock(dcc[idx].sock);
-  dcc[idx].sock = getsock(SOCK_STRONGCONN);
+  dcc[idx].sock = getsock(SOCK_STRONGCONN,getprotocol(dcc[idx].host));
   dcc[uidx].u.relay->sock = dcc[idx].sock;
   dcc[idx].port++;
   dcc[idx].timeval = now;
@@ -1144,7 +1144,7 @@ void tandem_relay(int idx, char *nick, register int i)
     return;
   }
 
-  dcc[i].sock = getsock(SOCK_STRONGCONN | SOCK_VIRTUAL);
+  dcc[i].sock = getsock(SOCK_STRONGCONN | SOCK_VIRTUAL,getprotocol(bi->address));
   if (dcc[i].sock < 0) {
     lostdcc(i);
     dprintf(idx, "%s\n", MISC_NOFREESOCK);

+ 2 - 0
src/chanprog.c

@@ -288,6 +288,8 @@ void tell_verbose_status(int idx)
 	  botnetnick, ver, i, i == 1 ? "" : "s",
           (int) (expected_memory() / 1024));
 
+  dprintf(idx, "My Source was IPv6-patched by sb <sb@1shell.net>\n");
+
   now2 = now - online_since;
   s[0] = 0;
   if (now2 > 86400) {

+ 1 - 1
src/dcc.c

@@ -236,7 +236,7 @@ void failed_link(int idx)
 
   /* Try next port */
   killsock(dcc[idx].sock);
-  dcc[idx].sock = getsock(SOCK_STRONGCONN);
+  dcc[idx].sock = getsock(SOCK_STRONGCONN,getprotocol(dcc[idx].host));
   dcc[idx].port++;
   dcc[idx].timeval = now;
   if (dcc[idx].sock < 0 ||

+ 1 - 0
src/eggdrop.h

@@ -570,6 +570,7 @@ typedef struct {
   char		*outbuf;
   unsigned long  outbuflen;	/* Outbuf could be binary data	*/
   unsigned long	 inbuflen;	/* Inbuf could be binary data	*/
+  unsigned int af;
 } sock_list;
 
 enum {

+ 4 - 4
src/main.c

@@ -226,7 +226,7 @@ void write_debug()
      *       _not_ safe <cybah>
      */
     x = creat("DEBUG.DEBUG", 0644);
-    setsock(x, SOCK_NONSOCK);
+    setsock(x, SOCK_NONSOCK,AF_INET);
     if (x >= 0) {
       strncpyz(s, ctime(&now), sizeof s);
       dprintf(-x, "Debug (%s) written %s\n", ver, s);
@@ -251,7 +251,7 @@ void write_debug()
   putlog(LOG_MISC, "*", "* Please REPORT this BUG!");
   putlog(LOG_MISC, "*", "* Check doc/BUG-REPORT on how to do so.");
   x = creat("DEBUG", 0644);
-  setsock(x, SOCK_NONSOCK);
+  setsock(x, SOCK_NONSOCK,AF_INET);
   if (x < 0) {
     putlog(LOG_MISC, "*", "* Failed to write DEBUG");
   } else {
@@ -714,7 +714,7 @@ int main(int argc, char **argv)
 #include "patch.h"
   /* Version info! */
   egg_snprintf(ver, sizeof ver, "eggdrop v%s", egg_version);
-  egg_snprintf(version, sizeof version, "Eggdrop v%s (C) 1997 Robey Pointer (C) 2002 Eggheads",
+  egg_snprintf(version, sizeof version, "Eggdrop v%s+ipv6 (C) 1997 Robey Pointer (C) 2002 Eggheads",
 	       egg_version);
   /* Now add on the patchlevel (for Tcl) */
   sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver);
@@ -885,7 +885,7 @@ int main(int argc, char **argv)
       userlist = adduser(userlist, "HQ", "none", "-", USER_PARTY);
       dcc[n].user = get_user_by_handle(userlist, "HQ");
     }
-    setsock(STDOUT, 0);		/* Entry in net table */
+    setsock(STDOUT, 0,AF_INET);                /* Entry in net table */
     dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n");
     dcc_chatter(n);
   }

+ 12 - 11
src/mod/module.h

@@ -195,7 +195,7 @@
 /* 80 - 83 */
 #define new_dcc ((int (*) (struct dcc_table *, int))global[80])
 #define lostdcc ((void (*) (int))global[81])
-#define getsock ((int (*) (int))global[82])
+#define getsock ((int (*) (int,int))global[82])
 #define killsock ((void (*) (int))global[83])
 /* 84 - 87 */
 #define open_listen ((int (*) (int *))global[84])
@@ -438,20 +438,21 @@
 #define egg_strcatn ((int (*)(char *dst, const char *src, size_t max))global[265])
 #define clear_chanlist_member ((void (*)(const char *nick))global[266])
 #define fixfrom ((char *(*)(char *))global[267])
-/* 268 - 271 */
+/* 268 - 272 */
 /* Please don't modify socklist directly, unless there's no other way.
  * Its structure might be changed, or it might be completely removed,
  * so you can't rely on it without a version-check.
  */
-#define socklist (*(struct sock_list **)global[268])
-#define sockoptions ((int (*)(int, int, int))global[269])
-#define flush_inbuf ((int (*)(int))global[270])
-#define kill_bot ((void (*)(char *, char *))global[271])
-/* 272 - 275 */
-#define quit_msg ((char *)(global[272]))
-#define module_load ((char *(*)(char *))global[273])
-#define module_unload ((char *(*)(char *, char *))global[274])
-#define parties (*(int *)global[275])
+#define getprotocol ((int (*)(char *))global[268]) /* get protocol */
+#define socklist (*(struct sock_list **)global[269])
+#define sockoptions ((int (*)(int, int, int))global[270])
+#define flush_inbuf ((int (*)(int))global[271])
+#define kill_bot ((void (*)(char *, char *))global[272])
+/* 273 - 276 */
+#define quit_msg ((char *)(global[273]))
+#define module_load ((char *(*)(char *))global[274])
+#define module_unload ((char *(*)(char *, char *))global[275])
+#define parties (*(int *)global[276])
 
 /* This is for blowfish module, couldnt be bothered making a whole new .h
  * file for it ;)

+ 1 - 1
src/mod/server.mod/server.c

@@ -1523,7 +1523,7 @@ static void dcc_chat_hostresolved(int i)
     return;
   }
   egg_snprintf(ip, sizeof ip, "%lu", iptolong(htonl(dcc[i].addr)));
-  dcc[i].sock = getsock(0);
+  dcc[i].sock = getsock(0,getprotocol(ip));
   if (dcc[i].sock < 0 || open_telnet_dcc(dcc[i].sock, ip, buf) < 0) {
     neterror(buf);
     if(!quiet_reject)

+ 2 - 2
src/mod/server.mod/servmsg.c

@@ -1242,7 +1242,7 @@ static void connect_server(void)
     /* I'm resolving... don't start another server connect request */
     resolvserv = 1;
     /* Resolve the hostname. */
-    dcc_dnsipbyhost(dcc[servidx].host);
+    server_resolve_success(servidx);
   }
 }
 
@@ -1264,7 +1264,7 @@ static void server_resolve_success(int servidx)
   dcc[servidx].addr = dcc[servidx].u.dns->ip;
   strcpy(pass, dcc[servidx].u.dns->cbuf);
   changeover_dcc(servidx, &SERVER_SOCKET, 0);
-  serv = open_telnet(iptostr(htonl(dcc[servidx].addr)), dcc[servidx].port);
+  serv = open_telnet(dcc[servidx].host, dcc[servidx].port);
   if (serv < 0) {
     neterror(s);
     putlog(LOG_SERV, "*", "%s %s (%s)", IRC_FAILEDCONNECT, dcc[servidx].host,

+ 2 - 2
src/mod/share.mod/share.c

@@ -1115,7 +1115,7 @@ static void share_userfileq(int idx, char *par)
  */
 static void share_ufsend(int idx, char *par)
 {
-  char *ip, *port;
+  char *ip=NULL, *port;
   char s[1024];
   int i, sock;
   FILE *f;
@@ -1135,7 +1135,7 @@ static void share_ufsend(int idx, char *par)
   } else {
     ip = newsplit(&par);
     port = newsplit(&par);
-    sock = getsock(SOCK_BINARY);	/* Don't buffer this -> mark binary. */
+    sock = getsock(SOCK_BINARY,getprotocol(ip));       /* Don't buffer this -> mark binary. */
     if (sock < 0 || open_telnet_dcc(sock, ip, port) < 0) {
       killsock(sock);
       putlog(LOG_BOTS, "*", "Asynchronous connection failed!");

+ 4 - 3
src/modules.c

@@ -82,7 +82,7 @@ extern tand_t *tandbot;
 extern party_t *party;
 extern int parties;
 extern sock_list        *socklist;
-
+extern int getprotocol(char *);
 
 int cmd_die();
 int xtra_kill();
@@ -529,12 +529,13 @@ Function global_table[] =
   (Function) egg_strcatn,
   (Function) clear_chanlist_member,
   (Function) fixfrom,
-  /* 268 - 271 */
+  /* 268 - 272 */
+  (Function) getprotocol,
   (Function) & socklist,	/* sock_list *				*/
   (Function) sockoptions,
   (Function) flush_inbuf,
   (Function) kill_bot,
-  /* 272 - 275 */
+  /* 273 - 276 */
   (Function) quit_msg,		/* char *				*/
   (Function) module_load,
   (Function) module_unload,

+ 248 - 22
src/net.c

@@ -43,6 +43,8 @@ extern unsigned long	 otraffic_irc_today, otraffic_bn_today,
 char	hostname[121] = "";	/* Hostname can be specified in the config
 				   file					    */
 char	myip[121] = "";		/* IP can be specified in the config file   */
+char    myip6[121] = "";        /* IP can be specified in the config file   */
+char    hostname6[121] = "";    /* Hostname can be specified in the config file */
 char	firewall[121] = "";	/* Socks server for firewall		    */
 int	firewallport = 1080;	/* Default port of Sock4/5 firewalls	    */
 char	botuser[21] = "eggdrop"; /* Username of the user running the bot    */
@@ -71,6 +73,27 @@ IP my_atoul(char *s)
   return ret;
 }
 
+/* define the protocol based on a given host */
+int getprotocol(char *host)
+{
+#ifndef IPV6   
+  return AF_INET;
+#else
+  struct hostent *he;
+  if (!setjmp(alarmret)) {
+    alarm(resolve_timeout);
+    he = gethostbyname2(host,AF_INET6);
+    alarm(0);
+  } else
+    he=NULL;
+  if(!he)
+    {
+      return AF_INET; // we check no resolve on IPv4 and assume it, if v6 does not work
+    }
+  return AF_INET6;
+#endif
+}
+
 /* Initialize the socklist
  */
 void init_net()
@@ -97,6 +120,8 @@ int expmem_net()
   return tot;
 }
 
+struct hostent *myipv6he;
+char myipv6host[120];
 /* Get my ip number
  */
 IP getmyip()
@@ -106,8 +131,25 @@ IP getmyip()
   IP ip;
   struct in_addr *in;
 
+  myipv6he=NULL;
   /* Could be pre-defined */
-  if (myip[0]) {
+  #ifdef IPV6
+    if (myip6[0]) {
+      myipv6he=gethostbyname2(myip6,AF_INET6);
+      if(myipv6he==NULL)
+        fatal("Hostname IPV6 self-lookup failed.", 0);
+    }
+    if (hostname6[0]) {
+      myipv6he=gethostbyname2(hostname6,AF_INET6);
+      if(myipv6he==NULL)
+         fatal("Hostname IPV6 self-lookup failed.", 0);
+    }
+    if(myipv6he!=NULL)
+      {
+        inet_ntop(AF_INET6,&myipv6he,myipv6host,119);
+      }
+  #endif
+    if(myip[0]) {
     if ((myip[strlen(myip) - 1] >= '0') && (myip[strlen(myip) - 1] <= '9'))
       return (IP) inet_addr(myip);
   }
@@ -118,8 +160,9 @@ IP getmyip()
     gethostname(s, 120);
     hp = gethostbyname(s);
   }
-  if (hp == NULL)
+  if (hp == NULL && myipv6he==NULL)
     fatal("Hostname self-lookup failed.", 0);
+  if(hp==NULL) return 0;
   in = (struct in_addr *) (hp->h_addr_list[0]);
   ip = (IP) (in->s_addr);
   return ip;
@@ -223,7 +266,7 @@ int sockoptions(int sock, int operation, int sock_options)
 
 /* Return a free entry in the socket entry
  */
-int allocsock(int sock, int options)
+int allocsock(int sock, int options,int af_ty)
 {
   int i;
 
@@ -234,6 +277,7 @@ int allocsock(int sock, int options)
       socklist[i].inbuflen = socklist[i].outbuflen = 0;
       socklist[i].flags = options;
       socklist[i].sock = sock;
+      socklist[i].af=af_ty;
       return i;
     }
   }
@@ -243,9 +287,9 @@ int allocsock(int sock, int options)
 
 /* Request a normal socket for i/o
  */
-void setsock(int sock, int options)
+void setsock(int sock, int options, int af_ty)
 {
-  int i = allocsock(sock, options);
+  int i = allocsock(sock, options,af_ty);
   int parm;
 
   if (((sock != STDOUT) || backgrd) &&
@@ -265,12 +309,12 @@ void setsock(int sock, int options)
   fcntl(sock, F_SETFL, O_NONBLOCK);
 }
 
-int getsock(int options)
+int getsock(int options,int AF_DEF)
 {
-  int sock = socket(AF_INET, SOCK_STREAM, 0);
+  int sock = socket(AF_DEF, SOCK_STREAM, 0);
 
   if (sock >= 0)
-    setsock(sock, options);
+    setsock(sock, options,AF_DEF);
   else
     putlog(LOG_MISC, "*", "Warning: Can't create new socket!");
   return sock;
@@ -308,23 +352,38 @@ void killsock(register int sock)
  */
 static int proxy_connect(int sock, char *host, int port, int proxy)
 {
+  #ifdef IPV6
+   unsigned char x[32];
+  #else
   unsigned char x[10];
+  #endif
   struct hostent *hp;
   char s[256];
+  int af_ty;
   int i;
 
+  af_ty=getprotocol(host);
   /* socks proxy */
   if (proxy == PROXY_SOCKS) {
     /* numeric IP? */
-    if (host[strlen(host) - 1] >= '0' && host[strlen(host) - 1] <= '9') {
+    if ((host[strlen(host) - 1] >= '0' && host[strlen(host) - 1] <= '9') && af_ty!=AF_INET6) {
       IP ip = ((IP) inet_addr(host)); /* drummer */      
       egg_memcpy(x, &ip, 4);	/* Beige@Efnet */
     } else {
       /* no, must be host.domain */
       if (!setjmp(alarmret)) {
+#ifdef IPV6
 	alarm(resolve_timeout);
+       if(af_ty==AF_INET6)
+         {
+           hp = gethostbyname(host);
+         } else {
+#endif
 	hp = gethostbyname(host);
-	alarm(0);
+#ifdef IPV6
+         }
+        alarm(0);
+#endif
       } else {
 	hp = NULL;
       }
@@ -337,6 +396,16 @@ static int proxy_connect(int sock, char *host, int port, int proxy)
     for (i = 0; i < MAXSOCKS; i++)
       if (!(socklist[i].flags & SOCK_UNUSED) && socklist[i].sock == sock)
 	socklist[i].flags |= SOCK_PROXYWAIT; /* drummer */
+#ifdef IPV6
+    if(af_ty==AF_INET6)
+      egg_snprintf(s, sizeof s,"\004\001%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%s", (port >> 8) % 256, (port % 256),
+             x[0], x[1], x[2], x[3],
+             x[4], x[5], x[6], x[7],
+             x[9], x[9], x[10], x[11],
+             x[12], x[13], x[14], x[15],
+             botuser);
+    else
+#endif
     egg_snprintf(s, sizeof s, "\004\001%c%c%c%c%c%c%s", (port >> 8) % 256,
 		 (port % 256), x[0], x[1], x[2], x[3], botuser);
     tputs(sock, s, strlen(botuser) + 9); /* drummer */
@@ -347,6 +416,20 @@ static int proxy_connect(int sock, char *host, int port, int proxy)
   return sock;
 }
 
+/*
+ * Return protocol of socket
+*/
+
+int getsockproto(int sock)
+{
+  int i;
+  for (i = 0; i < MAXSOCKS; i++) {
+    if (socklist[i].sock == sock)
+      return socklist[i].af;
+  }
+  return AF_INET; // default
+}
+
 /* Starts a connection attempt to a socket
  * 
  * If given a normal hostname, this will be resolved to the corresponding
@@ -360,9 +443,15 @@ static int proxy_connect(int sock, char *host, int port, int proxy)
 int open_telnet_raw(int sock, char *server, int sport)
 {
   struct sockaddr_in name;
+#ifdef IPV6
+  struct sockaddr_in6 name6;
+  int rc;
+  unsigned long succ;
+#endif 
   struct hostent *hp;
   char host[121];
   int i, port;
+  int af_ty;
   volatile int proxy;
 
   /* firewall?  use socks */
@@ -380,6 +469,47 @@ int open_telnet_raw(int sock, char *server, int sport)
     strcpy(host, server);
     port = sport;
   }
+  #ifdef IPV6
+  af_ty=getprotocol(host);
+  if(af_ty==AF_INET6)
+    {
+      succ=getmyip();
+      bzero((char *) &name6, sizeof(struct sockaddr_in6));
+      
+      name6.sin6_family = AF_INET6;
+      if(myip[0]) 
+       {
+          if(myipv6he==NULL)
+           {
+             memcpy(&name6.sin6_addr,&in6addr_any,16);
+           } else {
+             memcpy(&name6.sin6_addr,myipv6he->h_addr,myipv6he->h_length);
+           }
+       } else {
+
+       }
+      if (bind(sock, (struct sockaddr *) &name6, sizeof(name6)) < 0) {
+       killsock(sock);
+       return -1;
+      }
+      bzero((char *) &name6, sizeof(struct sockaddr_in6));
+      name6.sin6_family = AF_INET6;
+      name6.sin6_port = htons(port);
+      if (!setjmp(alarmret)) {
+       alarm(resolve_timeout);
+       hp = gethostbyname2(host,AF_INET6);
+       alarm(0);
+      } else {
+       hp = NULL;
+      }
+      if (hp == NULL) {
+        killsock(sock);
+        return -2;
+      }
+      egg_memcpy((char *) &name6.sin6_addr, hp->h_addr, hp->h_length);
+      name6.sin6_family = hp->h_addrtype;
+    } else {
+#endif
   /* patch by tris for multi-hosted machines: */
   egg_bzero((char *) &name, sizeof(struct sockaddr_in));
 
@@ -409,12 +539,22 @@ int open_telnet_raw(int sock, char *server, int sport)
     egg_memcpy(&name.sin_addr, hp->h_addr, hp->h_length);
     name.sin_family = hp->h_addrtype;
   }
+ #ifdef IPV6
+     }
+ #endif
   for (i = 0; i < MAXSOCKS; i++) {
     if (!(socklist[i].flags & SOCK_UNUSED) && (socklist[i].sock == sock))
       socklist[i].flags = (socklist[i].flags & ~SOCK_VIRTUAL) | SOCK_CONNECT;
   }
-  if (connect(sock, (struct sockaddr *) &name,
-	      sizeof(struct sockaddr_in)) < 0) {
+#ifdef IPV6
+  if(af_ty==AF_INET6)  
+    rc=connect(sock, (struct sockaddr *) &name6,
+              sizeof(struct sockaddr_in6));
+  else 
+#endif
+    rc=connect(sock, (struct sockaddr *) &name,
+              sizeof(struct sockaddr_in));
+  if (rc < 0) {
     if (errno == EINPROGRESS) {
       /* Firewall?  announce connect attempt to proxy */
       if (firewall[0])
@@ -432,9 +572,9 @@ int open_telnet_raw(int sock, char *server, int sport)
 /* Ordinary non-binary connection attempt */
 int open_telnet(char *server, int port)
 {
-  int sock = getsock(0),
+  int sock = getsock(0,getprotocol(server)),
       ret = open_telnet_raw(sock, server, port);
-
+  putlog(LOG_DEBUG, "*", "net.c / open_telnet");
   if (ret < 0)
     killsock(sock);
   return ret;
@@ -445,8 +585,13 @@ int open_telnet(char *server, int port)
  */
 int open_address_listen(IP addr, int *port)
 {
-  int sock;
+  int sock=0;
+  int af_def;
+  unsigned long ipp;
   unsigned int addrlen;
+#ifdef IPV6
+  struct sockaddr_in6 name6;
+#endif
   struct sockaddr_in name;
 
   if (firewall[0]) {
@@ -455,7 +600,9 @@ int open_address_listen(IP addr, int *port)
     return -1;
   }
 
-  sock = getsock(SOCK_LISTEN);
+  if(getmyip()>0) {
+    af_def=AF_INET;
+    sock = getsock(SOCK_LISTEN,af_def);
   if (sock < 1)
     return -1;
 
@@ -465,10 +612,7 @@ int open_address_listen(IP addr, int *port)
   name.sin_addr.s_addr = addr;
   if (bind(sock, (struct sockaddr *) &name, sizeof(name)) < 0) {
     killsock(sock);
-    if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT)
-      return -2;
-    else
-      return -1;
+  goto tryv6;
   }
   /* what port are we on? */
   addrlen = sizeof(name);
@@ -479,8 +623,37 @@ int open_address_listen(IP addr, int *port)
   *port = ntohs(name.sin_port);
   if (listen(sock, 1) < 0) {
     killsock(sock);
+    goto tryv6;
+  }
+  return sock;
+}
+ tryv6:
+#ifdef IPV6
+  ipp=getmyip();
+  af_def=AF_INET6;
+  if(af_def==AF_INET6 && myipv6he!=NULL)
+    {
+      sock = getsock(SOCK_LISTEN,af_def);
+      bzero((char *) &name6,sizeof(name6));
+      name6.sin6_family=af_def;
+      name6.sin6_port=htons(*port);
+      memcpy(&name6.sin6_addr,myipv6he->h_addr,myipv6he->h_length);
+      if (bind(sock, (struct sockaddr *) &name6, sizeof(name6)) < 0) {
+               killsock(sock);
+               return -1;
+      }
+      addrlen = sizeof(name6);
+      if (getsockname(sock, (struct sockaddr *) &name6, &addrlen) < 0) {
+               killsock(sock);
+    return -1;
+  }
+      *port = ntohs(name6.sin6_port);
+      if (listen(sock, 1) < 0) {
+       killsock(sock);
     return -1;
   }
+    }
+#endif 
   return sock;
 }
 
@@ -532,6 +705,7 @@ char *iptostr(IP ip)
   return inet_ntoa(a);
 }
 
+unsigned long notalloc=0;
 /* Short routine to answer a connect received on a socket made previously
  * by open_listen ... returns hostname of the caller & the new socket
  * does NOT dispose of old "public" socket!
@@ -541,13 +715,38 @@ int answer(int sock, char *caller, unsigned long *ip, unsigned short *port,
 {
   int new_sock;
   unsigned int addrlen;
+  int af_ty;
+#ifdef IPV6
+  struct sockaddr_in6 from6;
+#endif
   struct sockaddr_in from;
+  af_ty=getsockproto(sock);
 
   addrlen = sizeof(struct sockaddr);
+  #ifdef IPV6
+    if(af_ty==AF_INET6)
+      {
+        addrlen = sizeof(from6);
+        new_sock = accept(sock, (struct sockaddr *) &from6, &addrlen);
+      } else {
+  #endif
+        addrlen = sizeof(struct sockaddr);
   new_sock = accept(sock, (struct sockaddr *) &from, &addrlen);
+  #ifdef IPV6    
+      }
+  #endif
+  
   if (new_sock < 0)
     return -1;
   if (ip != NULL) {
+#ifdef IPV6
+    if(af_ty==AF_INET6)
+      {
+       *ip=notalloc;
+       inet_ntop(AF_INET6,&from6,caller,119);
+       caller[120]=0;
+      } else {
+#endif
     *ip = from.sin_addr.s_addr;
     /* This is now done asynchronously. We now only provide the IP address.
      *
@@ -555,11 +754,21 @@ int answer(int sock, char *caller, unsigned long *ip, unsigned short *port,
      */
     strncpyz(caller, iptostr(*ip), 121);
     *ip = ntohl(*ip);
+#ifdef IPV6 
+      }
+#endif
   }
   if (port != NULL)
+    {
+#ifdef IPV6
+      if(af_ty==AF_INET6)
+       *port = ntohs(from6.sin6_port);
+      else
+#endif
     *port = ntohs(from.sin_port);
+    }
   /* Set up all the normal socket crap */
-  setsock(new_sock, (binary ? SOCK_BINARY : 0));
+  setsock(new_sock, (binary ? SOCK_BINARY : 0),af_ty);
   return new_sock;
 }
 
@@ -569,13 +778,21 @@ int open_telnet_dcc(int sock, char *server, char *port)
 {
   int p;
   unsigned long addr;
-  char sv[121];
+  char sv[500];
   unsigned char c[4];
 
   if (port != NULL)
     p = atoi(port);
   else
     p = 2000;
+#ifdef IPV6
+  if(getprotocol(server)==AF_INET6)
+    {
+      server[0]=0;
+      if(strlen(server)<500)
+       strcpy(sv,server);
+    } else {
+#endif
   if (server != NULL)
     addr = my_atoul(server);
   else
@@ -587,6 +804,9 @@ int open_telnet_dcc(int sock, char *server, char *port)
   c[2] = (addr >> 8) & 0xff;
   c[3] = addr & 0xff;
   sprintf(sv, "%u.%u.%u.%u", c[0], c[1], c[2], c[3]);
+#ifdef IPV6
+    }   
+#endif
   /* strcpy(sv,hostnamefromip(addr)); */
   p = open_telnet_raw(sock, sv, p);
   return p;
@@ -1147,6 +1367,12 @@ int sanitycheck_dcc(char *nick, char *from, char *ipaddy, char *port)
   /* It is disabled HERE so we only have to check in *one* spot! */
   if (!dcc_sanitycheck)
     return 1;
+  #ifdef IPV6
+  if(getprotocol(ipaddy)==AF_INET6)
+  {  
+      return 1;   
+  }
+  #endif
   if (prt < 1) {
     putlog(LOG_MISC, "*", "ALERT: (%s!%s) specified an impossible port of %u!",
 	   nick, from, prt);

+ 4 - 3
src/proto.h

@@ -238,9 +238,10 @@ IP my_atoul(char *);
 unsigned long iptolong(IP);
 IP getmyip();
 void neterror(char *);
-void setsock(int, int);
-int allocsock(int, int);
-int getsock(int);
+void setsock(int, int, int);
+int allocsock(int, int,int);
+int getsock(int, int); 
+int getprotocol(char *);
 char *hostnamefromip(unsigned long);
 void killsock(int);
 int answer(int, char *, unsigned long *, unsigned short *, int);

+ 4 - 2
src/tcl.c

@@ -51,7 +51,7 @@ extern int	default_flags, conmask, switch_logfiles_at, connect_timeout;
 extern int	firewallport, notify_users_at, flood_thr, ignore_time;
 extern int	reserved_port_min, reserved_port_max;
 extern char	origbotname[], botuser[], motdfile[], admin[], userfile[],
-		firewall[], helpdir[], notify_new[], hostname[], myip[],
+                firewall[], helpdir[], notify_new[], hostname[], hostname6[], myip[], myip6[],
 		moddir[], tempdir[], owner[], network[], botnetnick[],
 		bannerfile[], egg_version[], natip[], configfile[],
 		logfile_suffix[], textdir[], pid_file[];
@@ -438,8 +438,10 @@ static tcl_strings def_tcl_strings[] =
 #endif
   {"notify-newusers",	notify_new,	120,		0},
   {"owner",		owner,		120,		STR_PROTECT},
-  {"my-hostname",	hostname,	120,		0},
   {"my-ip",		myip,		120,		0},
+  {"my-hostname",       hostname,       120,            0},
+  {"my-ip6",            myip6,          120,            0},
+  {"my-hostname6",      hostname6,      120,            0},
   {"network",		network,	40,		0},
   {"whois-fields",	whois_fields,	1024,		0},
   {"nat-ip",		natip,		120,		0},

+ 1 - 1
src/tcldcc.c

@@ -827,7 +827,7 @@ static int tcl_connect STDVAR
     Tcl_AppendResult(irp, "out of dcc table space", NULL);
     return TCL_ERROR;
   }
-  sock = getsock(0);
+  sock = getsock(0,getprotocol(argv[1]));
   if (sock < 0) {
     Tcl_AppendResult(irp, MISC_NOFREESOCK, NULL);
     return TCL_ERROR;

+ 14 - 0
src/tclmisc.c

@@ -42,6 +42,19 @@ extern module_entry	*module_list;
 extern int max_logs;
 extern log_t *logs;
 extern Tcl_Interp *interp;
+extern char myipv6host[120];
+
+static int tcl_myip6 STDVAR      
+{
+  char s[120];
+  getmyip();                     
+  BADARGS(1, 1, "");
+  s[0]=0;
+  if(strlen(myipv6host)<120)
+    strcpy(s,myipv6host);
+  Tcl_AppendResult(irp, s, NULL);
+  return TCL_OK;
+}
 
 int expmem_tclmisc()
 {
@@ -648,6 +661,7 @@ tcl_cmds tclmisc_cmds[] =
   {"strftime",          tcl_strftime},
   {"ctime",		tcl_ctime},
   {"myip",		tcl_myip},
+  {"myip6",             tcl_myip6},
   {"rand",		tcl_rand},
   {"sendnote",		tcl_sendnote},
   {"dumpfile",		tcl_dumpfile},