diff --git a/src/main-conf.c b/src/main-conf.c
index f16ecc616a2a4547b66e016a9616392f1e71a531..fa2980f2f339ed0c13f83de21f8b15203ce0ef88 100644
--- a/src/main-conf.c
+++ b/src/main-conf.c
@@ -1345,7 +1345,7 @@ masscan_set_parameter(struct Masscan *masscan,
     } else if (EQUALS("datadir", name)) {
         strcpy_s(masscan->nmap.datadir, sizeof(masscan->nmap.datadir), value);
     } else if (EQUALS("data-length", name)) {
-        unsigned x = strtoul(value, 0, 0);
+        unsigned x = (unsigned)strtoul(value, 0, 0);
         if (x >= 1514 - 14 - 40) {
             fprintf(stderr, "error: %s=<n>: expected number less than 1500\n", name);
         } else {
@@ -1655,7 +1655,7 @@ masscan_set_parameter(struct Masscan *masscan,
             while (offset < max_offset && isspace(value[offset]))
                 offset++;
             if (offset+1 < max_offset && value[offset] == ':' && isdigit(value[offset+1]&0xFF)) {
-                port = strtoul(value+offset+1, 0, 0);
+                port = (unsigned)strtoul(value+offset+1, 0, 0);
                 if (port > 65535 || port == 0) {
                     LOG(0, "FAIL: bad redis port: %s\n", value+offset+1);
                     exit(1);
@@ -1679,7 +1679,7 @@ masscan_set_parameter(struct Masscan *masscan,
     } else if (EQUALS("resume-count", name)) {
         masscan->resume.count = parseInt(value);
     } else if (EQUALS("retries", name) || EQUALS("retry", name)) {
-        unsigned x = strtoul(value, 0, 0);
+        unsigned x = (unsigned)strtoul(value, 0, 0);
         if (x >= 1000) {
             fprintf(stderr, "error: retries=<n>: expected number less than 1000\n");
         } else {
@@ -1809,7 +1809,7 @@ masscan_set_parameter(struct Masscan *masscan,
         if (EQUALS("csv", value))
             masscan->is_test_csv = 0;
     } else if (EQUALS("ttl", name)) {
-        unsigned x = strtoul(value, 0, 0);
+        unsigned x = (unsigned)strtoul(value, 0, 0);
         if (x >= 256) {
             fprintf(stderr, "error: %s=<n>: expected number less than 256\n", name);
         } else {
diff --git a/src/masscan-app.h b/src/masscan-app.h
index 854ed6621cf6e33fdf11a4eca0295acb66c2b662..402bd1b8a7270b1b77dac7836e7c3393bc79413d 100644
--- a/src/masscan-app.h
+++ b/src/masscan-app.h
@@ -30,6 +30,10 @@ enum ApplicationProtocol {
     PROTO_VNC_RFB,
     PROTO_SAFE,
     PROTO_MEMCACHED,
+    
+    
+    
+    PROTO_end_of_list /* must be last one */
 };
 
 const char *
diff --git a/src/proto-banner1.c b/src/proto-banner1.c
index b3bb5871b6fd252108c709035558f6d254082c3e..b1d8b03d86ae4242f9ae116caf4433b7662809fc 100644
--- a/src/proto-banner1.c
+++ b/src/proto-banner1.c
@@ -141,7 +141,7 @@ banner1_parse(
                              banout,
                              more);
             break;
-        case PROTO_SMTP:
+    case PROTO_SMTP:
             banner_smtp.parse(   banner1,
                               banner1->http_fields,
                               tcb_state,
@@ -238,7 +238,9 @@ banner1_create(void)
     memset(b, 0, sizeof(*b));
 
     /*
-     * These patterns match the start of the TCP stream
+     * This creates a pattern-matching blob for heuristically determining
+     * a protocol that runs on wrong ports, such as how FTP servers
+     * often respond with "220 " or VNC servers respond with "RFB".
      */
     b->smack = smack_create("banner1", SMACK_CASE_INSENSITIVE);
     for (i=0; patterns[i].pattern; i++)
@@ -251,9 +253,19 @@ banner1_create(void)
     smack_compile(b->smack);
 
 
+    /* 
+     * This goes down the list of all the TCP protocol handlers and initializes
+     * them.
+     */
+    banner_ftp.init(b);
     banner_http.init(b);
-    banner_vnc.init(b);
+    banner_imap4.init(b);
     banner_memcached.init(b);
+    banner_pop3.init(b);
+    banner_smtp.init(b);
+    banner_ssh.init(b);
+    banner_ssl.init(b);
+    banner_vnc.init(b);
 
     b->tcp_payloads[80] = &banner_http;
     b->tcp_payloads[8080] = &banner_http;
diff --git a/src/proto-banner1.h b/src/proto-banner1.h
index 0eb1998dc91178b37b01341cf9ea3bd401aad1ef..ce99ce7b6c76f2393c124bbe4e94188b0565164b 100644
--- a/src/proto-banner1.h
+++ b/src/proto-banner1.h
@@ -3,11 +3,21 @@
 #include <stdint.h>
 #define STATE_DONE 0xFFFFFFFF
 #include <stdio.h>
+#include "masscan-app.h"
 #include "proto-banout.h"
 #include "proto-x509.h"
 
 struct InteractiveData;
-
+struct Banner1;
+struct ProtocolState;
+
+typedef void (*BannerParser)(
+              const struct Banner1 *banner1,
+              void *banner1_private,
+              struct ProtocolState *stream_state,
+              const unsigned char *px, size_t length,
+              struct BannerOutput *banout,
+              struct InteractiveData *more);
 struct Banner1
 {
     struct SMACK *smack;
@@ -25,6 +35,8 @@ struct Banner1
     unsigned is_poodle_sslv3:1;
 
     struct ProtocolParserStream *tcp_payloads[65536];
+    
+    BannerParser parser[PROTO_end_of_list];
 };
 
 struct BannerBase64
diff --git a/src/proto-banout.c b/src/proto-banout.c
index ec07b26ef4f4fc0bb2294bf5105c404b2d578e88..e24553e39f4ac8c9d2740d23e7fdcd6bfb3c07a4 100644
--- a/src/proto-banout.c
+++ b/src/proto-banout.c
@@ -37,6 +37,7 @@ banout_release(struct BannerOutput *banout)
         free(banout->next);
         banout->next = next;
     }
+    banout_init(banout);
 }
 
 
diff --git a/src/proto-tcp.c b/src/proto-tcp.c
index 1a81a3cc58c2b011fe6d9564c1f50ee486b6537d..f04f1df118ef18383893152d56ceca6aad74125f 100644
--- a/src/proto-tcp.c
+++ b/src/proto-tcp.c
@@ -313,7 +313,7 @@ tcpcon_set_parameter(struct TCP_ConnectionTable *tcpcon,
             fprintf(stderr, "tcpcon: parmeter: expected array []: %s\n", name);
             exit(1);
         }
-        port = strtoul(p+1, 0, 0);
+        port = (unsigned)strtoul(p+1, 0, 0);
 
         x = banner1->tcp_payloads[port];
         if (x == NULL) {
@@ -460,6 +460,42 @@ enum DestroyReason {
 
 };
 
+/***************************************************************************
+ * Flush all the banners asssociated with this TCP connection. This always
+ * called when TCB is destroyed. This may also be called earlier, such
+ * as when a FIN is received.
+ ***************************************************************************/
+static void
+tcpcon_flush_banners(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb)
+{
+    struct BannerOutput *banout;
+    
+    /* Go through and print all the banners. Some protocols have 
+     * multiple banners. For example, web servers have both
+     * HTTP and HTML banners, and SSL also has several 
+     * X.509 certificate banners */
+    for (banout = &tcb->banout; banout != NULL; banout = banout->next) {
+        if (banout->length && banout->protocol) {
+            tcpcon->report_banner(
+                                  tcpcon->out,
+                                  global_now,
+                                  tcb->ip_them,
+                                  6, /*TCP protocol*/
+                                  tcb->port_them,
+                                  banout->protocol & 0x0FFFFFFF,
+                                  tcb->ttl,
+                                  banout->banner,
+                                  banout->length);
+        }
+    }
+    
+    /*
+     * Free up all the banners.
+     */
+    banout_release(&tcb->banout);
+
+}
+
 /***************************************************************************
  * Destroy a TCP connection entry. We have to unlink both from the
  * TCB-table as well as the timeout-table.
@@ -473,8 +509,7 @@ tcpcon_destroy_tcb(
 {
     unsigned index;
     struct TCP_Control_Block **r_entry;
-    struct BannerOutput *banout;
-
+    
     UNUSEDPARM(reason);
 
 //printf("." "tcb age = %u-sec, reason=%u                                   \n", time(0) - tcb->when_created, reason);
@@ -512,27 +547,10 @@ tcpcon_destroy_tcb(
 
     /*
      * Print out any banners associated with this TCP session. Most of the
-     * time, there'll only be one.
+     * time, there'll only be one. After printing them out, delete the
+     * banners.
      */
-    for (banout = &tcb->banout; banout != NULL; banout = banout->next) {
-        if (banout->length && banout->protocol) {
-            tcpcon->report_banner(
-                tcpcon->out,
-                global_now,
-                tcb->ip_them,
-                6, /*TCP protocol*/
-                tcb->port_them,
-                banout->protocol & 0x0FFFFFFF,
-                tcb->ttl,
-                banout->banner,
-                banout->length);
-        }
-    }
-
-    /*
-     * If there are multiple banners, then free the additional ones
-     */
-    banout_release(&tcb->banout);
+    tcpcon_flush_banners(tcpcon, tcb);
 
     /*
      * Unlink this from the timeout system.
@@ -1238,6 +1256,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon,
             0x11,
             0, 0, 0);
         tcb->seqno_me++;
+        tcpcon_flush_banners(tcpcon, tcb);
         break;
     
     case STATE_WAITING_FOR_RESPONSE<<8 | TCP_WHAT_TIMEOUT:
diff --git a/src/ranges.c b/src/ranges.c
index df53fd36ac6e2f3d204d65c5108c61218ae11284..2a636eb04f10ec380493a62b3fc1dfcd6eebec41 100644
--- a/src/ranges.c
+++ b/src/ranges.c
@@ -642,11 +642,11 @@ rangelist_parse_ports(struct RangeList *ports, const char *string, unsigned *is_
         if (!isdigit(p[0] & 0xFF))
             break;
 
-        port = strtoul(p, &p, 0);
+        port = (unsigned)strtoul(p, &p, 0);
         end = port;
         if (*p == '-') {
             p++;
-            end = strtoul(p, &p, 0);
+            end = (unsigned)strtoul(p, &p, 0);
         }
 
         if (port > 0xFFFF || end > 0xFFFF || end < port) {
diff --git a/src/rawsock-getif.c b/src/rawsock-getif.c
index 77d6e2259afb8bf722f2ee0e8a13b9b6609f40c4..4da549255d3fd32f8d7d641e3cc8fb83d65e0d5c 100644
--- a/src/rawsock-getif.c
+++ b/src/rawsock-getif.c
@@ -43,7 +43,7 @@ int
 rawsock_get_default_interface(char *ifname, size_t sizeof_ifname)
 {
     int fd;
-    int seq = time(0);
+    int seq = (int)time(0);
     int err;
     struct rt_msghdr *rtm;
     size_t sizeof_buffer;
diff --git a/src/rawsock-getroute.c b/src/rawsock-getroute.c
index 95af493774fc3f0e29ae05804bf8fdb60a15a679..cbc399ad085b0d442795199e0e13792baa41dc4a 100644
--- a/src/rawsock-getroute.c
+++ b/src/rawsock-getroute.c
@@ -99,7 +99,7 @@ int
 rawsock_get_default_gateway(const char *ifname, unsigned *ipv4)
 {
     int fd;
-    int seq = time(0);
+    int seq = (int)time(0);
     int err;
     struct rt_msghdr *rtm;
     size_t sizeof_buffer;
diff --git a/src/rawsock-pcapfile.c b/src/rawsock-pcapfile.c
index cd879bacab2dbb63f2a4ac3aadc74cf8d546e0c3..d6c583f1a5915b7cf8ae5c593e3073f84c406637 100644
--- a/src/rawsock-pcapfile.c
+++ b/src/rawsock-pcapfile.c
@@ -613,7 +613,7 @@ struct PcapFile *pcapfile_openread(const char *capfilename)
 
     /* Read the first frame's timestamp */
     {
-        int loc;
+        long loc;
         char tsbuf[8];
         size_t x;