]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - windows/winnet.c
Handle packets with no type byte by returning SSH_MSG_UNIMPLEMENTED.
[PuTTY.git] / windows / winnet.c
index 039701cf0bd9b9aab05d0e0f89c9f7af3622f6e2..fa2de80967565e91cd7161512fd2646f7d563bfc 100644 (file)
@@ -50,7 +50,7 @@ struct SockAddrStep_tag {
 struct Socket_tag {
     const struct socket_function_table *fn;
     /* the above variable absolutely *must* be the first in this structure */
-    char *error;
+    const char *error;
     SOCKET s;
     Plug plug;
     bufchain output_data;
@@ -138,7 +138,7 @@ static int cmpfortree(void *av, void *bv)
 static int cmpforsearch(void *av, void *bv)
 {
     Actual_Socket b = (Actual_Socket) bv;
-    unsigned long as = (unsigned long) av, bs = (unsigned long) b->s;
+    uintptr_t as = (uintptr_t) av, bs = (uintptr_t) b->s;
     if (as < bs)
        return -1;
     if (as > bs)
@@ -160,6 +160,8 @@ DECL_WINDOWS_FUNCTION(static, struct servent FAR *, getservbyname,
                      (const char FAR *, const char FAR *));
 DECL_WINDOWS_FUNCTION(static, unsigned long, inet_addr, (const char FAR *));
 DECL_WINDOWS_FUNCTION(static, char FAR *, inet_ntoa, (struct in_addr));
+DECL_WINDOWS_FUNCTION(static, const char FAR *, inet_ntop,
+                      (int, void FAR *, char *, size_t));
 DECL_WINDOWS_FUNCTION(static, int, connect,
                      (SOCKET, const struct sockaddr FAR *, int));
 DECL_WINDOWS_FUNCTION(static, int, bind,
@@ -174,6 +176,8 @@ DECL_WINDOWS_FUNCTION(static, int, ioctlsocket,
                      (SOCKET, long, u_long FAR *));
 DECL_WINDOWS_FUNCTION(static, SOCKET, accept,
                      (SOCKET, struct sockaddr FAR *, int FAR *));
+DECL_WINDOWS_FUNCTION(static, int, getpeername,
+                     (SOCKET, struct sockaddr FAR *, int FAR *));
 DECL_WINDOWS_FUNCTION(static, int, recv, (SOCKET, char FAR *, int, int));
 DECL_WINDOWS_FUNCTION(static, int, WSAIoctl,
                      (SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD,
@@ -288,6 +292,7 @@ void sk_init(void)
     GET_WINDOWS_FUNCTION(winsock_module, getservbyname);
     GET_WINDOWS_FUNCTION(winsock_module, inet_addr);
     GET_WINDOWS_FUNCTION(winsock_module, inet_ntoa);
+    GET_WINDOWS_FUNCTION(winsock_module, inet_ntop);
     GET_WINDOWS_FUNCTION(winsock_module, connect);
     GET_WINDOWS_FUNCTION(winsock_module, bind);
     GET_WINDOWS_FUNCTION(winsock_module, setsockopt);
@@ -297,6 +302,7 @@ void sk_init(void)
     GET_WINDOWS_FUNCTION(winsock_module, shutdown);
     GET_WINDOWS_FUNCTION(winsock_module, ioctlsocket);
     GET_WINDOWS_FUNCTION(winsock_module, accept);
+    GET_WINDOWS_FUNCTION(winsock_module, getpeername);
     GET_WINDOWS_FUNCTION(winsock_module, recv);
     GET_WINDOWS_FUNCTION(winsock_module, WSAIoctl);
 
@@ -356,7 +362,7 @@ static int errstring_compare(void *av, void *bv)
 
 static tree234 *errstrings = NULL;
 
-char *winsock_error_string(int error)
+const char *winsock_error_string(int error)
 {
     const char prefix[] = "Network error: ";
     struct errstring *es;
@@ -472,8 +478,8 @@ char *winsock_error_string(int error)
                            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                            es->text + bufused, bufsize - bufused, NULL)) {
             sprintf(es->text + bufused,
-                    "Windows error code %d (and FormatMessage returned %d)", 
-                    error, GetLastError());
+                    "Windows error code %d (and FormatMessage returned %u)",
+                    error, (unsigned int)GetLastError());
         } else {
             int len = strlen(es->text);
             if (len > 0 && es->text[len-1] == '\n')
@@ -861,6 +867,7 @@ static int sk_tcp_write_oob(Socket s, const char *data, int len);
 static void sk_tcp_write_eof(Socket s);
 static void sk_tcp_set_frozen(Socket s, int is_frozen);
 static const char *sk_tcp_socket_error(Socket s);
+static char *sk_tcp_peer_info(Socket s);
 
 extern char *do_select(SOCKET skt, int startup);
 
@@ -874,7 +881,8 @@ static Socket sk_tcp_accept(accept_ctx_t ctx, Plug plug)
        sk_tcp_write_eof,
        sk_tcp_flush,
        sk_tcp_set_frozen,
-       sk_tcp_socket_error
+       sk_tcp_socket_error,
+       sk_tcp_peer_info,
     };
 
     DWORD err;
@@ -1122,7 +1130,8 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
        sk_tcp_write_eof,
        sk_tcp_flush,
        sk_tcp_set_frozen,
-       sk_tcp_socket_error
+       sk_tcp_socket_error,
+       sk_tcp_peer_info,
     };
 
     Actual_Socket ret;
@@ -1162,8 +1171,8 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
     return (Socket) ret;
 }
 
-Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only,
-                     int orig_address_family)
+Socket sk_newlistener(const char *srcaddr, int port, Plug plug,
+                      int local_host_only, int orig_address_family)
 {
     static const struct socket_function_table fn_table = {
        sk_tcp_plug,
@@ -1173,7 +1182,8 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only,
        sk_tcp_write_eof,
        sk_tcp_flush,
        sk_tcp_set_frozen,
-       sk_tcp_socket_error
+       sk_tcp_socket_error,
+       sk_tcp_peer_info,
     };
 
     SOCKET s;
@@ -1648,7 +1658,7 @@ int select_result(WPARAM wParam, LPARAM lParam)
        ret = p_recv(s->s, buf, sizeof(buf), MSG_OOB);
        noise_ultralight(ret);
        if (ret <= 0) {
-           char *str = (ret == 0 ? "Internal networking trouble" :
+           const char *str = (ret == 0 ? "Internal networking trouble" :
                         winsock_error_string(p_WSAGetLastError()));
            /* We're inside the Windows frontend here, so we know
             * that the frontend handle is unnecessary. */
@@ -1744,6 +1754,38 @@ static const char *sk_tcp_socket_error(Socket sock)
     return s->error;
 }
 
+static char *sk_tcp_peer_info(Socket sock)
+{
+    Actual_Socket s = (Actual_Socket) sock;
+#ifdef NO_IPV6
+    struct sockaddr_in addr;
+#else
+    struct sockaddr_storage addr;
+#endif
+    int addrlen = sizeof(addr);
+    char buf[INET6_ADDRSTRLEN];
+
+    if (p_getpeername(s->s, (struct sockaddr *)&addr, &addrlen) < 0)
+        return NULL;
+
+    if (((struct sockaddr *)&addr)->sa_family == AF_INET) {
+        return dupprintf
+            ("%s:%d",
+             p_inet_ntoa(((struct sockaddr_in *)&addr)->sin_addr),
+             (int)p_ntohs(((struct sockaddr_in *)&addr)->sin_port));
+#ifndef NO_IPV6
+    } else if (((struct sockaddr *)&addr)->sa_family == AF_INET6) {
+        return dupprintf
+            ("[%s]:%d",
+             p_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr,
+                         buf, sizeof(buf)),
+             (int)p_ntohs(((struct sockaddr_in6 *)&addr)->sin6_port));
+#endif
+    } else {
+        return NULL;
+    }
+}
+
 static void sk_tcp_set_frozen(Socket sock, int is_frozen)
 {
     Actual_Socket s = (Actual_Socket) sock;