Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into openchange
[jelmer/samba4-debian.git] / source / nbt_server / packet.c
index d7211c8ca4daf29130ee35a21892871b013e89ae..07a309b6335a3a5b6f65663285af569483b024d9 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "nbt_server/nbt_server.h"
+#include "smbd/service_task.h"
+#include "lib/socket/socket.h"
+#include "librpc/gen_ndr/ndr_nbt.h"
+#include "param/param.h"
 
 /*
   we received a badly formed packet - log it
 */
 void nbtd_bad_packet(struct nbt_name_packet *packet, 
-                    const struct nbt_peer_socket *src, const char *reason)
+                    const struct socket_address *src, const char *reason)
 {
        DEBUG(2,("nbtd: bad packet '%s' from %s:%d\n", reason, src->addr, src->port));
        if (DEBUGLVL(5)) {
@@ -40,40 +43,55 @@ void nbtd_bad_packet(struct nbt_name_packet *packet,
   see if an incoming packet is a broadcast packet from one of our own
   interfaces
 */
-BOOL nbtd_self_packet(struct nbt_name_socket *nbtsock, 
-                     struct nbt_name_packet *packet, 
-                     const struct nbt_peer_socket *src)
+bool nbtd_self_packet_and_bcast(struct nbt_name_socket *nbtsock, 
+                               struct nbt_name_packet *packet, 
+                               const struct socket_address *src)
 {
        struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, 
                                                       struct nbtd_interface);
-       struct nbtd_server *nbtsrv = iface->nbtsrv;
-       
+
        /* if its not a broadcast then its not considered a self packet */
        if (!(packet->operation & NBT_FLAG_BROADCAST)) {
-               return False;
+               return false;
        }
 
-       /* if its not from the nbt port, then it wasn't a broadcast from us */
-       if (src->port != lp_nbt_port()) {
-               return False;
-       }
-
-       /* this uses the fact that iface->nbtsock is our non-broadcast
-          listen address */
+       /* 
+        * this uses the fact that iface->nbtsock is the unicast listen address
+        * if the interface isn't the global bcast interface
+        *
+        * so if the request was directed to the unicast address it isn't a broadcast
+        * message
+        */
        if (iface->nbtsock == nbtsock &&
            iface != iface->nbtsrv->bcast_interface) {
-               return False;
+               return false;
+       }
+
+       return nbtd_self_packet(nbtsock, packet, src);
+}
+
+bool nbtd_self_packet(struct nbt_name_socket *nbtsock, 
+                     struct nbt_name_packet *packet, 
+                     const struct socket_address *src)
+{
+       struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, 
+                                                      struct nbtd_interface);
+       struct nbtd_server *nbtsrv = iface->nbtsrv;
+       
+       /* if its not from the nbt port, then it wasn't a broadcast from us */
+       if (src->port != lp_nbt_port(iface->nbtsrv->task->lp_ctx)) {
+               return false;
        }
 
        /* we have to loop over our interface list, seeing if its from
           one of our own interfaces */
        for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
                if (strcmp(src->addr, iface->ip_address) == 0) {
-                       return True;
+                       return true;
                }
        }
 
-       return False;
+       return false;
 }
 
 
@@ -82,7 +100,7 @@ BOOL nbtd_self_packet(struct nbt_name_socket *nbtsock,
 */
 void nbtd_name_query_reply(struct nbt_name_socket *nbtsock, 
                           struct nbt_name_packet *request_packet, 
-                          const struct nbt_peer_socket *src,
+                          struct socket_address *src,
                           struct nbt_name *name, uint32_t ttl,
                           uint16_t nb_flags, const char **addresses)
 {
@@ -146,7 +164,7 @@ failed:
 */
 void nbtd_negative_name_query_reply(struct nbt_name_socket *nbtsock, 
                                    struct nbt_name_packet *request_packet, 
-                                   const struct nbt_peer_socket *src)
+                                   struct socket_address *src)
 {
        struct nbt_name_packet *packet;
        struct nbt_name *name = &request_packet->questions[0].name;
@@ -189,7 +207,7 @@ failed:
 */
 void nbtd_name_registration_reply(struct nbt_name_socket *nbtsock, 
                                  struct nbt_name_packet *request_packet, 
-                                 const struct nbt_peer_socket *src,
+                                 struct socket_address *src,
                                  uint8_t rcode)
 {
        struct nbt_name_packet *packet;
@@ -237,7 +255,7 @@ failed:
 */
 void nbtd_name_release_reply(struct nbt_name_socket *nbtsock, 
                             struct nbt_name_packet *request_packet, 
-                            const struct nbt_peer_socket *src,
+                            struct socket_address *src,
                             uint8_t rcode)
 {
        struct nbt_name_packet *packet;
@@ -283,7 +301,7 @@ failed:
 */
 void nbtd_wack_reply(struct nbt_name_socket *nbtsock, 
                     struct nbt_name_packet *request_packet, 
-                    const struct nbt_peer_socket *src,
+                    struct socket_address *src,
                     uint32_t ttl)
 {
        struct nbt_name_packet *packet;
@@ -310,7 +328,7 @@ void nbtd_wack_reply(struct nbt_name_socket *nbtsock,
        packet->answers[0].rr_class          = NBT_QCLASS_IP;
        packet->answers[0].ttl               = ttl;
        packet->answers[0].rdata.data.length = 2;
-       packet->answers[0].rdata.data.data   = talloc_size(packet, 2);
+       packet->answers[0].rdata.data.data   = talloc_array(packet, uint8_t, 2);
        if (packet->answers[0].rdata.data.data == NULL) goto failed;
        RSSVAL(packet->answers[0].rdata.data.data, 0, request_packet->operation);