浏览代码

Recoded IPv6 completely...
Linking via ipv6 now works
many code fixes from the eggdrop ipv6 patch
dcc/partyline support for ipv6
more to come...


svn: 116

Bryan Drewery 23 年之前
父节点
当前提交
4681cc7a5b
共有 19 个文件被更改,包括 311 次插入392 次删除
  1. 3 3
      src/botnet.c
  2. 3 8
      src/chanprog.c
  3. 21 1
      src/dcc.c
  4. 5 9
      src/dccutil.c
  5. 0 4
      src/dns.c
  6. 21 1
      src/eggdrop.h
  7. 13 31
      src/main.c
  8. 0 24
      src/mod/channels.mod/userchan.c
  9. 1 1
      src/mod/ctcp.mod/ctcp.c
  10. 3 2
      src/mod/module.h
  11. 6 10
      src/mod/server.mod/server.c
  12. 2 2
      src/mod/share.mod/share.c
  13. 1 1
      src/mod/transfer.mod/transfer.c
  14. 2 2
      src/mod/update.mod/update.c
  15. 5 3
      src/modules.c
  16. 215 259
      src/net.c
  17. 6 6
      src/proto.h
  18. 3 6
      src/tcldcc.c
  19. 1 19
      src/tclmisc.c

+ 3 - 3
src/botnet.c

@@ -1043,7 +1043,7 @@ static void botlink_resolve_success(int i)
   dcc[i].u.bot->numver = idx;
   dcc[i].u.bot->port = dcc[i].port;		/* Remember where i started */
 #ifdef USE_IPV6
-  dcc[i].sock = getsock(SOCK_STRONGCONN, getprotocol(dcc[i].host));
+  dcc[i].sock = getsock(SOCK_STRONGCONN, hostprotocol(dcc[i].host));
 #else
   dcc[i].sock = getsock(SOCK_STRONGCONN);
 #endif /* USE_IPV6 */
@@ -1083,7 +1083,7 @@ static void failed_tandem_relay(int idx)
   }
   killsock(dcc[idx].sock);
 #ifdef USE_IPV6
-  dcc[idx].sock = getsock(SOCK_STRONGCONN, getprotocol(dcc[idx].host));
+  dcc[idx].sock = getsock(SOCK_STRONGCONN, hostprotocol(dcc[idx].host));
 #else
   dcc[idx].sock = getsock(SOCK_STRONGCONN);
 #endif /* USE_IPV6 */
@@ -1134,7 +1134,7 @@ void tandem_relay(int idx, char *nick, register int i)
   }
 
 #ifdef USE_IPV6
-  dcc[i].sock = getsock(SOCK_STRONGCONN | SOCK_VIRTUAL, getprotocol(bi->address));
+  dcc[i].sock = getsock(SOCK_STRONGCONN | SOCK_VIRTUAL, hostprotocol(bi->address));
 #else
   dcc[i].sock = getsock(SOCK_STRONGCONN | SOCK_VIRTUAL);
 #endif /* USE_IPV6 */

+ 3 - 8
src/chanprog.c

@@ -569,6 +569,9 @@ void chanprog()
 
   admin[0] = 0;
   helpdir[0] = 0;
+
+  /* cache our ip on load instead of every 30 seconds -zip */
+  cache_my_ip();
   for (i = 0; i < max_logs; i++)
     logs[i].flags |= LF_EXPIRING;
   conmask = 0;
@@ -594,15 +597,7 @@ void chanprog()
   //setstatic = 0;
   loading = 1;
   readuserfile(userfile, &userlist);
-/* old
-  if (!readuserfile(userfile, &userlist)) {
-   char tmp[178];
-   egg_snprintf(tmp, sizeof tmp, MISC_NOUSERFILE, configfile);
-   fatal(tmp, 0);
-  }
-*/
   loading = 0;
-  //setstatic = 1;
 #endif
 
   load_internal_users();

+ 21 - 1
src/dcc.c

@@ -377,7 +377,7 @@ static void cont_link(int idx, char *buf, int ii)
     i = sizeof(sa);
     /* myip myport hubnick mynick */
     getsockname(socklist[snum].sock, (struct sockaddr *) &sa, &i);
-    sprintf(tmp,"%8x@%4x@%s@%s", getmyip(0), sa.sin_port, dcc[idx].nick, botnetnick);
+    sprintf(tmp,"%8x@%4x@%s@%s", getmyip(), sa.sin_port, dcc[idx].nick, botnetnick);
     MD5_Init(&ctx);
     MD5_Update(&ctx, tmp, strlen(tmp));
     MD5_Final(socklist[snum].ikey, &ctx);
@@ -556,6 +556,10 @@ static void display_dcc_bot(int idx, char *buf)
   buf[i++] = b_status(idx) & STAT_OFFEREDU ? 'B' : 'b';
   buf[i++] = b_status(idx) & STAT_SENDINGU ? 'D' : 'd';
   buf[i++] = b_status(idx) & STAT_GETTINGU ? 'E' : 'e';
+#ifdef USE_IPV6
+  if (sockprotocol(dcc[idx].sock) == AF_INET6 && dcc[idx].addr6[0])
+    buf[i++] = '6';
+#endif /* USE_IPV6 */
   buf[i++] = 0;
 }
 
@@ -1161,6 +1165,10 @@ static void display_dcc_chat(int idx, char *buf)
   buf[i++] = dcc[idx].status & STAT_PAGE ? 'P' : 'p';
   buf[i++] = dcc[idx].status & STAT_COLORM ? 'M' : 'm';
   buf[i++] = dcc[idx].status & STAT_COLORA ? 'A' : 'a';
+#ifdef USE_IPV6
+  if (sockprotocol(dcc[idx].sock) == AF_INET6 && dcc[idx].addr6[0])
+    buf[i++] = '6';
+#endif /* USE_IPV6 */
   simple_sprintf(buf + i, "/%d", dcc[idx].u.chat->channel);
 }
 
@@ -1253,6 +1261,9 @@ static void dcc_telnet(int idx, char *buf, int i)
   i = new_dcc(&DCC_DNSWAIT, sizeof(struct dns_info));
   dcc[i].sock = sock;
   dcc[i].addr = ip;
+#ifdef USE_IPV6
+  strcpy(dcc[i].addr6, s);
+#endif /* USE_IPV6 */
   dcc[i].port = port;
   dcc[i].timeval = now;
   strcpy(dcc[i].nick, "*");
@@ -1262,7 +1273,11 @@ static void dcc_telnet(int idx, char *buf, int i)
   dcc[i].u.dns->dns_type = RES_HOSTBYIP;
   dcc[i].u.dns->ibuf = dcc[idx].sock;
   dcc[i].u.dns->type = &DCC_IDENTWAIT;
+#ifdef USE_IPV6
+  dcc_telnet_hostresolved(i);
+#else
   dcc_dnshostbyip(ip);
+#endif /* USE_IPV6 */
 }
 
 static void dcc_telnet_hostresolved(int i)
@@ -1271,6 +1286,11 @@ static void dcc_telnet_hostresolved(int i)
   int j = 0, sock;
   char s[UHOSTLEN], s2[UHOSTLEN + 20];
 
+#ifdef USE_IPV6
+  if (sockprotocol(dcc[i].sock) == AF_INET6 && dcc[i].addr6[0])
+    strncpyz(dcc[i].host, dcc[i].addr6, UHOSTLEN);
+  else
+#endif /* USE_IPV6 */
   strncpyz(dcc[i].host, dcc[i].u.dns->host, UHOSTLEN);
 
   for (idx = 0; idx < dcc_total; idx++)

+ 5 - 9
src/dccutil.c

@@ -414,19 +414,19 @@ void tell_dcc(int zidx)
   }
   if(nicklen < 9) nicklen = 9;
   
-  egg_snprintf(format, sizeof format, "%%-4s %%-8s %%-5s %%-%us %%-17s %%s\n", 
+  egg_snprintf(format, sizeof format, "%%-4s %%-8s %%-5s %%-%us %%-25s %%s\n", 
                           nicklen);
   dprintf(zidx, format, "SOCK", "ADDR",     "PORT",  "NICK", "HOST", "TYPE");
   dprintf(zidx, format, "----", "--------", "-----", "---------", 
-                        "-----------------", "----");
+                        "-------------------------", "----");
 
   egg_snprintf(format, sizeof format, "%%-4d %%08X %%5d %%-%us %%-17s %%s\n", 
                           nicklen);
   /* Show server */
   for (i = 0; i < dcc_total; i++) {
     j = strlen(dcc[i].host);
-    if (j > 17)
-      j -= 17;
+    if (j > 25)
+      j -= 25;
     else
       j = 0;
     if (dcc[i].type && dcc[i].type->display)
@@ -714,11 +714,7 @@ Context;
         putlog(LOG_ERRORS, "*", STR("Can't open listening port - it's taken"));
       else {
         idx = new_dcc(&DCC_TELNET, 0);
-#ifdef USE_IPV6
-        dcc[idx].addr = 0x00000000; /* it's not big enough to hold '0xffffffffffffffffffffffffffffffff' =P */
-#else
-        dcc[idx].addr = iptolong(getmyip(0));
-#endif /* USE_IPV6 */
+        dcc[idx].addr = iptolong(getmyip());
         dcc[idx].port = port;
         dcc[idx].sock = i;
         dcc[idx].timeval = now;

+ 0 - 4
src/dns.c

@@ -414,10 +414,8 @@ void block_dns_hostbyip(IP ip)
   static char s[UHOSTLEN];
 
   if (!setjmp(alarmret)) {
-    debug0("dns.c:437 alarm");
     alarm(resolve_timeout);
     hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
-    debug0("dns.c:440 alarm");
     alarm(0);
     if (hp) {
       strncpyz(s, hp->h_name, sizeof s);
@@ -445,10 +443,8 @@ void block_dns_ipbyhost(char *host)
     struct hostent *hp;
     struct in_addr *in;
     IP ip = 0;
-    debug0("dns.c:468 alarm");
     alarm(resolve_timeout);
     hp = gethostbyname(host);
-    debug0("dns.c:472 alarm");
     alarm(0);
 
     if (hp) {

+ 21 - 1
src/eggdrop.h

@@ -302,7 +302,6 @@ struct dcc_t {
   IP addr;			/* IP address in host byte order	 */
 #ifdef USE_IPV6
   char addr6[121];              /* easier.. ipv6 address in regular notation (3ffe:80c0:225::) */
-  int af_type;                  /* AF_INET or AF_INET6 */
 #endif /* USE_IPV6 */
   unsigned int port;
   struct userrec *user;
@@ -423,6 +422,27 @@ struct script_info {
   char command[121];
 };
 
+#ifdef USE_IPV6
+#define SIZEOF_SOCKADDR(so) ((so).sa.sa_family == AF_INET6 ? sizeof(so.sin6) : sizeof(so.sin))
+#else
+#define SIZEOF_SOCKADDR(so) (sizeof(so.sin))
+#endif /* USE_IPV6 */
+
+#if !defined(IN6_IS_ADDR_V4MAPPED) 
+# define IN6_IS_ADDR_V4MAPPED(a) \
+        ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \
+         (((u_int32_t *) (a))[2] == htonl (0xffff)))
+#endif /* !defined(IN6_IS_ADDR_V4MAPPED) */
+
+#include <netinet/in.h>
+union sockaddr_union {
+  struct sockaddr sa;
+  struct sockaddr_in sin;
+#ifdef USE_IPV6
+  struct sockaddr_in6 sin6;
+#endif /* USE_IPV6 */
+};
+
 struct dns_info {
   void (*dns_success)(int);	/* is called if the dns request succeeds   */
   void (*dns_failure)(int);	/* is called if it fails		   */

+ 13 - 31
src/main.c

@@ -127,7 +127,7 @@ int	use_stderr = 1;		/* Send stuff to stderr instead of logfiles? */
 int	do_restart = 0;		/* .restart has been called, restart asap */
 int	die_on_sighup = 0;	/* die if bot receives SIGHUP */
 int	die_on_sigterm = 0;	/* die if bot receives SIGTERM */
-int	resolve_timeout = 15;	/* hostname/address lookup timeout */
+int	resolve_timeout = 10;	/* hostname/address lookup timeout */
 char	quit_msg[1024];		/* quit message */
 time_t	now;			/* duh, now :) */
 
@@ -253,11 +253,7 @@ void write_debug()
      *       _not_ safe <cybah>
      */
     x = creat("DEBUG.DEBUG", 0600);
-#ifdef USE_IPV6
-    setsock(x, SOCK_NONSOCK, AF_INET);
-#else
     setsock(x, SOCK_NONSOCK);
-#endif /* USE_IPV6 */
     if (x >= 0) {
       strncpyz(s, ctime(&now), sizeof s);
       dprintf(-x, "Debug (%s) written %s\n", ver, s);
@@ -280,11 +276,7 @@ void write_debug()
 	 cx_line[cx_ptr], cx_note[cx_ptr][0] ? cx_note[cx_ptr] : "");
 //  putlog(LOG_MISC, "*", "* Please REPORT this BUG to bryan (send him ~/DEBUG as well)!");
   x = creat("DEBUG", 0600);
-#ifdef USE_IPV6
-  setsock(x, SOCK_NONSOCK, AF_INET);
-#else
   setsock(x, SOCK_NONSOCK);
-#endif /* USE_IPV6 */
   if (x < 0) {
     putlog(LOG_MISC, "*", "* Failed to write DEBUG");
   } else {
@@ -936,13 +928,7 @@ static inline void garbage_collect(void)
   else
     run_cnt++;
 }
-/*
-static void do_arg(char *s)
-{
-  if (s[0] != '-')
-    strncpyz(configfile, s, sizeof configfile);
-}
-*/
+
 int crontab_exists() {
   char buf[2048], *out=NULL;
   sprintf(buf, STR("crontab -l | grep \"%s\" | grep -v \"^#\""), binname);
@@ -1038,7 +1024,10 @@ static void gotspawn(char *filename)
     temps = (char *) decrypt_string(netpass, decryptit(templine));
 
     pscloak = atoi(newsplit(&temps));
-
+#ifdef S_PSCLOAK
+    if (SDEBUG)
+      printf("GOTSPAWN, NOT CLOAKING\n");
+#endif /* S_PSCLOAK */
     nick = newsplit(&temps);
     if (!nick)
       fatal("invalid config (2).",0);
@@ -1076,7 +1065,7 @@ static void gotspawn(char *filename)
     }
   }
   fclose(fp);
-  unlink(filename);
+//  unlink(filename);
 }
 
 static int spawnbot(char *bin, char *nick, char *ip, char *host, char *ipsix, int cloak)
@@ -1093,7 +1082,7 @@ static int spawnbot(char *bin, char *nick, char *ip, char *host, char *ipsix, in
   if (!(fp = fopen(buf, "w")))
     fatal("Cannot create spawnfiles...", 0);
 
-  lfprintf(fp, "%d %s %s %s %s\n", cloak, nick, ip, host, ipsix);
+  lfprintf(fp, "%d %s %s %s %s\n", cloak, nick, ip, host ? host : ".", ipsix ? ipsix : ".");
 
   fflush(fp);
   fclose(fp);
@@ -1530,6 +1519,10 @@ Context;
         }
       } else if (c[0] == '!') { //local tcl exploit
         if (c[1] == '-') { //dont use pscloak
+#ifdef S_PSCLOAK
+          if (SDEBUG)
+            printf("NOT CLOAKING\n");
+#endif /* S_PSCLOAK */
           pscloak = 0;
         } else {
           newsplit(&temps);
@@ -1682,13 +1675,6 @@ Context;
     }
   }
 
-#ifdef LEAF
-{
-  long test = iptolong(getmyip(1));
-  test = 0;
-}
-#endif
-
 #ifdef LEAF
 #ifdef S_PSCLOAK
   if (pscloak) {
@@ -1755,7 +1741,7 @@ Context;
   if (!backgrd && term_z) {
     int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info));
 
-    dcc[n].addr = iptolong(getmyip(1));
+    dcc[n].addr = iptolong(getmyip());
     dcc[n].sock = STDOUT;
     dcc[n].timeval = now;
     dcc[n].u.chat->con_flags = conmask;
@@ -1769,11 +1755,7 @@ Context;
       userlist = adduser(userlist, "HQ", "none", "-", USER_ADMIN | USER_OWNER | USER_MASTER | USER_VOICE | USER_OP | USER_PARTY | USER_CHUBA | USER_HUBA);
       dcc[n].user = get_user_by_handle(userlist, "HQ");
     }
-#ifdef USE_IPV6
-    setsock(STDOUT, 0, AF_INET); /* Entry in net table */
-#else
     setsock(STDOUT, 0);          /* Entry in net table */
-#endif /* USE_IPV6 */
     dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n");
     dcc_chatter(n);
   }

+ 0 - 24
src/mod/channels.mod/userchan.c

@@ -1061,30 +1061,6 @@ static int write_config(FILE *f, int idx)
         return 0;
     }
 
-/* old tcl shit..
-  int total = 0, i = 0;
-
-//fix proc config to accept NUM 0 for total, num for specific entry.
-  if (Tcl_Eval(interp, "config_start") == TCL_OK) { //make the tcl copy over vital vars first.
-   if (Tcl_Eval(interp, "array size a") == TCL_OK) { //get total config entries
-    total = atoi(interp->result);
-    for (i = 0; i < total; i++) { //loop each entry
-     buf[0] = '\0';
-     sprintf(buf, "config %i", i); //call proc config with i, returns + set...
-     if (Tcl_Eval(interp, buf) == TCL_OK) {
-       if (lfprintf(f, "%s\n", interp->result) == EOF) //write each config %i entry on a line alone.
-        return 0;
-     } else
-       return 0;
-    }
-//    if (lfprintf(f, "+ config_end\n") == EOF) //write config_end to userfile
-//      return 0;
-   } else 
-     return 0;
-  } else
-    return 0;
-*/
-
 #ifdef S_DCCPASS
   for (cp = cmdpass; cp; cp = cp->next)
     if (lfprintf(f, "- %s %s\n", cp->name, cp->pass) == EOF)

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

@@ -698,7 +698,7 @@ static int ctcp_CHAT(char *nick, char *uhost, char *handle, char *object, char *
       /* do me a favour and don't change this back to a CTCP reply,
        * CTCP replies are NOTICE's this has to be a PRIVMSG
        * -poptix 5/1/1997 */
-      dprintf(DP_HELP, "PRIVMSG %s :\001DCC CHAT chat %lu %u\001\n", nick, iptolong(getmyip(0)), dcc[ix].port);
+      dprintf(DP_HELP, "PRIVMSG %s :\001DCC CHAT chat %lu %u\001\n", nick, iptolong(getmyip()), dcc[ix].port);
     }
 
 

+ 3 - 2
src/mod/module.h

@@ -193,7 +193,7 @@
 #define list_contains ((int (*) (struct list_type *, struct list_type *))global[75])
 /* 76 - 79 */
 #define answer ((int (*) (int,char *,unsigned long *,unsigned short *,int))global[76])
-#define getmyip ((IP (*) (int))global[77])
+#define getmyip ((IP (*) (void))global[77])
 #define neterror ((void (*) (char *))global[78])
 #define tputs ((void (*) (int, char *,unsigned int))global[79])
 /* 80 - 83 */
@@ -452,7 +452,7 @@
  * Its structure might be changed, or it might be completely removed,
  * so you can't rely on it without a version-check.
  */
-#define getprotocol ((int (*)(char *))global[268]) /* get protocol */
+#define sockprotocol ((int (*)(int))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])
@@ -534,6 +534,7 @@
 #define open_listen_by_af ((int (*) (int *, int))global[328])
 /* 329 - 332 */
 #define egg_inet_ntop ((int (*)(int af, const void *src, char *dst, socklen_t size))global[329])
+#define hostprotocol ((int (*) (char *))global[330])
 
 
 

+ 6 - 10
src/mod/server.mod/server.c

@@ -1623,17 +1623,13 @@ static int ctcp_DCC_CHAT(char *nick, char *from, char *handle,
       return 1;
     }
 #ifdef USE_IPV6
-    if (ip[4] == ':') {
+    if (hostprotocol(ip) == AF_INET6 && sockprotocol(dcc[i].sock) == AF_INET6) {
       debug1("ipv6 addr: %s",ip);
       strcpy(dcc[i].addr6,ip);
       debug1("ipv6 addr: %s",dcc[i].addr6);
-      dcc[i].af_type = AF_INET6;
-    } else {
-      dcc[i].addr = my_atoul(ip);
-    }
-#else
-    dcc[i].addr = my_atoul(ip);
+    } else 
 #endif /* USE_IPV6 */
+    dcc[i].addr = my_atoul(ip);
     dcc[i].port = atoi(prt);
     dcc[i].sock = -1;
     strcpy(dcc[i].nick, u->handle);
@@ -1641,7 +1637,7 @@ static int ctcp_DCC_CHAT(char *nick, char *from, char *handle,
     dcc[i].timeval = now;
     dcc[i].user = u;
 #ifdef USE_IPV6
-    if (dcc[i].af_type != AF_INET6) {
+    if (sockprotocol(dcc[i].sock) != AF_INET6) {
 #endif /* USE_IPV6 */
 /* remove me? */
       dcc[i].addr = my_atoul(ip);
@@ -1673,14 +1669,14 @@ static void dcc_chat_hostresolved(int i)
     return;
   }
 #else
-  if (dcc[i].af_type == AF_INET6) {
+  if (sockprotocol(dcc[i].sock) == AF_INET6) {
     strcpy(ip,dcc[i].addr6); /* safe, addr6 is 121 */
     debug0("afinet6, af_type, strcpy");
   } else
 #endif /* !USE_IPV6 */
   egg_snprintf(ip, sizeof ip, "%lu", iptolong(htonl(dcc[i].addr)));
 #ifdef USE_IPV6
-  if (dcc[i].af_type == AF_INET6) {
+  if (sockprotocol(dcc[i].sock) == AF_INET6) {
 #  ifdef IPV6_DEBUG
     debug2("af_inet6 %s / %s", dcc[i].addr6, ip);
 #  endif /* IPV6_DEBUG */

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

@@ -1136,7 +1136,7 @@ static void share_userfileq(int idx, char *par)
  */
 static void share_ufsend(int idx, char *par)
 {
-    sock = getsock(SOCK_BINARY, getprotocol(ip)); /* Don't buffer this -> mark binary. */
+  char *ip=NULL, *port;
   char s[1024];
   int i, sock;
   FILE *f;
@@ -1967,7 +1967,7 @@ static void start_sending_users(int idx)
 
   if (!uff_call_sending(idx, share_file)) {
     unlink(share_file);
-	    iptolong(natip[0] ? (IP) inet_addr(natip) : getmyip(0)),
+    dprintf(idx, "s e %s\n", "uff parsing failed");
     putlog(LOG_BOTS, "@", "uff parsing failed");
     dcc[idx].status &= ~(STAT_SHARE | STAT_SENDING | STAT_AGGRESSIVE);
     return;

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

@@ -1614,7 +1614,7 @@ static int raw_dcc_resend_send(char *filename, char *nick, char *from,
   if (nick[0] != '*') {
     dprintf(DP_HELP, "PRIVMSG %s :\001DCC %sSEND %s %lu %d %lu\001\n", nick,
 	    resend ? "RE" :  "", nfn,
-	    iptolong(natip[0] ? (IP) inet_addr(natip) : getmyip(0)), port,
+	    iptolong(natip[0] ? (IP) inet_addr(natip) : getmyip()), port,
 	    dccfilesize);
     putlog(LOG_FILES, "*",TRANSFER_BEGIN_DCC, resend ? TRANSFER_RE :  "",
 	   nfn, nick);

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

@@ -105,7 +105,7 @@ static void update_ufsend(int idx, char *par)
     ip = newsplit(&par);
     port = newsplit(&par);
 #ifdef USE_IPV6
-    sock = getsock(SOCK_BINARY, getprotocol(ip)); /* Don't buffer this -> mark binary. */
+    sock = getsock(SOCK_BINARY, hostprotocol(ip)); /* Don't buffer this -> mark binary. */
 #else
     sock = getsock(SOCK_BINARY); /* Don't buffer this -> mark binary. */
 #endif /* USE_IPV6 */
@@ -361,7 +361,7 @@ static void start_sending_binary(int idx)
     i = dcc_total - 1;
     strcpy(dcc[i].host, dcc[idx].nick);		/* Store bot's nick */
     dprintf(idx, "sb us %lu %d %lu\n",
-	    iptolong(natip[0] ? (IP) inet_addr(natip) : getmyip(0)),
+	    iptolong(natip[0] ? (IP) inet_addr(natip) : getmyip()),
 	    dcc[i].port, dcc[i].u.xfer->length);
   }
 #endif

+ 5 - 3
src/modules.c

@@ -39,7 +39,6 @@ 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();
@@ -139,6 +138,7 @@ void (*dns_ipbyhost) (char *) = block_dns_ipbyhost;
 module_entry *module_list;
 dependancy *dependancy_list = NULL;
 
+
 /* The horrible global lookup table for functions
  * BUT it makes the whole thing *much* more portable than letting each
  * OS screw up the symbols their own special way :/
@@ -504,7 +504,7 @@ Function global_table[] =
   (Function) clear_chanlist_member,
   (Function) fixfrom,
   /* 268 - 272 */
-  (Function) getprotocol,
+  (Function) sockprotocol,
   (Function) & socklist,	/* sock_list *				*/
   (Function) sockoptions,
   (Function) flush_inbuf,
@@ -578,7 +578,8 @@ Function global_table[] =
   (Function) replace,
   (Function) degarble,
   (Function) egg_inet_ntop,
-  (Function) open_listen_by_af
+  (Function) open_listen_by_af,
+  (Function) hostprotocol
 
 
 };
@@ -812,6 +813,7 @@ void *mod_malloc(int size, const char *modname, const char *filename, int line)
 #endif
 }
 
+
 void *mod_realloc(void *ptr, int size, const char *modname,
 		  const char *filename, int line)
 {

+ 215 - 259
src/net.c

@@ -44,6 +44,12 @@ extern unsigned long	 otraffic_irc_today, otraffic_bn_today,
 			 otraffic_dcc_today, otraffic_filesys_today,
 			 otraffic_trans_today, otraffic_unknown_today;
 
+union sockaddr_union cached_myip4_so;
+#ifdef USE_IPV6
+union sockaddr_union cached_myip6_so;
+unsigned long notalloc = 0;
+#endif /* USE_IPV6 */
+
 char	hostname[121] = "";	/* Hostname can be specified in the config
 				   file					    */
 char	myip[121] = "";		/* IP can be specified in the config file   */
@@ -58,13 +64,6 @@ sock_list *socklist = NULL;	/* Enough to be safe			    */
 int	MAXSOCKS = 0;
 jmp_buf	alarmret;		/* Env buffer for alarm() returns	    */
 
-#ifdef USE_IPV6
-struct hostent *myipv6he;
-char myipv6host[120];
-unsigned long notalloc = 0;
-#endif /* USE_IPV6 */
-
-
 /* Types of proxy */
 #define PROXY_SOCKS   1
 #define PROXY_SUN     2
@@ -84,7 +83,7 @@ IP my_atoul(char *s)
   return ret;
 }
 
-int getprotocol(char *host)
+int hostprotocol(char *host)
 {
 #ifdef USE_IPV6
   struct hostent *he;
@@ -111,6 +110,62 @@ int getprotocol(char *host)
 #endif /* USE_IPV6 */
 }
 
+/* get the protocol used on a socket */
+int sockprotocol(int socket)
+{
+  struct sockaddr sa;
+  int i = sizeof(sa);
+
+  if (getsockname(socket, &sa, &i))
+    return -1;
+  else
+    return sa.sa_family;
+}
+
+/* AF_INET-independent resolving routine */
+int get_ip(char *hostname, union sockaddr_union *so)
+{
+#ifdef USE_IPV6
+  struct addrinfo hints, *ai, *res;
+  int error;
+#else
+  struct hostent *hp;
+#endif /* USE_IPV6 */
+
+  memset(so, 0, sizeof(union sockaddr_union));
+  debug1("get_ip(%s)", hostname);
+
+  if (!hostname || !hostname[0])
+    return 1;
+#ifdef USE_IPV6
+  memset(&hints, 0, sizeof(struct addrinfo));
+  hints.ai_socktype = SOCK_STREAM;
+
+  if ((error = getaddrinfo(hostname, NULL, &hints, &res)))
+    return error;
+
+  error = 1;
+  for (ai = res; ai != NULL; ai = ai->ai_next) {
+    if ((ai->ai_family == AF_INET6) || (ai->ai_family == AF_INET)) {
+      memcpy(so, ai->ai_addr, sizeof(union sockaddr_union));
+      error = 0;
+      break;
+    }
+  }
+
+  freeaddrinfo(res);
+  return error;
+#else
+
+  if (!(hp = gethostbyname(hostname)))
+    return -1;
+
+  memcpy(&so->sin.sin_addr, hp->h_addr, 4);
+  so->sin.sin_family = AF_INET;
+  return 0;
+#endif /* USE_IPV6 */
+}
+
 /* Initialize the socklist
  */
 void init_net()
@@ -140,73 +195,63 @@ int expmem_net()
 
 /* Get my ip number
  */
-IP getmyip(int dfatal)
+IP getmyip() {
+  return (IP) cached_myip4_so.sin.sin_addr.s_addr;
+}
+
+/* see if it's necessary to set inaddr_any... because if we can't resolve, we die anyway */
+void cache_my_ip()
 {
-  struct hostent *hp;
   char s[121];
-  IP ip;
-  struct in_addr *in;
-#if defined(USE_IPV6) && !defined(HAVE_GETHOSTBYNAME2)
-  int error_num;
-#endif /* USE_IPV6 && !HAVE_GETHOSTBYNAME2 */
+  int error, any = 0;
 
-#ifdef USE_IPV6
-  myipv6he=NULL;
-
-    if (myip6[0]) {
-      if (SDEBUG && dfatal)
-        printf(STR("myip6: %s\n"), myip6);
-#    ifdef HAVE_GETHOSTBYNAME2
-      myipv6he = gethostbyname2(myip6, AF_INET6);
-#    else
-      myipv6he = getipnodebyname(myip6, AF_INET6, AI_DEFAULT, &error_num);
-#    endif /* !HAVE_GETHOSTBYNAME2 */
-    }
-
-    if (hostname6[0] && myipv6he == NULL) {
-      if (SDEBUG && dfatal)
-        printf(STR("hostname6: %s\n"), hostname6);
-      myipv6he=gethostbyname2(hostname6,AF_INET6);
+  debug0("cache_my_ip()");
+  memset(&cached_myip4_so, 0, sizeof(union sockaddr_union));
 
-      if(myipv6he == NULL && dfatal && !myip6[0])
-         fatal(STR("Hostname IPV6 self-lookup failed (include IPV6 ip in conf)."), 0);
-    }
+#ifdef USE_IPV6
+  memset(&cached_myip6_so, 0, sizeof(union sockaddr_union));
+
+  if (myip6 != NULL && myip6[1]) {
+    if (SDEBUG)
+      printf("myip6: %s\n", myip6);
+    if (get_ip(myip6, &cached_myip6_so))
+      any = 1;
+  } else if (hostname != NULL && hostname6[1]) {
+    if (SDEBUG)
+      printf("myhostname6: %s\n", hostname6);
+    if (get_ip(hostname6, &cached_myip6_so))
+      any = 1;
+  } else
+    any = 1;
 
-    if(myipv6he != NULL)
-      egg_inet_ntop(AF_INET6, &myipv6he, myipv6host, 119);
+  if (any) {
+    if (SDEBUG)
+      printf("IPV6 addr_any is set.\n");
+    cached_myip6_so.sin6.sin6_family = AF_INET6;
+    cached_myip6_so.sin6.sin6_addr = in6addr_any;
+  }
 #endif /* USE_IPV6 */
 
-  /* Could be pre-defined */
+  error = 0;
   if (myip[0]) {
-    if ((myip[strlen(myip) - 1] >= '0') && (myip[strlen(myip) - 1] <= '9')) {
-      if (SDEBUG)
-        printf("myip1: %d\n", inet_addr(myip));
-      return (IP) inet_addr(myip);
-    }
-  }
-  /* Also could be pre-defined */
-  if (hostname[0])
-    hp = gethostbyname(hostname);
-  else {
+    if (get_ip(myip, &cached_myip4_so))
+      error = 1;
+  } else if (hostname[0]) {
+    if (get_ip(hostname, &cached_myip4_so))
+      error = 2;
+  } else {
     gethostname(s, 120);
-    hp = gethostbyname(s);
+    if (get_ip(hostname, &cached_myip4_so)) {
+//      error = 3;
+      cached_myip4_so.sin.sin_family = AF_INET;
+      cached_myip4_so.sin.sin_addr.s_addr = INADDR_ANY;
+    }
   }
-#ifdef USE_IPV6
-  if (hp == NULL && myipv6he == NULL && dfatal)
-#else
-  if (hp == NULL)
-#endif /* USE_IPV6 */
-    fatal(STR("Hostname self-lookup failed.  Set 'my-ip' in the config"), 0);
 
-#ifdef USE_IPV6
-  if(hp == NULL)
-    return 0;
-#endif /* USE_IPV6 */
-  in = (struct in_addr *) (hp->h_addr_list[0]);
-  ip = (IP) (in->s_addr);
-  if (SDEBUG)
-    printf("myip2: %d\n", ip);
-  return ip;
+  if (error) {
+    putlog(LOG_DEBUG, "*", "Hostname self-lookup error: %d", error);
+    fatal("Hostname self-lookup failed.", 0);
+  }
 }
 
 void neterror(char *s)
@@ -312,11 +357,7 @@ int sockoptions(int sock, int operation, int sock_options)
 
 /* Return a free entry in the socket entry
  */
-#ifdef USE_IPV6
-int allocsock(int sock, int options, int af_ty)
-#else
 int allocsock(int sock, int options)
-#endif /* USE_IPV6 */
 {
   int i;
 
@@ -327,9 +368,6 @@ int allocsock(int sock, int options)
       socklist[i].inbuflen = socklist[i].outbuflen = 0;
       socklist[i].flags = options;
       socklist[i].sock = sock;
-#ifdef USE_IPV6
-      socklist[i].af = af_ty;
-#endif /* USE_IPV6 */
       socklist[i].encstatus = 0;
       socklist[i].gz = 0;
       egg_bzero(&socklist[i].okey, sizeof(socklist[i].okey));
@@ -343,15 +381,9 @@ int allocsock(int sock, int options)
 
 /* Request a normal socket for i/o
  */
-#ifdef USE_IPV6
-void setsock(int sock, int options, int af_ty)
-{
-  int i = allocsock(sock, options, af_ty), parm;
-#else
 void setsock(int sock, int options)
 {
   int i = allocsock(sock, options), parm;
-#endif /* USE_IPV6 */
 
   if (((sock != STDOUT) || backgrd) && !(socklist[i].flags & SOCK_NONSOCK)) {
     parm = 1;
@@ -372,25 +404,21 @@ void setsock(int sock, int options)
 #ifdef USE_IPV6
 int getsock(int options, int af_def)
 {
-  int sock = socket(af_def, SOCK_STREAM, 0);
 #else
 int getsock(int options)
 {
-  int sock = socket(AF_INET, SOCK_STREAM, 0);
+  int af_def = AF_INET;
 #endif /* USE_IPV6 */
+  int sock;
+  sock = socket(af_def, SOCK_STREAM, 0);
 
   if (sock >= 0)
-#ifdef USE_IPV6
-    setsock(sock, options, af_def);
-#else
     setsock(sock, options);
-#endif /* USE_IPV6 */
   else
     putlog(LOG_MISC, "*", "Warning: Can't create new socket!");
   return sock;
 }
 
-
 /* Done with a socket
  */
 void real_killsock(register int sock, const char *file, int line)
@@ -435,7 +463,7 @@ static int proxy_connect(int sock, char *host, int port, int proxy)
   int i;
 
 #ifdef USE_IPV6
-  af_ty = getprotocol(host);
+  af_ty = sockprotocol(sock);
 #endif /* USE_IPV6 */
   /* socks proxy */
   if (proxy == PROXY_SOCKS) {
@@ -490,24 +518,6 @@ static int proxy_connect(int sock, char *host, int port, int proxy)
   return sock;
 }
 
-/*
- * Return protocol of socket
-*/
-int getsockproto(int sock)
-{
-#ifdef USE_IPV6
-  int i;
-  for (i = 0; i < MAXSOCKS; i++) {
-    if (socklist[i].sock == sock)
-      return socklist[i].af;
-  }
-  return AF_INET;
-#else
-  return 0;
-#endif /* USE_IPV6 */
-}
-
-
 /* Starts a connection attempt to a socket
  * 
  * If given a normal hostname, this will be resolved to the corresponding
@@ -520,18 +530,9 @@ int getsockproto(int sock)
  */
 int open_telnet_raw(int sock, char *server, int sport)
 {
-  struct sockaddr_in name;
-#ifdef USE_IPV6
-  struct sockaddr_in6 name6;
-  unsigned long succ;
-  int af_ty;
-#  ifndef HAVE_GETHOSTBYNAME2
-  int error_num;
-#  endif /* !HAVE_GETHOSTBYNAME2 */
-#endif /* USE_IPV6 */
-  struct hostent *hp;
+  union sockaddr_union so;
   char host[121];
-  int i, port, rc;
+  int i, error, port, rc;
   volatile int proxy;
 
   /* firewall?  use socks */
@@ -549,91 +550,52 @@ int open_telnet_raw(int sock, char *server, int sport)
     strcpy(host, server);
     port = sport;
   }
+
+  error = 0;
+  if (!setjmp(alarmret)) {
+    alarm(resolve_timeout);
+    if (!get_ip(host,&so)) {
+      alarm(0);
+      /* ok, we resolved it, bind an appropriate ip */
 #ifdef USE_IPV6
-  af_ty = getprotocol(host);
-  if (af_ty == AF_INET6) {
-    succ = getmyip(0);
-    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);
-    }
-    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);
-#  ifdef HAVE_GETHOSTBYNAME2
-      hp = gethostbyname2(host, AF_INET6);
-#  else
-      hp = getipnodebyname(host, AF_INET6, AI_DEFAULT, &error_num);
-#  endif /* HAVE_GETHOSTBYNAME2 */
-     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;
-#  ifndef HAVE_GETHOSTBYNAME2
-    freehostent(myipv6he);
-#  endif /* !HAVE_GETHOSTBYNAME2 */
-  } else {
+      if (so.sa.sa_family == AF_INET6) {
+        if (bind(sock, &cached_myip6_so.sa, SIZEOF_SOCKADDR(cached_myip6_so)) < 0) {
+          killsock(sock);
+          return -1;
+        }
+      } else {
+#endif
+        if (bind(sock, &cached_myip4_so.sa, SIZEOF_SOCKADDR(cached_myip4_so)) < 0) {
+          killsock(sock);
+          return -3;
+        }
+#ifdef USE_IPV6
+      }
+
+      if (so.sa.sa_family == AF_INET6)
+        so.sin6.sin6_port = htons(port);
+      else
 #endif /* USE_IPV6 */
-    egg_bzero((char *) &name, sizeof(struct sockaddr_in));
+        so.sin.sin_port = htons(port);
 
-    name.sin_family = AF_INET;
-    name.sin_addr.s_addr = (myip[0] ? getmyip(0) : INADDR_ANY);
-    if (bind(sock, (struct sockaddr *) &name, sizeof(name)) < 0) {
-      putlog(LOG_MISC, "*", "Error binding to ip: %s", strerror(errno));
-      return -1;
+    } else {
+      alarm(0);
+      error = 1;
     }
-    egg_bzero((char *) &name, sizeof(struct sockaddr_in));
+  }
 
-    name.sin_family = AF_INET;
-    name.sin_port = htons(port);
-    /* Numeric IP? */
-    if ((host[strlen(host) - 1] >= '0') && (host[strlen(host) - 1] <= '9'))
-      name.sin_addr.s_addr = inet_addr(host);
-    else {
-      /* No, must be host.domain */
-      debug0("WARNING: open_telnet_raw() is about to block in gethostbyname()!");
-      if (!setjmp(alarmret)) {
-        alarm(resolve_timeout);
-        hp = gethostbyname(host);
-        alarm(0);
-      } else
-        hp = NULL;
-      if (hp == NULL)
-        return -2;
-      egg_memcpy(&name.sin_addr, hp->h_addr, hp->h_length);
-      name.sin_family = hp->h_addrtype;
-    }
-#ifdef USE_IPV6
+  /* I guess we broke something */
+  if (error) {
+    killsock(sock);
+    return -2;
   }
-#endif /* USE_IPV6 */
+
   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;
   }
-#ifdef USE_IPV6
-  if(af_ty == AF_INET6)  
-    rc = connect(sock, (struct sockaddr *) &name6,
-                 sizeof(struct sockaddr_in6));
-  else 
-#endif /* USE_IPV6 */
-    rc = connect(sock, (struct sockaddr *) &name,
-                 sizeof(struct sockaddr_in));
+
+  rc = connect(sock, &so.sa, SIZEOF_SOCKADDR(so));
   if (rc < 0) {    if (errno == EINPROGRESS) {
       /* Firewall?  announce connect attempt to proxy */
       if (firewall[0])
@@ -652,9 +614,9 @@ int open_telnet_raw(int sock, char *server, int sport)
 int open_telnet(char *server, int port)
 {
 #ifdef USE_IPV6
-  int sock = getsock(0, getprotocol(server)), ret = open_telnet_raw(sock, server, port);
+  int sock = getsock(0, hostprotocol(server)) , ret = open_telnet_raw(sock, server, port);
 #else
-  int sock = getsock(0), ret = open_telnet_raw(sock, server, port);
+  int sock = getsock(0) , ret = open_telnet_raw(sock, server, port);
 #endif /* USE_IPV6 */
 
   if (ret < 0)
@@ -676,7 +638,6 @@ int open_address_listen(IP addr, int *port)
   int sock = 0;
   unsigned int addrlen;
 #ifdef USE_IPV6
-  unsigned long ipp;
   struct sockaddr_in6 name6;
 #endif /* USE_IPV6 */
   struct sockaddr_in name;
@@ -689,15 +650,11 @@ int open_address_listen(IP addr, int *port)
   }
 #ifdef USE_IPV6
   if (af_def == AF_INET6) {
-    ipp = getmyip(0);
-    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, &in6addr_any, 16);
-      /* memcpy(&name6.sin6_addr, myipv6he->h_addr, myipv6he->h_length); */
       if (bind(sock, (struct sockaddr *) &name6, sizeof(name6)) < 0) {
         killsock(sock);
         return -1;
@@ -712,37 +669,32 @@ int open_address_listen(IP addr, int *port)
         killsock(sock);
         return -1;
       }
-    }
   } else {
-#endif /* USE_IPV6 */
-    if(getmyip(0) > 0) {
-#ifdef USE_IPV6
-      sock = getsock(SOCK_LISTEN, AF_INET);
+    sock = getsock(SOCK_LISTEN, AF_INET);
 #else
-      sock = getsock(SOCK_LISTEN);
+    sock = getsock(SOCK_LISTEN);
 #endif /* USE_IPV6 */
-      if (sock < 1)
-        return -1;
+    if (sock < 1)
+      return -1;
 
-      egg_bzero((char *) &name, sizeof(struct sockaddr_in));
-      name.sin_family = AF_INET;
-      name.sin_port = htons(*port); /* 0 = just assign us a port */
-      name.sin_addr.s_addr = addr;
-      if (bind(sock, (struct sockaddr *) &name, sizeof(name)) < 0) {
-        killsock(sock);
-        return -1;
-      }
-      /* what port are we on? */
-      addrlen = sizeof(name);
-      if (getsockname(sock, (struct sockaddr *) &name, &addrlen) < 0) {
-        killsock(sock);
-        return -1;
-      }
-      *port = ntohs(name.sin_port);
-      if (listen(sock, 1) < 0) {
-        killsock(sock);
-        return -1;
-      }
+    egg_bzero((char *) &name, sizeof(struct sockaddr_in));
+    name.sin_family = AF_INET;
+    name.sin_port = htons(*port); /* 0 = just assign us a port */
+    name.sin_addr.s_addr = addr;
+    if (bind(sock, (struct sockaddr *) &name, sizeof(name)) < 0) {
+      killsock(sock);
+      return -1;
+    }
+    /* what port are we on? */
+    addrlen = sizeof(name);
+    if (getsockname(sock, (struct sockaddr *) &name, &addrlen) < 0) {
+      killsock(sock);
+      return -1;
+    }
+    *port = ntohs(name.sin_port);
+    if (listen(sock, 1) < 0) {
+      killsock(sock);
+      return -1;
     }
 #ifdef USE_IPV6
   }
@@ -756,9 +708,9 @@ int open_address_listen(IP addr, int *port)
 inline int open_listen(int *port)
 {
 #ifdef USE_IPV6
-  return open_address_listen(myip[0] ? getmyip(0) : INADDR_ANY, AF_INET, port);
+  return open_address_listen(myip[0] ? getmyip() : INADDR_ANY, AF_INET, port);
 #else
-  return open_address_listen(myip[0] ? getmyip(0) : INADDR_ANY, port);
+  return open_address_listen(myip[0] ? getmyip() : INADDR_ANY, port);
 #endif /* USE_IPV6 */
 }
 
@@ -769,13 +721,12 @@ inline int open_listen(int *port)
 inline int open_listen_by_af(int *port, int af_def)
 {
 #ifdef USE_IPV6
-  return open_address_listen(myip[0] ? getmyip(0) : INADDR_ANY, af_def, port);
+  return open_address_listen(myip[0] ? getmyip() : INADDR_ANY, af_def, port);
 #else
   return 0;
 #endif /* USE_IPV6 */
 }
 
-
 /* Given a network-style IP address, returns the hostname. The hostname
  * will be in the "##.##.##.##" format if there was an error.
  * 
@@ -827,7 +778,7 @@ int answer(int sock, char *caller, unsigned long *ip, unsigned short *port,
   unsigned int addrlen;
   struct sockaddr_in from;
 #ifdef USE_IPV6
-  int af_ty = getsockproto(sock);
+  int af_ty = sockprotocol(sock);
   struct sockaddr_in6 from6;
 
   if (af_ty == AF_INET6) {
@@ -845,11 +796,26 @@ int answer(int sock, char *caller, unsigned long *ip, unsigned short *port,
     return -1;
   if (ip != NULL) {
 #ifdef USE_IPV6
-    if(af_ty == AF_INET6) {
-       *ip = notalloc;
-       egg_inet_ntop(AF_INET6, &from6, caller, 119);
-       caller[120] = 0;
-      } else {
+    /* Detect IPv4 in IPv6 mapped address .... */
+    if (af_ty == AF_INET6 && (!IN6_IS_ADDR_V4MAPPED(&from6.sin6_addr))) {
+      egg_inet_ntop(AF_INET6, &from6.sin6_addr, caller, 119);
+      caller[120] = 0;
+      *ip = notalloc;
+    } else if (IN6_IS_ADDR_V4MAPPED(&from6.sin6_addr)) {    /* ...and convert it to plain (AF_INET) IPv4 address (openssh) */
+      struct sockaddr_in *from4 = (struct sockaddr_in *)&from6;
+      struct in_addr addr;
+
+      memcpy(&addr, ((char *)&from6.sin6_addr) + 12, sizeof(addr));
+      memset(&from, 0, sizeof(from));
+
+      from4->sin_family = AF_INET;
+      addrlen = sizeof(*from4);
+      memcpy(&from4->sin_addr, &addr, sizeof(addr));
+
+      *ip = from4->sin_addr.s_addr;
+      strncpyz(caller, iptostr(*ip), 121);
+      *ip = ntohl(*ip);
+    } else {
 #endif /* USE_IPV6 */
       *ip = from.sin_addr.s_addr;
       /* This is now done asynchronously. We now only provide the IP address.
@@ -871,11 +837,7 @@ int answer(int sock, char *caller, unsigned long *ip, unsigned short *port,
         *port = ntohs(from.sin_port);
     }
   /* Set up all the normal socket crap */
-#ifdef USE_IPV6
-  setsock(new_sock, (binary ? SOCK_BINARY : 0), af_ty);
-#else
   setsock(new_sock, (binary ? SOCK_BINARY : 0));
-#endif /* USE_IPV6 */
   return new_sock;
 }
 
@@ -896,7 +858,7 @@ int open_telnet_dcc(int sock, char *server, char *port)
   else
     p = 2000;
 #ifdef USE_IPV6
-  if (getprotocol(server) == AF_INET6) {
+  if (sockprotocol(sock) == AF_INET6) {
 #  ifdef DEBUG_IPV6
     debug0("open_telnet_dcc, af_inet6!");
 #  endif /* DEBUG_IPV6 */
@@ -965,7 +927,7 @@ static int sockread(char *s, int *len)
        * 
        * ITE
        */
-      FD_SET(fdtmp , &fd);
+      FD_SET(fdtmp, &fd);
     }
 #ifdef HPUX_HACKS
 #ifndef HPUX10_HACKS
@@ -981,8 +943,8 @@ static int sockread(char *s, int *len)
     for (i = 0; i < MAXSOCKS; i++) {
       if ((!(socklist[i].flags & SOCK_UNUSED)) &&
 	  ((FD_ISSET(socklist[i].sock, &fd)) ||
-	   ((socklist[i].sock == STDOUT) && (!backgrd) &&
-	    (FD_ISSET(STDIN, &fd))))) {
+	  ((socklist[i].sock == STDOUT) && (!backgrd) &&
+	  (FD_ISSET(STDIN, &fd))))) {
 	if (socklist[i].flags & (SOCK_LISTEN | SOCK_CONNECT)) {
 	  /* Listening socket -- don't read, just return activity */
 	  /* Same for connection attempt */
@@ -1433,9 +1395,10 @@ void dequeue_sockets()
 {
   int i, x;
 
-  int z=0, fds;
+  int z = 0, fds;
   fd_set wfds;
   struct timeval tv;
+
 /* ^-- start poptix test code, this should avoid writes to sockets not ready to be written to. */
   fds = getdtablesize();
 
@@ -1445,17 +1408,15 @@ void dequeue_sockets()
 #endif
   FD_ZERO(&wfds);
   tv.tv_sec = 0;
-  tv.tv_usec = 0; /* we only want to see if it's ready for writing, no need to actually wait.. */
+  tv.tv_usec = 0; 		/* we only want to see if it's ready for writing, no need to actually wait.. */
   for (i = 0; i < MAXSOCKS; i++) { 
-    if (!(socklist[i].flags & SOCK_UNUSED) &&
-	socklist[i].outbuf != NULL) {
-	  FD_SET(socklist[i].sock, &wfds);
-	  z=1; 
-	}
-  }
-  if (!z) { 
-	return; /* nothing to write */
+    if (!(socklist[i].flags & SOCK_UNUSED) && socklist[i].outbuf != NULL) {
+      FD_SET(socklist[i].sock, &wfds);
+      z = 1; 
+    }
   }
+  if (!z)
+    return; 			/* nothing to write */
 #ifdef HPUX_HACKS
  #ifndef HPUX10_HACKS
   select(fds, (int *) NULL, (int *) &wfds, (int *) NULL, &tv);
@@ -1473,8 +1434,7 @@ void dequeue_sockets()
 	(socklist[i].outbuf != NULL) && (FD_ISSET(socklist[i].sock, &wfds))) {
       /* Trick tputs into doing the work */
       errno = 0;
-      x = write(socklist[i].sock, socklist[i].outbuf,
-		socklist[i].outbuflen);
+      x = write(socklist[i].sock, socklist[i].outbuf, socklist[i].outbuflen);
       if ((x < 0) && (errno != EAGAIN)
 #ifdef EBADSLT
 	  && (errno != EBADSLT)
@@ -1501,7 +1461,8 @@ void dequeue_sockets()
 	socklist[i].outbuflen -= x;
 	nfree(p);
       } else {
-	debug3("dequeue_sockets(): errno = %d (%s) on %d",errno,strerror(errno),socklist[i].sock);
+	debug3("dequeue_sockets(): errno = %d (%s) on %d", errno,
+               strerror(errno), socklist[i].sock);
       }
       /* All queued data was sent. Call handler if one exists and the
        * dcc entry wants it.
@@ -1579,11 +1540,6 @@ int sanitycheck_dcc(char *nick, char *from, char *ipaddy, char *port)
   if (!dcc_sanitycheck)
     return 1;
 
-#ifdef USE_IPV6
-  if (getprotocol(ipaddy) == AF_INET6)
-    return 1;
-#endif /* USE_IPV6 */
-
   if (prt < 1) {
     putlog(LOG_MISC, "*", "ALERT: (%s!%s) specified an impossible port of %u!",
 	   nick, from, prt);

+ 6 - 6
src/proto.h

@@ -283,18 +283,18 @@ void set_cmd_pass(char *, int);
 /* net.c */
 IP my_atoul(char *);
 unsigned long iptolong(IP);
-IP getmyip(int);
+IP getmyip();
+void cache_my_ip();
 void neterror(char *);
+void setsock(int, int);
+int allocsock(int, int);
 #ifdef USE_IPV6
-void setsock(int, int, int);
-int allocsock(int, int, int);
 int getsock(int, int);
 #else
-void setsock(int, int);
-int allocsock(int, int);
 int getsock(int);
 #endif /* USE_IPV6 */
-int getprotocol(char *);
+int sockprotocol(int);
+int hostprotocol(char *);
 char *hostnamefromip(unsigned long);
 void real_killsock(int, const char *, int);
 int answer(int, char *, unsigned long *, unsigned short *, int);

+ 3 - 6
src/tcldcc.c

@@ -953,7 +953,7 @@ static int tcl_connect STDVAR
     return TCL_ERROR;
   }
 #ifdef USE_IPV6
-  sock = getsock(0, getprotocol(argv[1]));
+  sock = getsock(0, hostprotocol(argv[1]));
 #else
   sock = getsock(0);
 #endif /* USE_IPV6 */
@@ -1027,6 +1027,7 @@ static int tcl_listen STDVAR
       Tcl_AppendResult(irp, "no more DCC slots available", NULL);
       return TCL_ERROR;
     }
+    cache_my_ip(); /* may need to do this because config loads before ip's are cached -bryan */
     /* Try to grab port */
     j = port + 20;
     i = (-1);
@@ -1052,11 +1053,7 @@ static int tcl_listen STDVAR
       return TCL_ERROR;
     }
     idx = new_dcc(&DCC_TELNET, 0);
-#ifdef USE_IPV6
-    dcc[idx].addr = 0x00000000; /* it's not big enough to hold '0xffffffffffffffffffffffffffffffff' =P */
-#else
-    dcc[idx].addr = iptolong(getmyip(0));
-#endif /* USE_IPV6 */
+    dcc[idx].addr = iptolong(getmyip());
     dcc[idx].port = port;
     dcc[idx].sock = i;
     dcc[idx].timeval = now;

+ 1 - 19
src/tclmisc.c

@@ -23,21 +23,6 @@ extern module_entry	*module_list;
 extern int max_logs, timesync;
 extern log_t *logs;
 extern Tcl_Interp *interp;
-#ifdef USE_IPV6
-extern char myipv6host[120];
-
-static int tcl_myip6 STDVAR      
-{
-  char s[120];
-  getmyip(0);                     
-  BADARGS(1, 1, "");
-  s[0]=0;
-  if(strlen(myipv6host)<120)
-    strcpy(s,myipv6host);
-  Tcl_AppendResult(irp, s, NULL);
-  return TCL_OK;
-}
-#endif
 
 int expmem_tclmisc()
 {
@@ -415,7 +400,7 @@ static int tcl_myip STDVAR
   char s[16];
 
   BADARGS(1, 1, "");
-  egg_snprintf(s, sizeof s, "%lu", iptolong(getmyip(0)));
+  egg_snprintf(s, sizeof s, "%lu", iptolong(getmyip()));
   Tcl_AppendResult(irp, s, NULL);
   return TCL_OK;
 }
@@ -599,9 +584,6 @@ tcl_cmds tclmisc_cmds[] =
   {"strftime",          tcl_strftime},
   {"ctime",		tcl_ctime},
   {"myip",		tcl_myip},
-#ifdef USE_IPV6
-  {"myip6",             tcl_myip6},
-#endif /* USE_IPV6 */
   {"rand",		tcl_rand},
   {"sendnote",		tcl_sendnote},
 #ifdef HUB