Browse Source

netbios_ns: refactor send_name_query

Thomas Guillem 10 years ago
parent
commit
4173b819ce
1 changed files with 87 additions and 96 deletions
  1. 87 96
      src/netbios_ns.c

+ 87 - 96
src/netbios_ns.c

@@ -35,6 +35,12 @@
 #include "netbios_query.h"
 #include "netbios_utils.h"
 
+enum name_query_type {
+    NAME_QUERY_TYPE_INVALID,
+    NAME_QUERY_TYPE_NB,
+    NAME_QUERY_TYPE_NBSTAT
+};
+static char name_query_broadcast[] = NETBIOS_WILDCARD;
 
 static int    ns_open_socket(netbios_ns *ns)
 {
@@ -92,6 +98,75 @@ static void   ns_close_abort_pipe(netbios_ns *ns)
     }
 }
 
+static int netbios_ns_send_name_query(netbios_ns *ns,
+                                      uint32_t ip,
+                                      enum name_query_type type,
+                                      const char *name,
+                                      uint16_t query_flag)
+{
+    struct sockaddr_in  addr;
+    ssize_t             sent;
+    uint16_t            trn_id;
+    const char          *query_type;
+    static char         query_type_nb[4] = { 0x00, 0x20, 0x00, 0x01 };
+    static char         query_type_nbstat[4] = { 0x00, 0x21, 0x00, 0x01 };
+    netbios_query       *q;
+
+    assert(ns != NULL);
+
+    switch (type)
+    {
+        case NAME_QUERY_TYPE_NB:
+            query_type = query_type_nb;
+            break;
+        case NAME_QUERY_TYPE_NBSTAT:
+            query_type = query_type_nbstat; // NBSTAT/IP;
+            break;
+        default:
+            BDSM_dbg("netbios_ns_send_name_query: unknow name_query_type");
+            return -1;
+    }
+
+    // Prepare packet
+    q = netbios_query_new(34 + 4, 1, NETBIOS_OP_NAME_QUERY);
+    if (query_flag)
+        netbios_query_set_flag(q, query_flag, 1);
+
+    // Append the queried name to the packet
+    netbios_query_append(q, name, strlen(name) + 1);
+
+    // Magic footer (i.e. Question type (Netbios) / class (IP)
+    netbios_query_append(q, query_type, 4);
+    q->packet->queries = htons(1);
+
+    if (ip == 0)
+        inet_aton("255.255.255.255", (struct in_addr *)&ip);
+
+    trn_id = ns->last_trn_id + 1; // Increment transaction ID, not to reuse them
+    q->packet->trn_id = htons(trn_id);
+
+    addr.sin_addr.s_addr  = ip;
+    addr.sin_family       = AF_INET;
+    addr.sin_port         = htons(NETBIOS_PORT_NAME);
+
+    sent = sendto(ns->socket, (void *)q->packet,
+                  sizeof(netbios_query_packet) + q->cursor, 0,
+                  (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
+
+    netbios_query_destroy(q);
+
+    if (sent < 0)
+    {
+        BDSM_perror("netbios_ns_send_name_query: ");
+        return -1;
+    }
+    else
+        BDSM_dbg("netbios_ns_send_name_query, name query sent for '*'.\n");
+
+    ns->last_trn_id = trn_id; // Remember the last transaction id.
+    return 0;
+}
+
 netbios_ns  *netbios_ns_new()
 {
     netbios_ns  *ns;
@@ -127,37 +202,6 @@ void          netbios_ns_destroy(netbios_ns *ns)
     free(ns);
 }
 
-static int        netbios_ns_send_query(netbios_ns *ns, netbios_query *q,
-                                        uint32_t ip)
-{
-    struct sockaddr_in  addr;
-    ssize_t             sent;
-    uint16_t            trn_id;
-
-    assert(ns != NULL && q != NULL);
-
-    trn_id = ns->last_trn_id + 1; // Increment transaction ID, not to reuse them
-    q->packet->trn_id = htons(trn_id);
-
-    addr.sin_addr.s_addr  = ip;
-    addr.sin_family       = AF_INET;
-    addr.sin_port         = htons(NETBIOS_PORT_NAME);
-
-    sent = sendto(ns->socket, (void *)q->packet,
-                  sizeof(netbios_query_packet) + q->cursor, 0,
-                  (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
-    netbios_query_destroy(q);
-
-    if (sent < 0)
-    {
-        BDSM_perror("netbios_ns_send_query: ");
-        return (0);
-    }
-
-    ns->last_trn_id = trn_id; // Remember the last transaction id.
-    return (1);
-}
-
 static ssize_t    netbios_ns_recv(int sock, int abort_fd,
                                   void *buf, size_t buf_size,
                                   struct timeval *timeout, struct sockaddr *addr,
@@ -202,12 +246,9 @@ int      netbios_ns_resolve(netbios_ns *ns, const char *name, char type, uint32_
 {
     netbios_ns_entry    *cached;
     struct timeval      timeout;
-    netbios_query       *q;
     char                *encoded_name;
-    char                footer[4] = { 0x00, 0x20, 0x00, 0x01 };
     char                recv_buffer[512]; // Hu ?
     ssize_t             recv;
-    uint32_t            ip;
 
 
     assert(ns != NULL);
@@ -222,27 +263,13 @@ int      netbios_ns_resolve(netbios_ns *ns, const char *name, char type, uint32_
     if ((encoded_name = netbios_name_encode(name, 0, type)) == NULL)
         return (0);
 
-    // Prepare packet
-    q = netbios_query_new(34 + 4, 1, NETBIOS_OP_NAME_QUERY);
-    netbios_query_set_flag(q, NETBIOS_FLAG_RECURSIVE, 1);
-    netbios_query_set_flag(q, NETBIOS_FLAG_BROADCAST, 1);
-
-    // Append the queried name to the packet
-    netbios_query_append(q, encoded_name, strlen(encoded_name) + 1);
-
-    // Magic footer (i.e. Question type (Netbios) / class (IP)
-    netbios_query_append(q, footer, 4);
-    q->packet->queries = htons(1);
-
-    // We broadcast this query
-    inet_aton("255.255.255.255", (struct in_addr *)&ip);
-
-    // Let's send it
-    if (!netbios_ns_send_query(ns, q, ip))
+    if (netbios_ns_send_name_query(ns, 0, NAME_QUERY_TYPE_NB, encoded_name,
+                                   NETBIOS_FLAG_RECURSIVE |
+                                   NETBIOS_FLAG_BROADCAST) == -1)
+    {
+        free(encoded_name);
         return (0);
-    else
-        BDSM_dbg("netbios_ns_resolve, name query sent for '%s' !\n", name);
-
+    }
     free(encoded_name);
 
     // Now wait for a reply and pray
@@ -290,13 +317,8 @@ static void   netbios_ns_discover_rec(netbios_ns *ns, struct timeval *timeout,
 
 int           netbios_ns_discover(netbios_ns *ns)
 {
-    const char  broadcast_name[] = NETBIOS_WILDCARD;
-    char        footer[4]        = { 0x00, 0x20, 0x00, 0x01 };
-
     struct timeval      timeout;
-    netbios_query     *q;
-    char                recv_buffer[256]; // Hu ?
-    uint32_t            ip;
+    char                recv_buffer[256];
 
     assert(ns != NULL);
 
@@ -304,26 +326,9 @@ int           netbios_ns_discover(netbios_ns *ns)
     // First step, we broadcast a packet to receive a message from every
     // NETBIOS nodes on the local network
     //
-    q = netbios_query_new(34 + 4, 1, NETBIOS_OP_NAME_QUERY);
-    // Append the queried name to the packet
-    netbios_query_append(q, broadcast_name, strlen(broadcast_name) + 1);
-    // Magic footer (i.e. Question type (Netbios) / class (IP)
-    netbios_query_append(q, footer, 4);
-    q->packet->queries = htons(1);
-
-    // We broadcast this query
-    inet_aton("255.255.255.255", (struct in_addr *)&ip);
-
-    // Let's send it
-    if (!netbios_ns_send_query(ns, q, ip))
-    {
-        BDSM_dbg("Unable to send netbios 'discovery query'.\n");
+    if (netbios_ns_send_name_query(ns, 0, NAME_QUERY_TYPE_NB,
+                                   name_query_broadcast, 0) == -1)
         return (0);
-    }
-    else
-        BDSM_dbg("netbios_ns_discover, name query sent for '*'.\n");
-
-
 
     //
     // Second step, we list every IP that answered to our broadcast.
@@ -345,12 +350,8 @@ void          netbios_ns_abort(netbios_ns *ns)
 // returned by the host
 const char        *netbios_ns_inverse(netbios_ns *ns, uint32_t ip)
 {
-    const char  broadcast_name[] = NETBIOS_WILDCARD;
-    char        footer[4]        = { 0x00, 0x21, 0x00, 0x01 }; // NBSTAT/IP
-
     netbios_ns_entry  *cached;
     struct timeval      timeout;
-    netbios_query     *q;
     char                recv_buffer[512]; // Hu ?
     ssize_t             recv;
 
@@ -359,18 +360,9 @@ const char        *netbios_ns_inverse(netbios_ns *ns, uint32_t ip)
     if ((cached = netbios_ns_entry_find(ns, NULL, ip)) != NULL)
         return (cached->name);
 
-    // Prepare NBSTAT query packet
-    q = netbios_query_new(34 + 4, 1, NETBIOS_OP_NAME_QUERY);
-    netbios_query_append(q, broadcast_name, strlen(broadcast_name) + 1);
-    netbios_query_append(q, footer, 4);
-    q->packet->queries = htons(1);
-
-    // Let's send it
-    if (!netbios_ns_send_query(ns, q, ip))
-        return (NULL);
-    else
-        BDSM_dbg("netbios_ns_inverse, reverse name query sent for '%s' !\n",
-                 inet_ntoa(*(struct in_addr *)&ip));
+    if (netbios_ns_send_name_query(ns, ip, NAME_QUERY_TYPE_NBSTAT,
+                                   name_query_broadcast, 0) == -1)
+        goto error;
 
     // Now wait for a reply and pray
     timeout.tv_sec = 1;
@@ -429,4 +421,3 @@ error:
     BDSM_perror("netbios_ns_inverse: ");
     return (NULL);
 }
-