LCOV - code coverage report
Current view: top level - source3/nmbd - nmbd_packets.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 610 1005 60.7 %
Date: 2021-09-23 10:06:22 Functions: 38 49 77.6 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    NBT netbios routines and daemon - version 2
       4             :    Copyright (C) Andrew Tridgell 1994-1998
       5             :    Copyright (C) Luke Kenneth Casson Leighton 1994-1998
       6             :    Copyright (C) Jeremy Allison 1994-2003
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "nmbd/nmbd.h"
      24             : #include "../lib/util/select.h"
      25             : #include "system/select.h"
      26             : #include "libsmb/libsmb.h"
      27             : #include "libsmb/unexpected.h"
      28             : #include "lib/util/string_wrappers.h"
      29             : 
      30             : extern int ClientNMB;
      31             : extern int ClientDGRAM;
      32             : extern int global_nmb_port;
      33             : 
      34             : extern int num_response_packets;
      35             : 
      36             : bool rescan_listen_set = False;
      37             : 
      38             : static struct nb_packet_server *packet_server;
      39             : 
      40          33 : bool nmbd_init_packet_server(void)
      41             : {
      42             :         NTSTATUS status;
      43             : 
      44          33 :         status = nb_packet_server_create(
      45             :                 NULL, nmbd_event_context(),
      46             :                 lp_parm_int(-1, "nmbd", "unexpected_clients", 200),
      47             :                 &packet_server);
      48          33 :         if (!NT_STATUS_IS_OK(status)) {
      49           0 :                 DEBUG(0, ("ERROR: nb_packet_server_create failed: %s\n",
      50             :                           nt_errstr(status)));
      51           0 :                 return false;
      52             :         }
      53          33 :         return true;
      54             : }
      55             : 
      56             : 
      57             : /*******************************************************************
      58             :   The global packet linked-list. Incoming entries are 
      59             :   added to the end of this list. It is supposed to remain fairly 
      60             :   short so we won't bother with an end pointer.
      61             : ******************************************************************/
      62             : 
      63             : static struct packet_struct *packet_queue = NULL;
      64             : 
      65             : /***************************************************************************
      66             : Utility function to find the specific fd to send a packet out on.
      67             : **************************************************************************/
      68             : 
      69         366 : static int find_subnet_fd_for_address( struct in_addr local_ip )
      70             : {
      71             :         struct subnet_record *subrec;
      72             : 
      73         366 :         for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
      74         366 :                 if(ip_equal_v4(local_ip, subrec->myip))
      75         366 :                         return subrec->nmb_sock;
      76             : 
      77           0 :         return ClientNMB;
      78             : }
      79             : 
      80             : /***************************************************************************
      81             : Utility function to find the specific fd to send a mailslot packet out on.
      82             : **************************************************************************/
      83             : 
      84         565 : static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
      85             : {
      86             :         struct subnet_record *subrec;
      87             : 
      88         565 :         for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
      89         565 :                 if(ip_equal_v4(local_ip, subrec->myip))
      90         565 :                         return subrec->dgram_sock;
      91             : 
      92           0 :         return ClientDGRAM;
      93             : }
      94             : 
      95             : /***************************************************************************
      96             : Get/Set problematic nb_flags as network byte order 16 bit int.
      97             : **************************************************************************/
      98             : 
      99        2158 : uint16_t get_nb_flags(char *buf)
     100             : {
     101        2158 :         return ((((uint16_t)*buf)&0xFFFF) & NB_FLGMSK);
     102             : }
     103             : 
     104        1390 : void set_nb_flags(char *buf, uint16_t nb_flags)
     105             : {
     106        1390 :         *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
     107        1390 :         *buf = '\0';
     108        1390 : }
     109             : 
     110             : /***************************************************************************
     111             : Dumps out the browse packet data.
     112             : **************************************************************************/
     113             : 
     114         876 : static void debug_browse_data(const char *outbuf, int len)
     115             : {
     116             :         int i,j;
     117             : 
     118         876 :         DEBUG( 4, ( "debug_browse_data():\n" ) );
     119        3797 :         for (i = 0; i < len; i+= 16) {
     120        2921 :                 DEBUGADD( 4, ( "%3x char ", i ) );
     121             : 
     122       47838 :                 for (j = 0; j < 16; j++) {
     123             :                         unsigned char x;
     124       45353 :                         if (i+j >= len)
     125         436 :                                 break;
     126             : 
     127       44917 :                         x = outbuf[i+j];
     128       44917 :                         if (x < 32 || x > 127) 
     129       16712 :                                 x = '.';
     130             : 
     131       44917 :                         DEBUGADD( 4, ( "%c", x ) );
     132             :                 }
     133             : 
     134        2921 :                 DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
     135             : 
     136       47838 :                 for (j = 0; j < 16; j++) {
     137       45353 :                         if (i+j >= len) 
     138         436 :                                 break;
     139       44917 :                         DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
     140             :                 }
     141             : 
     142        2921 :                 DEBUGADD( 4, ("\n") );
     143             :         }
     144         876 : }
     145             : 
     146             : /***************************************************************************
     147             :   Generates the unique transaction identifier
     148             : **************************************************************************/
     149             : 
     150             : static uint16_t name_trn_id=0;
     151             : 
     152         931 : static uint16_t generate_name_trn_id(void)
     153             : {
     154         931 :         if (!name_trn_id) {
     155          33 :                 name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)getpid()%(unsigned)100);
     156             :         }
     157         931 :         name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
     158         931 :         return name_trn_id;
     159             : }
     160             : 
     161             : /***************************************************************************
     162             :  Either loops back or sends out a completed NetBIOS packet.
     163             : **************************************************************************/
     164             : 
     165         366 : static bool send_netbios_packet(struct packet_struct *p)
     166             : {
     167         366 :         bool loopback_this_packet = False;
     168             : 
     169             :         /* Check if we are sending to or from ourselves as a WINS server. */
     170         366 :         if(ismyip_v4(p->ip) && (p->port == global_nmb_port))
     171           0 :                 loopback_this_packet = True;
     172             : 
     173         366 :         if(loopback_this_packet) {
     174           0 :                 struct packet_struct *lo_packet = NULL;
     175           0 :                 DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
     176           0 :                 if((lo_packet = copy_packet(p)) == NULL)
     177           0 :                         return False;
     178           0 :                 queue_packet(lo_packet);
     179         366 :         } else if (!send_packet(p)) {
     180           0 :                 DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
     181             :                         inet_ntoa(p->ip),p->port));
     182           0 :                 return False;
     183             :         }
     184             : 
     185         366 :         return True;
     186             : } 
     187             : 
     188             : /***************************************************************************
     189             :  Sets up the common elements of an outgoing NetBIOS packet.
     190             : 
     191             :  Note: do not attempt to rationalise whether rec_des should be set or not
     192             :  in a particular situation. Just follow rfc_1002 or look at examples from WinXX.
     193             :  It does NOT follow the rule that requests to the wins server always have
     194             :  rec_des true. See for example name releases and refreshes
     195             : **************************************************************************/
     196             : 
     197         366 : static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
     198             :                                                             bool bcast, bool rec_des,
     199             :                                                             struct in_addr to_ip)
     200             : {
     201         366 :         struct packet_struct *packet = NULL;
     202         366 :         struct nmb_packet *nmb = NULL;
     203             : 
     204             :         /* Allocate the packet_struct we will return. */
     205         366 :         if((packet = SMB_MALLOC_P(struct packet_struct)) == NULL) {
     206           0 :                 DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
     207           0 :                 return NULL;
     208             :         }
     209             : 
     210         366 :         memset((char *)packet,'\0',sizeof(*packet));
     211             : 
     212         366 :         nmb = &packet->packet.nmb;
     213             : 
     214         366 :         nmb->header.name_trn_id = generate_name_trn_id();
     215         366 :         nmb->header.response = False;
     216         366 :         nmb->header.nm_flags.recursion_desired = rec_des;
     217         366 :         nmb->header.nm_flags.recursion_available = False;
     218         366 :         nmb->header.nm_flags.trunc = False;
     219         366 :         nmb->header.nm_flags.authoritative = False;
     220         366 :         nmb->header.nm_flags.bcast = bcast;
     221             : 
     222         366 :         nmb->header.rcode = 0;
     223         366 :         nmb->header.qdcount = 1;
     224         366 :         nmb->header.ancount = 0;
     225         366 :         nmb->header.nscount = 0;
     226             : 
     227         366 :         nmb->question.question_name = *nmbname;
     228         366 :         nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
     229         366 :         nmb->question.question_class = QUESTION_CLASS_IN;
     230             : 
     231         366 :         packet->ip = to_ip;
     232         366 :         packet->port = NMB_PORT;
     233         366 :         packet->recv_fd = -1;
     234         366 :         packet->send_fd = ClientNMB;
     235         366 :         packet->timestamp = time(NULL);
     236         366 :         packet->packet_type = NMB_PACKET;
     237         366 :         packet->locked = False;
     238             : 
     239         366 :         return packet; /* Caller must free. */
     240             : }
     241             : 
     242             : /***************************************************************************
     243             :  Sets up the common elements of register, refresh or release packet.
     244             : **************************************************************************/
     245             : 
     246         231 : static bool create_and_init_additional_record(struct packet_struct *packet,
     247             :                                                      uint16_t nb_flags,
     248             :                                                      const struct in_addr *register_ip)
     249             : {
     250         231 :         struct nmb_packet *nmb = &packet->packet.nmb;
     251             : 
     252         231 :         if((nmb->additional = SMB_MALLOC_P(struct res_rec)) == NULL) {
     253           0 :                 DEBUG(0,("create_and_init_additional_record: malloc fail for additional record.\n"));
     254           0 :                 return False;
     255             :         }
     256             : 
     257         231 :         memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
     258             : 
     259         231 :         nmb->additional->rr_name  = nmb->question.question_name;
     260         231 :         nmb->additional->rr_type  = RR_TYPE_NB;
     261         231 :         nmb->additional->rr_class = RR_CLASS_IN;
     262             : 
     263             :         /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
     264         231 :         if (nmb->header.nm_flags.bcast)
     265         231 :                 nmb->additional->ttl = PERMANENT_TTL;
     266             :         else
     267           0 :                 nmb->additional->ttl = lp_max_ttl();
     268             : 
     269         231 :         nmb->additional->rdlength = 6;
     270             : 
     271         231 :         set_nb_flags(nmb->additional->rdata,nb_flags);
     272             : 
     273             :         /* Set the address for the name we are registering. */
     274         231 :         putip(&nmb->additional->rdata[2], register_ip);
     275             : 
     276             :         /* 
     277             :            it turns out that Jeremys code was correct, we are supposed
     278             :            to send registrations from the IP we are registering. The
     279             :            trick is what to do on timeouts! When we send on a
     280             :            non-routable IP then the reply will timeout, and we should
     281             :            treat this as success, not failure. That means we go into
     282             :            our standard refresh cycle for that name which copes nicely
     283             :            with disconnected networks.
     284             :         */
     285         231 :         packet->recv_fd = -1;
     286         231 :         packet->send_fd = find_subnet_fd_for_address(*register_ip);
     287             : 
     288         231 :         return True;
     289             : }
     290             : 
     291             : /***************************************************************************
     292             :  Sends out a name query.
     293             : **************************************************************************/
     294             : 
     295         135 : static bool initiate_name_query_packet( struct packet_struct *packet)
     296             : {
     297         135 :         struct nmb_packet *nmb = NULL;
     298             : 
     299         135 :         nmb = &packet->packet.nmb;
     300             : 
     301         135 :         nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
     302         135 :         nmb->header.arcount = 0;
     303             : 
     304         135 :         nmb->header.nm_flags.recursion_desired = True;
     305             : 
     306         135 :         DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
     307             :                 nmb_namestr(&nmb->question.question_name), 
     308             :                 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
     309             : 
     310         135 :         return send_netbios_packet( packet );
     311             : }
     312             : 
     313             : /***************************************************************************
     314             :  Sends out a name query - from a WINS server. 
     315             : **************************************************************************/
     316             : 
     317           0 : static bool initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
     318             : {   
     319           0 :         struct nmb_packet *nmb = NULL;
     320             : 
     321           0 :         nmb = &packet->packet.nmb;
     322             : 
     323           0 :         nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
     324           0 :         nmb->header.arcount = 0;
     325             : 
     326           0 :         nmb->header.nm_flags.recursion_desired = False;
     327             : 
     328           0 :         DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
     329             :                 nmb_namestr(&nmb->question.question_name),
     330             :                 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
     331             : 
     332           0 :         return send_netbios_packet( packet );
     333             : } 
     334             : 
     335             : /***************************************************************************
     336             :  Sends out a name register.
     337             : **************************************************************************/
     338             : 
     339         231 : static bool initiate_name_register_packet( struct packet_struct *packet,
     340             :                                     uint16_t nb_flags, const struct in_addr *register_ip)
     341             : {
     342         231 :         struct nmb_packet *nmb = &packet->packet.nmb;
     343             : 
     344         231 :         nmb->header.opcode = NMB_NAME_REG_OPCODE;
     345         231 :         nmb->header.arcount = 1;
     346             : 
     347         231 :         nmb->header.nm_flags.recursion_desired = True;
     348             : 
     349         231 :         if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
     350           0 :                 return False;
     351             : 
     352         231 :         DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
     353             :                 nmb_namestr(&nmb->additional->rr_name),
     354             :                 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
     355             : 
     356         231 :         return send_netbios_packet( packet );
     357             : }
     358             : 
     359             : /***************************************************************************
     360             :  Sends out a multihomed name register.
     361             : **************************************************************************/
     362             : 
     363           0 : static bool initiate_multihomed_name_register_packet(struct packet_struct *packet,
     364             :                                                      uint16_t nb_flags, struct in_addr *register_ip)
     365             : {
     366           0 :         struct nmb_packet *nmb = &packet->packet.nmb;
     367             :         fstring second_ip_buf;
     368             : 
     369           0 :         fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
     370             : 
     371           0 :         nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
     372           0 :         nmb->header.arcount = 1;
     373             : 
     374           0 :         nmb->header.nm_flags.recursion_desired = True;
     375             : 
     376           0 :         if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
     377           0 :                 return False;
     378             : 
     379           0 :         DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
     380             : for name %s IP %s (bcast=%s) to IP %s\n",
     381             :                  nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
     382             :                  BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
     383             : 
     384           0 :         return send_netbios_packet( packet );
     385             : } 
     386             : 
     387             : /***************************************************************************
     388             :  Sends out a name refresh.
     389             : **************************************************************************/
     390             : 
     391           0 : static bool initiate_name_refresh_packet( struct packet_struct *packet,
     392             :                                    uint16_t nb_flags, struct in_addr *refresh_ip)
     393             : {
     394           0 :         struct nmb_packet *nmb = &packet->packet.nmb;
     395             : 
     396           0 :         nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
     397           0 :         nmb->header.arcount = 1;
     398             : 
     399           0 :         nmb->header.nm_flags.recursion_desired = False;
     400             : 
     401           0 :         if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
     402           0 :                 return False;
     403             : 
     404           0 :         DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
     405             :                 nmb_namestr(&nmb->additional->rr_name),
     406             :                 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
     407             : 
     408           0 :         return send_netbios_packet( packet );
     409             : } 
     410             : 
     411             : /***************************************************************************
     412             :  Sends out a name release.
     413             : **************************************************************************/
     414             : 
     415           0 : static bool initiate_name_release_packet( struct packet_struct *packet,
     416             :                                    uint16_t nb_flags, struct in_addr *release_ip)
     417             : {
     418           0 :         struct nmb_packet *nmb = &packet->packet.nmb;
     419             : 
     420           0 :         nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
     421           0 :         nmb->header.arcount = 1;
     422             : 
     423           0 :         nmb->header.nm_flags.recursion_desired = False;
     424             : 
     425           0 :         if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
     426           0 :                 return False;
     427             : 
     428           0 :         DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
     429             :                 nmb_namestr(&nmb->additional->rr_name),
     430             :                 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
     431             : 
     432           0 :         return send_netbios_packet( packet );
     433             : } 
     434             : 
     435             : /***************************************************************************
     436             :  Sends out a node status.
     437             : **************************************************************************/
     438             : 
     439           0 : static bool initiate_node_status_packet( struct packet_struct *packet )
     440             : {
     441           0 :         struct nmb_packet *nmb = &packet->packet.nmb;
     442             : 
     443           0 :         nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
     444           0 :         nmb->header.arcount = 0;
     445             : 
     446           0 :         nmb->header.nm_flags.recursion_desired = False;
     447             : 
     448           0 :         nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
     449             : 
     450           0 :         DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
     451             :                 nmb_namestr(&nmb->question.question_name),
     452             :                 inet_ntoa(packet->ip)));
     453             : 
     454           0 :         return send_netbios_packet( packet );
     455             : }
     456             : 
     457             : /****************************************************************************
     458             :   Simplification functions for queuing standard packets.
     459             :   These should be the only publicly callable functions for sending
     460             :   out packets.
     461             : ****************************************************************************/
     462             : 
     463             : /****************************************************************************
     464             :  Assertion - we should never be sending nmbd packets on the remote
     465             :  broadcast subnet.
     466             : ****************************************************************************/
     467             : 
     468         366 : static bool assert_check_subnet(struct subnet_record *subrec)
     469             : {
     470         366 :         if( subrec == remote_broadcast_subnet) {
     471           0 :                 DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
     472             : This is a bug.\n"));
     473           0 :                 return True;
     474             :         }
     475         366 :         return False;
     476             : }
     477             : 
     478             : /****************************************************************************
     479             :  Queue a register name packet to the broadcast address of a subnet.
     480             : ****************************************************************************/
     481             : 
     482         231 : struct response_record *queue_register_name( struct subnet_record *subrec,
     483             :                           response_function resp_fn,
     484             :                           timeout_response_function timeout_fn,
     485             :                           register_name_success_function success_fn,
     486             :                           register_name_fail_function fail_fn,
     487             :                           struct userdata_struct *userdata,
     488             :                           struct nmb_name *nmbname,
     489             :                           uint16_t nb_flags)
     490             : {
     491             :         struct packet_struct *p;
     492             :         struct response_record *rrec;
     493             :         struct sockaddr_storage ss;
     494         231 :         const struct sockaddr_storage *pss = NULL;
     495         231 :         if(assert_check_subnet(subrec))
     496           0 :                 return NULL;
     497             : 
     498             :         /* note that all name registration requests have RD set (rfc1002 - section 4.2.2 */
     499         231 :         if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
     500             :                                 subrec->bcast_ip)) == NULL)
     501           0 :                 return NULL;
     502             : 
     503         231 :         in_addr_to_sockaddr_storage(&ss, subrec->bcast_ip);
     504         231 :         pss = iface_ip((struct sockaddr *)(void *)&ss);
     505         231 :         if (!pss || pss->ss_family != AF_INET) {
     506           0 :                 p->locked = False;
     507           0 :                 free_packet(p);
     508           0 :                 return NULL;
     509             :         }
     510             : 
     511         423 :         if(initiate_name_register_packet(p, nb_flags,
     512         231 :                         &((const struct sockaddr_in *)pss)->sin_addr) == False) {
     513           0 :                 p->locked = False;
     514           0 :                 free_packet(p);
     515           0 :                 return NULL;
     516             :         }
     517             : 
     518         231 :         if((rrec = make_response_record(subrec,        /* subnet record. */
     519             :                                 p,                     /* packet we sent. */
     520             :                                 resp_fn,               /* function to call on response. */
     521             :                                 timeout_fn,            /* function to call on timeout. */
     522             :                                 (success_function)success_fn,            /* function to call on operation success. */
     523             :                                 (fail_function)fail_fn,               /* function to call on operation fail. */
     524             :                                 userdata)) == NULL)  {
     525           0 :                 p->locked = False;
     526           0 :                 free_packet(p);
     527           0 :                 return NULL;
     528             :         }
     529             : 
     530         231 :         return rrec;
     531             : }
     532             : 
     533             : /****************************************************************************
     534             :  Queue a refresh name packet to the broadcast address of a subnet.
     535             : ****************************************************************************/
     536             : 
     537           0 : void queue_wins_refresh(struct nmb_name *nmbname,
     538             :                         response_function resp_fn,
     539             :                         timeout_response_function timeout_fn,
     540             :                         uint16_t nb_flags,
     541             :                         struct in_addr refresh_ip,
     542             :                         const char *tag)
     543             : {
     544             :         struct packet_struct *p;
     545             :         struct response_record *rrec;
     546             :         struct in_addr wins_ip;
     547             :         struct userdata_struct *userdata;
     548             :         fstring ip_str;
     549             : 
     550           0 :         wins_ip = wins_srv_ip_tag(tag, refresh_ip);
     551             : 
     552           0 :         if ((p = create_and_init_netbios_packet(nmbname, False, False, wins_ip)) == NULL) {
     553           0 :                 return;
     554             :         }
     555             : 
     556           0 :         if (!initiate_name_refresh_packet(p, nb_flags, &refresh_ip)) {
     557           0 :                 p->locked = False;
     558           0 :                 free_packet(p);
     559           0 :                 return;
     560             :         }
     561             : 
     562           0 :         fstrcpy(ip_str, inet_ntoa(refresh_ip));
     563             : 
     564           0 :         DEBUG(6,("Refreshing name %s IP %s with WINS server %s using tag '%s'\n",
     565             :                  nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
     566             : 
     567           0 :         userdata = (struct userdata_struct *)SMB_MALLOC(sizeof(*userdata) + strlen(tag) + 1);
     568           0 :         if (!userdata) {
     569           0 :                 p->locked = False;
     570           0 :                 free_packet(p);
     571           0 :                 DEBUG(0,("Failed to allocate userdata structure!\n"));
     572           0 :                 return;
     573             :         }
     574           0 :         ZERO_STRUCTP(userdata);
     575           0 :         userdata->userdata_len = strlen(tag) + 1;
     576           0 :         strlcpy(userdata->data, tag, userdata->userdata_len);     
     577             : 
     578           0 :         if ((rrec = make_response_record(unicast_subnet,
     579             :                                          p,
     580             :                                          resp_fn, timeout_fn,
     581             :                                          NULL,
     582             :                                          NULL,
     583             :                                          userdata)) == NULL) {
     584           0 :                 p->locked = False;
     585           0 :                 free_packet(p);
     586           0 :                 return;
     587             :         }
     588             : 
     589           0 :         free(userdata);
     590             : 
     591             :         /* we don't want to repeat refresh packets */
     592           0 :         rrec->repeat_count = 0;
     593             : }
     594             : 
     595             : 
     596             : /****************************************************************************
     597             :  Queue a multihomed register name packet to a given WINS server IP
     598             : ****************************************************************************/
     599             : 
     600           0 : struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
     601             :                                                         response_function resp_fn,
     602             :                                                         timeout_response_function timeout_fn,
     603             :                                                         register_name_success_function success_fn,
     604             :                                                         register_name_fail_function fail_fn,
     605             :                                                         struct userdata_struct *userdata,
     606             :                                                         struct nmb_name *nmbname,
     607             :                                                         uint16_t nb_flags,
     608             :                                                         struct in_addr register_ip,
     609             :                                                         struct in_addr wins_ip)
     610             : {
     611             :         struct packet_struct *p;
     612             :         struct response_record *rrec;
     613             :         bool ret;
     614             : 
     615             :         /* Sanity check. */
     616           0 :         if(subrec != unicast_subnet) {
     617           0 :                 DEBUG(0,("queue_register_multihomed_name: should only be done on \
     618             : unicast subnet. subnet is %s\n.", subrec->subnet_name ));
     619           0 :                 return NULL;
     620             :         }
     621             : 
     622           0 :         if(assert_check_subnet(subrec))
     623           0 :                 return NULL;
     624             : 
     625           0 :         if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
     626           0 :                 return NULL;
     627             : 
     628           0 :         if (nb_flags & NB_GROUP)
     629           0 :                 ret = initiate_name_register_packet( p, nb_flags, &register_ip);
     630             :         else
     631           0 :                 ret = initiate_multihomed_name_register_packet(p, nb_flags, &register_ip);
     632             : 
     633           0 :         if (ret == False) {  
     634           0 :                 p->locked = False;
     635           0 :                 free_packet(p);
     636           0 :                 return NULL;
     637             :         }  
     638             : 
     639           0 :         if ((rrec = make_response_record(subrec,    /* subnet record. */
     640             :                                          p,                     /* packet we sent. */
     641             :                                          resp_fn,               /* function to call on response. */
     642             :                                          timeout_fn,            /* function to call on timeout. */
     643             :                                          (success_function)success_fn, /* function to call on operation success. */
     644             :                                          (fail_function)fail_fn,       /* function to call on operation fail. */
     645             :                                          userdata)) == NULL) {  
     646           0 :                 p->locked = False;
     647           0 :                 free_packet(p);
     648           0 :                 return NULL;
     649             :         }  
     650             : 
     651           0 :         return rrec;
     652             : }
     653             : 
     654             : /****************************************************************************
     655             :  Queue a release name packet to the broadcast address of a subnet.
     656             : ****************************************************************************/
     657             : 
     658           0 : struct response_record *queue_release_name( struct subnet_record *subrec,
     659             :                                             response_function resp_fn,
     660             :                                             timeout_response_function timeout_fn,
     661             :                                             release_name_success_function success_fn,
     662             :                                             release_name_fail_function fail_fn,
     663             :                                             struct userdata_struct *userdata,
     664             :                                             struct nmb_name *nmbname,
     665             :                                             uint16_t nb_flags,
     666             :                                             struct in_addr release_ip,
     667             :                                             struct in_addr dest_ip)
     668             : {
     669             :         struct packet_struct *p;
     670             :         struct response_record *rrec;
     671             : 
     672           0 :         if(assert_check_subnet(subrec))
     673           0 :                 return NULL;
     674             : 
     675           0 :         if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False, dest_ip)) == NULL)
     676           0 :                 return NULL;
     677             : 
     678           0 :         if(initiate_name_release_packet( p, nb_flags, &release_ip) == False) {
     679           0 :                 p->locked = False;
     680           0 :                 free_packet(p);
     681           0 :                 return NULL;
     682             :         }
     683             : 
     684           0 :         if((rrec = make_response_record(subrec,                /* subnet record. */
     685             :                                         p,                     /* packet we sent. */
     686             :                                         resp_fn,               /* function to call on response. */
     687             :                                         timeout_fn,            /* function to call on timeout. */
     688             :                                         (success_function)success_fn,            /* function to call on operation success. */
     689             :                                         (fail_function)fail_fn,               /* function to call on operation fail. */
     690             :                                         userdata)) == NULL)  {
     691           0 :                 p->locked = False;
     692           0 :                 free_packet(p);
     693           0 :                 return NULL;
     694             :         }
     695             : 
     696             :         /*
     697             :          * For a broadcast release packet, only send once.
     698             :          * This will cause us to remove the name asap. JRA.
     699             :          */
     700             : 
     701           0 :         if (subrec != unicast_subnet) {
     702           0 :                 rrec->repeat_count = 0;
     703           0 :                 rrec->repeat_time = 0;
     704             :         }
     705             : 
     706           0 :         return rrec;
     707             : }
     708             : 
     709             : /****************************************************************************
     710             :  Queue a query name packet to the broadcast address of a subnet.
     711             : ****************************************************************************/
     712             : 
     713         135 : struct response_record *queue_query_name( struct subnet_record *subrec,
     714             :                           response_function resp_fn,
     715             :                           timeout_response_function timeout_fn,
     716             :                           query_name_success_function success_fn,
     717             :                           query_name_fail_function fail_fn,
     718             :                           struct userdata_struct *userdata,
     719             :                           struct nmb_name *nmbname)
     720             : {
     721             :         struct packet_struct *p;
     722             :         struct response_record *rrec;
     723             :         struct in_addr to_ip;
     724             : 
     725         135 :         if(assert_check_subnet(subrec))
     726           0 :                 return NULL;
     727             : 
     728         135 :         to_ip = subrec->bcast_ip;
     729             : 
     730             :         /* queries to the WINS server turn up here as queries to IP 0.0.0.0 
     731             :                         These need to be handled a bit differently */
     732         135 :         if (subrec->type == UNICAST_SUBNET && is_zero_ip_v4(to_ip)) {
     733             :                 /* What we really need to do is loop over each of our wins
     734             :                  * servers and wins server tags here, but that just doesn't
     735             :                  * fit our architecture at the moment (userdata may already
     736             :                  * be used when we get here). For now we just query the first
     737             :                  * active wins server on the first tag.
     738             :                  */ 
     739           0 :                 char **tags = wins_srv_tags();
     740           0 :                 if (!tags) {
     741           0 :                         return NULL;
     742             :                 }
     743           0 :                 to_ip = wins_srv_ip_tag(tags[0], to_ip);
     744           0 :                 wins_srv_tags_free(tags);
     745             :         }
     746             : 
     747         135 :         if(( p = create_and_init_netbios_packet(nmbname, 
     748             :                                         (subrec != unicast_subnet), 
     749             :                                         (subrec == unicast_subnet), 
     750             :                                         to_ip)) == NULL)
     751           0 :                 return NULL;
     752             : 
     753         135 :         if(lp_bind_interfaces_only()) {
     754             :                 int i;
     755             : 
     756         135 :                 DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
     757         270 :                 for(i = 0; i < iface_count(); i++) {
     758         270 :                         const struct in_addr *ifip = iface_n_ip_v4(i);
     759             : 
     760         270 :                         if (ifip == NULL) {
     761         135 :                                 DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
     762         135 :                                 continue;
     763             :                         }
     764             : 
     765         135 :                         if (is_loopback_ip_v4(*ifip)) {
     766           0 :                                 DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
     767           0 :                                 continue;
     768             :                         }
     769             : 
     770         135 :                         DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
     771         135 :                                 p->send_fd = find_subnet_fd_for_address( *ifip );
     772         135 :                                 break;
     773             :                 }
     774             :         }
     775             : 
     776         135 :         if(initiate_name_query_packet( p ) == False) {
     777           0 :                 p->locked = False;
     778           0 :                 free_packet(p);
     779           0 :                 return NULL;
     780             :         }
     781             : 
     782         135 :         if((rrec = make_response_record(subrec,                /* subnet record. */
     783             :                                         p,                     /* packet we sent. */
     784             :                                         resp_fn,               /* function to call on response. */
     785             :                                         timeout_fn,            /* function to call on timeout. */
     786             :                                         (success_function)success_fn,            /* function to call on operation success. */
     787             :                                         (fail_function)fail_fn,               /* function to call on operation fail. */
     788             :                                         userdata)) == NULL) {
     789           0 :                 p->locked = False;
     790           0 :                 free_packet(p);
     791           0 :                 return NULL;
     792             :         }
     793             : 
     794         135 :         return rrec;
     795             : }
     796             : 
     797             : /****************************************************************************
     798             :  Queue a query name packet to a given address from the WINS subnet.
     799             : ****************************************************************************/
     800             : 
     801           0 : struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
     802             :                           response_function resp_fn,
     803             :                           timeout_response_function timeout_fn,
     804             :                           query_name_success_function success_fn,
     805             :                           query_name_fail_function fail_fn,
     806             :                           struct userdata_struct *userdata,
     807             :                           struct nmb_name *nmbname)
     808             : {
     809             :         struct packet_struct *p;
     810             :         struct response_record *rrec;
     811             : 
     812           0 :         if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
     813           0 :                 return NULL;
     814             : 
     815           0 :         if(initiate_name_query_packet_from_wins_server( p ) == False) {
     816           0 :                 p->locked = False;
     817           0 :                 free_packet(p);
     818           0 :                 return NULL;
     819             :         }
     820             : 
     821           0 :         if((rrec = make_response_record(wins_server_subnet,            /* subnet record. */
     822             :                                                 p,                     /* packet we sent. */
     823             :                                                 resp_fn,               /* function to call on response. */
     824             :                                                 timeout_fn,            /* function to call on timeout. */
     825             :                                                 (success_function)success_fn,            /* function to call on operation success. */
     826             :                                                 (fail_function)fail_fn,               /* function to call on operation fail. */
     827             :                                                 userdata)) == NULL) {
     828           0 :                 p->locked = False;
     829           0 :                 free_packet(p);
     830           0 :                 return NULL;
     831             :         }
     832             : 
     833           0 :         return rrec;
     834             : }
     835             : 
     836             : /****************************************************************************
     837             :  Queue a node status packet to a given name and address.
     838             : ****************************************************************************/
     839             : 
     840           0 : struct response_record *queue_node_status( struct subnet_record *subrec,
     841             :                           response_function resp_fn,
     842             :                           timeout_response_function timeout_fn,
     843             :                           node_status_success_function success_fn,
     844             :                           node_status_fail_function fail_fn,
     845             :                           struct userdata_struct *userdata,
     846             :                           struct nmb_name *nmbname,
     847             :                           struct in_addr send_ip)
     848             : {
     849             :         struct packet_struct *p;
     850             :         struct response_record *rrec;
     851             : 
     852             :         /* Sanity check. */
     853           0 :         if(subrec != unicast_subnet) {
     854           0 :                 DEBUG(0,("queue_register_multihomed_name: should only be done on \
     855             : unicast subnet. subnet is %s\n.", subrec->subnet_name ));
     856           0 :                 return NULL;
     857             :         }
     858             : 
     859           0 :         if(assert_check_subnet(subrec))
     860           0 :                 return NULL;
     861             : 
     862           0 :         if(( p = create_and_init_netbios_packet(nmbname, False, False, send_ip)) == NULL)
     863           0 :                 return NULL;
     864             : 
     865           0 :         if(initiate_node_status_packet(p) == False) {
     866           0 :                 p->locked = False;
     867           0 :                 free_packet(p);
     868           0 :                 return NULL;
     869             :         }
     870             : 
     871           0 :         if((rrec = make_response_record(subrec,           /* subnet record. */
     872             :                                         p,                     /* packet we sent. */
     873             :                                         resp_fn,               /* function to call on response. */
     874             :                                         timeout_fn,            /* function to call on timeout. */
     875             :                                         (success_function)success_fn,            /* function to call on operation success. */
     876             :                                         (fail_function)fail_fn,               /* function to call on operation fail. */
     877             :                                         userdata)) == NULL) {
     878           0 :                 p->locked = False;
     879           0 :                 free_packet(p);
     880           0 :                 return NULL;
     881             :         }
     882             : 
     883           0 :         return rrec;
     884             : }
     885             : 
     886             : /****************************************************************************
     887             :   Reply to a netbios name packet.  see rfc1002.txt
     888             : ****************************************************************************/
     889             : 
     890         840 : void reply_netbios_packet(struct packet_struct *orig_packet,
     891             :                           int rcode, enum netbios_reply_type_code rcv_code, int opcode,
     892             :                           int ttl, char *data,int len)
     893             : {
     894             :         struct packet_struct packet;
     895         840 :         struct nmb_packet *nmb = NULL;
     896             :         struct res_rec answers;
     897         840 :         struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
     898         840 :         bool loopback_this_packet = False;
     899         840 :         int rr_type = RR_TYPE_NB;
     900         840 :         const char *packet_type = "unknown";
     901             : 
     902             :         /* Check if we are sending to or from ourselves. */
     903         840 :         if(ismyip_v4(orig_packet->ip) && (orig_packet->port == global_nmb_port))
     904           5 :                 loopback_this_packet = True;
     905             : 
     906         840 :         nmb = &packet.packet.nmb;
     907             : 
     908             :         /* Do a partial copy of the packet. We clear the locked flag and
     909             :                         the resource record pointers. */
     910         840 :         packet = *orig_packet;   /* Full structure copy. */
     911         840 :         packet.locked = False;
     912         840 :         nmb->answers = NULL;
     913         840 :         nmb->nsrecs = NULL;
     914         840 :         nmb->additional = NULL;
     915             : 
     916         840 :         switch (rcv_code) {
     917          50 :                 case NMB_STATUS:
     918          50 :                         packet_type = "nmb_status";
     919          50 :                         nmb->header.nm_flags.recursion_desired = False;
     920          50 :                         nmb->header.nm_flags.recursion_available = False;
     921          50 :                         rr_type = RR_TYPE_NBSTAT;
     922          50 :                         break;
     923         783 :                 case NMB_QUERY:
     924         783 :                         packet_type = "nmb_query";
     925         783 :                         nmb->header.nm_flags.recursion_desired = True;
     926         783 :                         nmb->header.nm_flags.recursion_available = True;
     927         783 :                         if (rcode) {
     928           0 :                                 rr_type = RR_TYPE_NULL;
     929             :                         }
     930         783 :                         break;
     931           7 :                 case NMB_REG:
     932             :                 case NMB_REG_REFRESH:
     933           7 :                         packet_type = "nmb_reg";
     934           7 :                         nmb->header.nm_flags.recursion_desired = True;
     935           7 :                         nmb->header.nm_flags.recursion_available = True;
     936           7 :                         break;
     937           0 :                 case NMB_REL:
     938           0 :                         packet_type = "nmb_rel";
     939           0 :                         nmb->header.nm_flags.recursion_desired = False;
     940           0 :                         nmb->header.nm_flags.recursion_available = False;
     941           0 :                         break;
     942           0 :                 case NMB_WAIT_ACK:
     943           0 :                         packet_type = "nmb_wack";
     944           0 :                         nmb->header.nm_flags.recursion_desired = False;
     945           0 :                         nmb->header.nm_flags.recursion_available = False;
     946           0 :                         rr_type = RR_TYPE_NULL;
     947           0 :                         break;
     948           0 :                 case WINS_REG:
     949           0 :                         packet_type = "wins_reg";
     950           0 :                         nmb->header.nm_flags.recursion_desired = True;
     951           0 :                         nmb->header.nm_flags.recursion_available = True;
     952           0 :                         break;
     953           0 :                 case WINS_QUERY:
     954           0 :                         packet_type = "wins_query";
     955           0 :                         nmb->header.nm_flags.recursion_desired = True;
     956           0 :                         nmb->header.nm_flags.recursion_available = True;
     957           0 :                         if (rcode) {
     958           0 :                                 rr_type = RR_TYPE_NULL;
     959             :                         }
     960           0 :                         break;
     961           0 :                 default:
     962           0 :                         DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
     963             :                                 packet_type, nmb_namestr(&orig_nmb->question.question_name),
     964             :                                 inet_ntoa(packet.ip)));
     965           0 :                         return;
     966             :         }
     967             : 
     968         840 :         DEBUG(4, ("reply_netbios_packet: sending a reply of packet type: %s "
     969             :                   "%s to ip %s for id %d\n", packet_type,
     970             :                   nmb_namestr(&orig_nmb->question.question_name),
     971             :                   inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
     972             : 
     973         840 :         nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
     974         840 :         nmb->header.opcode = opcode;
     975         840 :         nmb->header.response = True;
     976         840 :         nmb->header.nm_flags.bcast = False;
     977         840 :         nmb->header.nm_flags.trunc = False;
     978         840 :         nmb->header.nm_flags.authoritative = True;
     979             : 
     980         840 :         nmb->header.rcode = rcode;
     981         840 :         nmb->header.qdcount = 0;
     982         840 :         nmb->header.ancount = 1;
     983         840 :         nmb->header.nscount = 0;
     984         840 :         nmb->header.arcount = 0;
     985             : 
     986         840 :         memset((char*)&nmb->question,'\0',sizeof(nmb->question));
     987             : 
     988         840 :         nmb->answers = &answers;
     989         840 :         memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
     990             : 
     991         840 :         nmb->answers->rr_name  = orig_nmb->question.question_name;
     992         840 :         nmb->answers->rr_type  = rr_type;
     993         840 :         nmb->answers->rr_class = RR_CLASS_IN;
     994         840 :         nmb->answers->ttl      = ttl;
     995             : 
     996         840 :         if (data && len) {
     997         840 :                 if (len < 0 || len > sizeof(nmb->answers->rdata)) {
     998           0 :                         DEBUG(5,("reply_netbios_packet: "
     999             :                                 "invalid packet len (%d)\n",
    1000             :                                 len ));
    1001           0 :                         return;
    1002             :                 }
    1003         840 :                 nmb->answers->rdlength = len;
    1004         840 :                 memcpy(nmb->answers->rdata, data, len);
    1005             :         }
    1006             : 
    1007         840 :         packet.packet_type = NMB_PACKET;
    1008         840 :         packet.recv_fd = -1;
    1009             :         /* Ensure we send out on the same fd that the original
    1010             :                 packet came in on to give the correct source IP address. */
    1011         840 :         if (orig_packet->send_fd != -1) {
    1012         840 :                 packet.send_fd = orig_packet->send_fd;
    1013             :         } else {
    1014           0 :                 packet.send_fd = orig_packet->recv_fd;
    1015             :         }
    1016         840 :         packet.timestamp = time(NULL);
    1017             : 
    1018         840 :         debug_nmb_packet(&packet);
    1019             : 
    1020         840 :         if(loopback_this_packet) {
    1021             :                 struct packet_struct *lo_packet;
    1022           5 :                 DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
    1023           5 :                 if((lo_packet = copy_packet(&packet)) == NULL)
    1024           0 :                         return;
    1025           5 :                 queue_packet(lo_packet);
    1026         835 :         } else if (!send_packet(&packet)) {
    1027          35 :                 DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
    1028             :                         inet_ntoa(packet.ip),packet.port));
    1029             :         }
    1030             : }
    1031             : 
    1032             : /*******************************************************************
    1033             :   Queue a packet into a packet queue
    1034             : ******************************************************************/
    1035             : 
    1036        6460 : void queue_packet(struct packet_struct *packet)
    1037             : {
    1038        6460 :         DLIST_ADD_END(packet_queue, packet);
    1039        6460 : }
    1040             : 
    1041             : /****************************************************************************
    1042             :  Try and find a matching subnet record for a datagram port 138 packet.
    1043             : ****************************************************************************/
    1044             : 
    1045         436 : static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
    1046             : {
    1047             :         struct subnet_record *subrec;
    1048             : 
    1049             :         /* Go through all the broadcast subnets and see if the mask matches. */
    1050         436 :         for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
    1051         436 :                 if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
    1052         436 :                         return subrec;
    1053             :         }
    1054             : 
    1055             :         /* If the subnet record is the remote announce broadcast subnet,
    1056             :                 hack it here to be the first subnet. This is really gross and
    1057             :                 is needed due to people turning on port 137/138 broadcast
    1058             :                 forwarding on their routers. May fire and brimstone rain
    1059             :                 down upon them...
    1060             :         */
    1061             : 
    1062           0 :         return FIRST_SUBNET;
    1063             : }
    1064             : 
    1065             : /****************************************************************************
    1066             : Dispatch a browse frame from port 138 to the correct processing function.
    1067             : ****************************************************************************/
    1068             : 
    1069         436 : static void process_browse_packet(struct packet_struct *p, const char *buf,int len)
    1070             : {
    1071         436 :         struct dgram_packet *dgram = &p->packet.dgram;
    1072         436 :         int command = CVAL(buf,0);
    1073         436 :         struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
    1074             :         char scope[64];
    1075             :         unstring src_name;
    1076             : 
    1077             :         /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
    1078         436 :         pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
    1079         436 :         if (!strequal(scope, lp_netbios_scope())) {
    1080           0 :                 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
    1081             : mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, lp_netbios_scope()));
    1082         125 :                 return;
    1083             :         }
    1084             : 
    1085         436 :         pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
    1086         436 :         if (is_myname(src_name)) {
    1087         125 :                 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Source name \
    1088             : %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
    1089         125 :                 return;
    1090             :         }
    1091             : 
    1092         311 :         switch (command) {
    1093          83 :                 case ANN_HostAnnouncement:
    1094          83 :                         debug_browse_data(buf, len);
    1095          83 :                         process_host_announce(subrec, p, buf+1);
    1096          83 :                         break;
    1097         132 :                 case ANN_DomainAnnouncement:
    1098         132 :                         debug_browse_data(buf, len);
    1099         132 :                         process_workgroup_announce(subrec, p, buf+1);
    1100         132 :                         break;
    1101          62 :                 case ANN_LocalMasterAnnouncement:
    1102          62 :                         debug_browse_data(buf, len);
    1103          62 :                         process_local_master_announce(subrec, p, buf+1);
    1104          62 :                         break;
    1105           5 :                 case ANN_AnnouncementRequest:
    1106           5 :                         debug_browse_data(buf, len);
    1107           5 :                         process_announce_request(subrec, p, buf+1);
    1108           5 :                         break;
    1109          29 :                 case ANN_Election:
    1110          29 :                         debug_browse_data(buf, len);
    1111          29 :                         process_election(subrec, p, buf+1);
    1112          29 :                         break;
    1113           0 :                 case ANN_GetBackupListReq:
    1114           0 :                         debug_browse_data(buf, len);
    1115           0 :                         process_get_backup_list_request(subrec, p, buf+1);
    1116           0 :                         break;
    1117           0 :                 case ANN_GetBackupListResp:
    1118           0 :                         debug_browse_data(buf, len);
    1119             :                         /* We never send ANN_GetBackupListReq so we should never get these. */
    1120           0 :                         DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
    1121             : packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
    1122           0 :                         break;
    1123           0 :                 case ANN_ResetBrowserState:
    1124           0 :                         debug_browse_data(buf, len);
    1125           0 :                         process_reset_browser(subrec, p, buf+1);
    1126           0 :                         break;
    1127           0 :                 case ANN_MasterAnnouncement:
    1128             :                         /* Master browser datagrams must be processed on the unicast subnet. */
    1129           0 :                         subrec = unicast_subnet;
    1130             : 
    1131           0 :                         debug_browse_data(buf, len);
    1132           0 :                         process_master_browser_announce(subrec, p, buf+1);
    1133           0 :                         break;
    1134           0 :                 case ANN_BecomeBackup:
    1135             :                         /*
    1136             :                          * We don't currently implement this. Log it just in case.
    1137             :                          */
    1138           0 :                         debug_browse_data(buf, len);
    1139           0 :                         DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
    1140             : command ANN_BecomeBackup from %s IP %s to %s\n", subrec->subnet_name, nmb_namestr(&dgram->source_name),
    1141             :                                         inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
    1142           0 :                         break;
    1143           0 :                 default:
    1144           0 :                         debug_browse_data(buf, len);
    1145           0 :                         DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
    1146             : command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
    1147             :                                 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
    1148           0 :                         break;
    1149             :         }
    1150             : }
    1151             : 
    1152             : /****************************************************************************
    1153             :  Dispatch a LanMan browse frame from port 138 to the correct processing function.
    1154             : ****************************************************************************/
    1155             : 
    1156           0 : static void process_lanman_packet(struct packet_struct *p, const char *buf,int len)
    1157             : {
    1158           0 :         struct dgram_packet *dgram = &p->packet.dgram;
    1159           0 :         int command = SVAL(buf,0);
    1160           0 :         struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
    1161             :         char scope[64];
    1162             :         unstring src_name;
    1163             : 
    1164             :         /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
    1165             : 
    1166           0 :         pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
    1167           0 :         if (!strequal(scope, lp_netbios_scope())) {
    1168           0 :                 DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
    1169             : mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, lp_netbios_scope()));
    1170           0 :                 return;
    1171             :         }
    1172             : 
    1173           0 :         pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
    1174           0 :         if (is_myname(src_name)) {
    1175           0 :                 DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
    1176             : %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
    1177           0 :                 return;
    1178             :         }
    1179             : 
    1180           0 :         switch (command) {
    1181           0 :                 case ANN_HostAnnouncement:
    1182           0 :                         debug_browse_data(buf, len);
    1183           0 :                         process_lm_host_announce(subrec, p, buf+1, len > 1 ? len-1 : 0);
    1184           0 :                         break;
    1185           0 :                 case ANN_AnnouncementRequest:
    1186           0 :                         process_lm_announce_request(subrec, p, buf+1, len > 1 ? len-1 : 0);
    1187           0 :                         break;
    1188           0 :                 default:
    1189           0 :                         DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
    1190             : command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
    1191             :                                 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
    1192           0 :                         break;
    1193             :         }
    1194             : }
    1195             : 
    1196             : /****************************************************************************
    1197             :   Determine if a packet is for us on port 138. Note that to have any chance of
    1198             :   being efficient we need to drop as many packets as possible at this
    1199             :   stage as subsequent processing is expensive. 
    1200             : ****************************************************************************/
    1201             : 
    1202        1307 : static bool listening(struct packet_struct *p,struct nmb_name *nbname)
    1203             : {
    1204        1307 :         struct subnet_record *subrec = NULL;
    1205             : 
    1206        1307 :         for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
    1207        1307 :                 if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
    1208        1307 :                         break;
    1209             :         }
    1210             : 
    1211        1307 :         if(subrec == NULL)
    1212           0 :                 subrec = unicast_subnet;
    1213             : 
    1214        1307 :         return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
    1215             : }
    1216             : 
    1217             : /****************************************************************************
    1218             :   Process udp 138 datagrams
    1219             : ****************************************************************************/
    1220             : 
    1221        1307 : static void process_dgram(struct packet_struct *p)
    1222             : {
    1223             :         const char *buf;
    1224             :         const char *buf2;
    1225             :         int len;
    1226        1307 :         struct dgram_packet *dgram = &p->packet.dgram;
    1227             : 
    1228             :         /* If we aren't listening to the destination name then ignore the packet */
    1229        1307 :         if (!listening(p,&dgram->dest_name)) {
    1230         835 :                         nb_packet_dispatch(packet_server, p);
    1231         835 :                         DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
    1232             :                                 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
    1233         835 :                         return;
    1234             :         }
    1235             : 
    1236         472 :         if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
    1237           0 :                 nb_packet_dispatch(packet_server, p);
    1238             :                 /* Don't process error packets etc yet */
    1239           0 :                 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
    1240             : an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
    1241           0 :                 return;
    1242             :         }
    1243             : 
    1244             :         /* Ensure we have a large enough packet before looking inside. */
    1245         472 :         if (dgram->datasize < (smb_vwv12 - 2)) {
    1246             :                 /* That's the offset minus the 4 byte length + 2 bytes of offset. */
    1247           0 :                 DEBUG(0,("process_dgram: ignoring too short dgram packet (%u) sent to name %s from IP %s\n",
    1248             :                         (unsigned int)dgram->datasize,
    1249             :                         nmb_namestr(&dgram->dest_name),
    1250             :                         inet_ntoa(p->ip) ));
    1251           0 :                 return;
    1252             :         }
    1253             : 
    1254         472 :         buf = &dgram->data[0];
    1255         472 :         buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */
    1256             : 
    1257         472 :         if (CVAL(buf,smb_com) != SMBtrans)
    1258           0 :                 return;
    1259             : 
    1260         472 :         len = SVAL(buf,smb_vwv11);
    1261         472 :         buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
    1262             : 
    1263         472 :         if (len <= 0 || len > dgram->datasize) {
    1264           0 :                 DEBUG(0,("process_dgram: ignoring malformed1 (datasize = %d, len = %d) datagram \
    1265             : packet sent to name %s from IP %s\n",
    1266             :                         dgram->datasize,
    1267             :                         len,
    1268             :                         nmb_namestr(&dgram->dest_name),
    1269             :                         inet_ntoa(p->ip) ));
    1270           0 :                 return;
    1271             :         }
    1272             : 
    1273         472 :         if (buf2 < dgram->data || (buf2 >= dgram->data + dgram->datasize)) {
    1274           0 :                 DEBUG(0,("process_dgram: ignoring malformed2 (datasize = %d, len=%d, off=%d) datagram \
    1275             : packet sent to name %s from IP %s\n",
    1276             :                         dgram->datasize,
    1277             :                         len,
    1278             :                         (int)PTR_DIFF(buf2, dgram->data),
    1279             :                         nmb_namestr(&dgram->dest_name),
    1280             :                         inet_ntoa(p->ip) ));
    1281           0 :                 return;
    1282             :         }
    1283             : 
    1284         472 :         if ((buf2 + len < dgram->data) || (buf2 + len > dgram->data + dgram->datasize)) {
    1285           0 :                 DEBUG(0,("process_dgram: ignoring malformed3 (datasize = %d, len=%d, off=%d) datagram \
    1286             : packet sent to name %s from IP %s\n",
    1287             :                         dgram->datasize,
    1288             :                         len,
    1289             :                         (int)PTR_DIFF(buf2, dgram->data),
    1290             :                         nmb_namestr(&dgram->dest_name),
    1291             :                         inet_ntoa(p->ip) ));
    1292           0 :                 return;
    1293             :         }
    1294             : 
    1295         472 :         DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
    1296             :                 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
    1297             :                 inet_ntoa(p->ip), smb_buf_const(buf),CVAL(buf2,0),len));
    1298             : 
    1299             :         /* Datagram packet received for the browser mailslot */
    1300         472 :         if (strequal(smb_buf_const(buf),BROWSE_MAILSLOT)) {
    1301         436 :                 process_browse_packet(p,buf2,len);
    1302         436 :                 return;
    1303             :         }
    1304             : 
    1305             :         /* Datagram packet received for the LAN Manager mailslot */
    1306          36 :         if (strequal(smb_buf_const(buf),LANMAN_MAILSLOT)) {
    1307           0 :                 process_lanman_packet(p,buf2,len);
    1308           0 :                 return;
    1309             :         }
    1310             : 
    1311             :         /* Datagram packet received for the domain logon mailslot */
    1312          36 :         if (strequal(smb_buf_const(buf),NET_LOGON_MAILSLOT)) {
    1313           4 :                 process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
    1314           4 :                 return;
    1315             :         }
    1316             : 
    1317             :         /* Datagram packet received for the NT domain logon mailslot */
    1318          32 :         if (strequal(smb_buf_const(buf),NT_LOGON_MAILSLOT)) {
    1319          23 :                 process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
    1320          23 :                 return;
    1321             :         }
    1322             : 
    1323           9 :         nb_packet_dispatch(packet_server, p);
    1324             : }
    1325             : 
    1326             : /****************************************************************************
    1327             :   Validate a response nmb packet.
    1328             : ****************************************************************************/
    1329             : 
    1330         107 : static bool validate_nmb_response_packet( struct nmb_packet *nmb )
    1331             : {
    1332         107 :         bool ignore = False;
    1333             : 
    1334         107 :         switch (nmb->header.opcode) {
    1335           5 :                 case NMB_NAME_REG_OPCODE:
    1336             :                 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
    1337             :                 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
    1338           5 :                         if (nmb->header.ancount == 0) {
    1339           0 :                                 DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
    1340           0 :                                 ignore = True;
    1341             :                         }
    1342           5 :                         break;
    1343             : 
    1344         102 :                 case NMB_NAME_QUERY_OPCODE:
    1345         102 :                         if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {
    1346           0 :                                 DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
    1347           0 :                                 ignore = True;
    1348             :                         }
    1349         102 :                         break;
    1350             : 
    1351           0 :                 case NMB_NAME_RELEASE_OPCODE:
    1352           0 :                         if (nmb->header.ancount == 0) {
    1353           0 :                                 DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
    1354           0 :                                 ignore = True;
    1355             :                         }
    1356           0 :                         break;
    1357             : 
    1358           0 :                 case NMB_WACK_OPCODE:
    1359             :                         /* Check WACK response here. */
    1360           0 :                         if (nmb->header.ancount != 1) {
    1361           0 :                                 DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
    1362           0 :                                 ignore = True;
    1363             :                         }
    1364           0 :                         break;
    1365           0 :                 default:
    1366           0 :                         DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
    1367             :                                         nmb->header.opcode));
    1368           0 :                         return True;
    1369             :         }
    1370             : 
    1371         107 :         if(ignore)
    1372           0 :                 DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
    1373             : 
    1374         107 :         return ignore;
    1375             : }
    1376             : 
    1377             : /****************************************************************************
    1378             :   Validate a request nmb packet.
    1379             : ****************************************************************************/
    1380             : 
    1381        5046 : static bool validate_nmb_packet( struct nmb_packet *nmb )
    1382             : {
    1383        5046 :         bool ignore = False;
    1384             : 
    1385        5046 :         switch (nmb->header.opcode) {
    1386        1928 :                 case NMB_NAME_REG_OPCODE:
    1387             :                 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
    1388             :                 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
    1389             :                 case NMB_NAME_MULTIHOMED_REG_OPCODE:
    1390        1928 :                         if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
    1391           0 :                                 DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
    1392           0 :                                 ignore = True;
    1393             :                         }
    1394        1928 :                         break;
    1395             : 
    1396        3118 :                 case NMB_NAME_QUERY_OPCODE:
    1397        3167 :                         if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
    1398          50 :                                         (nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {
    1399           0 :                                 DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
    1400           0 :                                 ignore = True;
    1401             :                         }
    1402        3118 :                         break;
    1403             : 
    1404           0 :                 case NMB_NAME_RELEASE_OPCODE:
    1405           0 :                         if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
    1406           0 :                                 DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
    1407           0 :                                 ignore = True;
    1408             :                         }
    1409           0 :                         break;
    1410           0 :                 default:
    1411           0 :                         DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
    1412             :                                 nmb->header.opcode));
    1413           0 :                         return True;
    1414             :         }
    1415             : 
    1416        5046 :         if(ignore)
    1417           0 :                 DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
    1418             : 
    1419        5046 :         return ignore;
    1420             : }
    1421             : 
    1422             : /****************************************************************************
    1423             :   Find a subnet (and potentially a response record) for a packet.
    1424             : ****************************************************************************/
    1425             : 
    1426        5153 : static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
    1427             :                                                          struct response_record **pprrec)
    1428             : {
    1429        5153 :         struct nmb_packet *nmb = &p->packet.nmb;
    1430        5153 :         struct response_record *rrec = NULL;
    1431        5153 :         struct subnet_record *subrec = NULL;
    1432             : 
    1433        5153 :         if(pprrec != NULL)
    1434         107 :                 *pprrec = NULL;
    1435             : 
    1436        5153 :         if(nmb->header.response) {
    1437             :                 /* It's a response packet. Find a record for it or it's an error. */
    1438             : 
    1439         107 :                 rrec = find_response_record( &subrec, nmb->header.name_trn_id);
    1440         107 :                 if(rrec == NULL) {
    1441           5 :                         DEBUG(3, ("find_subnet_for_nmb_packet: response "
    1442             :                                   "record not found for response id %d\n",
    1443             :                                   nmb->header.name_trn_id));
    1444           5 :                         nb_packet_dispatch(packet_server, p);
    1445           5 :                         return NULL;
    1446             :                 }
    1447             : 
    1448         102 :                 if(subrec == NULL) {
    1449           0 :                         DEBUG(0, ("find_subnet_for_nmb_packet: subnet record "
    1450             :                                   "not found for response id %d\n",
    1451             :                                   nmb->header.name_trn_id));
    1452           0 :                         return NULL;
    1453             :                 }
    1454             : 
    1455         102 :                 if(pprrec != NULL)
    1456         102 :                         *pprrec = rrec;
    1457         102 :                 return subrec;
    1458             :         }
    1459             : 
    1460             :         /* Try and see what subnet this packet belongs to. */
    1461             : 
    1462             :         /* WINS server ? */
    1463        5046 :         if(packet_is_for_wins_server(p))
    1464           0 :                 return wins_server_subnet;
    1465             : 
    1466             :         /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
    1467        5046 :         if(nmb->header.nm_flags.bcast == False)
    1468         203 :                 return unicast_subnet;
    1469             : 
    1470             :         /* Go through all the broadcast subnets and see if the mask matches. */
    1471        4843 :         for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
    1472        4843 :                 if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
    1473        4843 :                         return subrec;
    1474             :         }
    1475             : 
    1476             :         /* If none match it must have been a directed broadcast - assign the remote_broadcast_subnet. */
    1477           0 :         return remote_broadcast_subnet;
    1478             : }
    1479             : 
    1480             : /****************************************************************************
    1481             :   Process a nmb request packet - validate the packet and route it.
    1482             : ****************************************************************************/
    1483             : 
    1484        5046 : static void process_nmb_request(struct packet_struct *p)
    1485             : {
    1486        5046 :         struct nmb_packet *nmb = &p->packet.nmb;
    1487        5046 :         struct subnet_record *subrec = NULL;
    1488             : 
    1489        5046 :         debug_nmb_packet(p);
    1490             : 
    1491             :         /* Ensure we have a good packet. */
    1492        5046 :         if(validate_nmb_packet(nmb))
    1493           0 :                 return;
    1494             : 
    1495             :         /* Allocate a subnet to this packet - if we cannot - fail. */
    1496        5046 :         if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
    1497           0 :                 return;
    1498             : 
    1499        5046 :         switch (nmb->header.opcode) {
    1500        1928 :                 case NMB_NAME_REG_OPCODE:
    1501        1928 :                         if(subrec == wins_server_subnet)
    1502           0 :                                 wins_process_name_registration_request(subrec, p);
    1503             :                         else
    1504        1928 :                                 process_name_registration_request(subrec, p);
    1505        1928 :                         break;
    1506             : 
    1507           0 :                 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
    1508             :                 case NMB_NAME_REFRESH_OPCODE_9:
    1509           0 :                         if(subrec == wins_server_subnet)
    1510           0 :                                 wins_process_name_refresh_request(subrec, p);
    1511             :                         else
    1512           0 :                                 process_name_refresh_request(subrec, p);
    1513           0 :                         break;
    1514             : 
    1515           0 :                 case NMB_NAME_MULTIHOMED_REG_OPCODE:
    1516           0 :                         if(subrec == wins_server_subnet) {
    1517           0 :                                 wins_process_multihomed_name_registration_request(subrec, p);
    1518             :                         } else {
    1519           0 :                                 DEBUG(0,("process_nmb_request: Multihomed registration request must be \
    1520             : directed at a WINS server.\n"));
    1521             :                         }
    1522           0 :                         break;
    1523             : 
    1524        3118 :                 case NMB_NAME_QUERY_OPCODE:
    1525        3118 :                         switch (nmb->question.question_type) {
    1526        3068 :                                 case QUESTION_TYPE_NB_QUERY:
    1527        3068 :                                         if(subrec == wins_server_subnet)
    1528           0 :                                                 wins_process_name_query_request(subrec, p);
    1529             :                                         else
    1530        3068 :                                                 process_name_query_request(subrec, p);
    1531        3068 :                                         break;
    1532          50 :                                 case QUESTION_TYPE_NB_STATUS:
    1533          50 :                                         if(subrec == wins_server_subnet) {
    1534           0 :                                                 DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
    1535             : not allowed.\n"));
    1536           0 :                                                 break;
    1537             :                                         } else {
    1538          50 :                                                 process_node_status_request(subrec, p);
    1539             :                                         }
    1540          50 :                                         break;
    1541             :                         }
    1542        3118 :                         break;
    1543             : 
    1544           0 :                 case NMB_NAME_RELEASE_OPCODE:
    1545           0 :                         if(subrec == wins_server_subnet)
    1546           0 :                                 wins_process_name_release_request(subrec, p);
    1547             :                         else
    1548           0 :                                 process_name_release_request(subrec, p);
    1549           0 :                         break;
    1550             :         }
    1551             : }
    1552             : 
    1553             : /****************************************************************************
    1554             :   Process a nmb response packet - validate the packet and route it.
    1555             :   to either the WINS server or a normal response.
    1556             : ****************************************************************************/
    1557             : 
    1558         107 : static void process_nmb_response(struct packet_struct *p)
    1559             : {
    1560         107 :         struct nmb_packet *nmb = &p->packet.nmb;
    1561         107 :         struct subnet_record *subrec = NULL;
    1562         107 :         struct response_record *rrec = NULL;
    1563             : 
    1564         107 :         debug_nmb_packet(p);
    1565             : 
    1566         107 :         if(validate_nmb_response_packet(nmb))
    1567           5 :                 return;
    1568             : 
    1569         107 :         if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
    1570           5 :                 return;
    1571             : 
    1572         102 :         if(rrec == NULL) {
    1573           0 :                 DEBUG(0, ("process_nmb_response: response packet received but "
    1574             :                           "no response record found for id = %d. Ignoring "
    1575             :                           "packet.\n", nmb->header.name_trn_id));
    1576           0 :                 return;
    1577             :         }
    1578             : 
    1579             :         /* Increment the number of responses received for this record. */
    1580         102 :         rrec->num_msgs++;
    1581             :         /* Ensure we don't re-send the request. */
    1582         102 :         rrec->repeat_count = 0;
    1583             : 
    1584             :         /* Call the response received function for this packet. */
    1585         102 :         (*rrec->resp_fn)(subrec, rrec, p);
    1586             : }
    1587             : 
    1588             : /*******************************************************************
    1589             :   Run elements off the packet queue till its empty
    1590             : ******************************************************************/
    1591             : 
    1592       20118 : void run_packet_queue(void)
    1593             : {
    1594             :         struct packet_struct *p;
    1595             : 
    1596       45437 :         while ((p = packet_queue)) {
    1597        6460 :                 DLIST_REMOVE(packet_queue, p);
    1598             : 
    1599        6460 :                 switch (p->packet_type) {
    1600        5153 :                         case NMB_PACKET:
    1601        5153 :                                 if(p->packet.nmb.header.response)
    1602         107 :                                         process_nmb_response(p);
    1603             :                                 else
    1604        5046 :                                         process_nmb_request(p);
    1605        5153 :                                 break;
    1606             : 
    1607        1307 :                         case DGRAM_PACKET:
    1608        1307 :                                 process_dgram(p);
    1609        1307 :                                 break;
    1610             :                 }
    1611        6460 :                 free_packet(p);
    1612             :         }
    1613       20118 : }
    1614             : 
    1615             : /*******************************************************************
    1616             :  Retransmit or timeout elements from all the outgoing subnet response
    1617             :  record queues. NOTE that this code must also check the WINS server
    1618             :  subnet for response records to timeout as the WINS server code
    1619             :  can send requests to check if a client still owns a name.
    1620             :  (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
    1621             : ******************************************************************/
    1622             : 
    1623       20118 : void retransmit_or_expire_response_records(time_t t)
    1624             : {
    1625             :         struct subnet_record *subrec;
    1626             : 
    1627       40236 :         for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
    1628             :                 struct response_record *rrec, *nextrrec;
    1629             : 
    1630       20118 :   restart:
    1631             : 
    1632       30439 :                 for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
    1633       10321 :                         nextrrec = rrec->next;
    1634             : 
    1635       10321 :                         if (rrec->repeat_time <= t) {
    1636        1157 :                                 if (rrec->repeat_count > 0) {
    1637             :                                         /* Resend while we have a non-zero repeat_count. */
    1638         792 :                                         if(!send_packet(rrec->packet)) {
    1639           0 :                                                 DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
    1640             : to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
    1641             :                                         }
    1642         792 :                                         rrec->repeat_time = t + rrec->repeat_interval;
    1643         792 :                                         rrec->repeat_count--;
    1644             :                                 } else {
    1645         365 :                                         DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
    1646             : on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
    1647             : 
    1648             :                                         /*
    1649             :                                          * Check the flag in this record to prevent recursion if we end
    1650             :                                          * up in this function again via the timeout function call.
    1651             :                                          */
    1652             : 
    1653         365 :                                         if(!rrec->in_expiration_processing) {
    1654             : 
    1655             :                                                 /*
    1656             :                                                  * Set the recursion protection flag in this record.
    1657             :                                                  */
    1658             : 
    1659         365 :                                                 rrec->in_expiration_processing = True;
    1660             : 
    1661             :                                                 /* Call the timeout function. This will deal with removing the
    1662             :                                                                 timed out packet. */
    1663         365 :                                                 if(rrec->timeout_fn) {
    1664         365 :                                                         (*rrec->timeout_fn)(subrec, rrec);
    1665             :                                                 } else {
    1666             :                                                         /* We must remove the record ourself if there is
    1667             :                                                                         no timeout function. */
    1668           0 :                                                         remove_response_record(subrec, rrec);
    1669             :                                                 }
    1670             :                                                 /* We have changed subrec->responselist,
    1671             :                                                  * restart from the beginning of this list. */
    1672         365 :                                                 goto restart;
    1673             :                                         } /* !rrec->in_expitation_processing */
    1674             :                                 } /* rrec->repeat_count > 0 */
    1675             :                         } /* rrec->repeat_time <= t */
    1676             :                 } /* end for rrec */
    1677             :         } /* end for subnet */
    1678       20118 : }
    1679             : 
    1680             : /****************************************************************************
    1681             :   Create an fd_set containing all the sockets in the subnet structures,
    1682             :   plus the broadcast sockets.
    1683             : ***************************************************************************/
    1684             : 
    1685             : struct socket_attributes {
    1686             :         enum packet_type type;
    1687             :         bool broadcast;
    1688             :         int fd;
    1689             :         bool triggered;
    1690             : };
    1691             : 
    1692          33 : static bool create_listen_array(struct socket_attributes **pattrs,
    1693             :                                   int *pnum_sockets)
    1694             : {
    1695          33 :         struct subnet_record *subrec = NULL;
    1696          33 :         int count = 0;
    1697          33 :         int num = 0;
    1698             :         struct socket_attributes *attrs;
    1699             : 
    1700             :         /* The ClientNMB and ClientDGRAM sockets */
    1701          33 :         count = 2;
    1702             : 
    1703             :         /* Check that we can add all the fd's we need. */
    1704          89 :         for (subrec = FIRST_SUBNET;
    1705          10 :              subrec != NULL;
    1706          33 :              subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
    1707          33 :                 if (subrec->nmb_sock != -1) {
    1708          33 :                         count += 1;
    1709             :                 }
    1710          33 :                 if (subrec->dgram_sock != -1) {
    1711          33 :                         count += 1;
    1712             :                 }
    1713          33 :                 if (subrec->nmb_bcast != -1) {
    1714          33 :                         count += 1;
    1715             :                 }
    1716          33 :                 if (subrec->dgram_bcast != -1) {
    1717          33 :                         count += 1;
    1718             :                 }
    1719             :         }
    1720             : 
    1721          33 :         attrs = talloc_zero_array(NULL, struct socket_attributes, count);
    1722          33 :         if (attrs == NULL) {
    1723           0 :                 DEBUG(1, ("talloc fail for attrs. "
    1724             :                           "size %d\n", count));
    1725           0 :                 return true;
    1726             :         }
    1727             : 
    1728          33 :         num = 0;
    1729             : 
    1730          33 :         attrs[num].fd = ClientNMB;
    1731          33 :         attrs[num].type = NMB_PACKET;
    1732          33 :         attrs[num].broadcast = false;
    1733          33 :         num += 1;
    1734             : 
    1735          33 :         attrs[num].fd = ClientDGRAM;
    1736          33 :         attrs[num].type = DGRAM_PACKET;
    1737          33 :         attrs[num].broadcast = false;
    1738          33 :         num += 1;
    1739             : 
    1740          66 :         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
    1741             : 
    1742          33 :                 if (subrec->nmb_sock != -1) {
    1743          33 :                         attrs[num].fd = subrec->nmb_sock;
    1744          33 :                         attrs[num].type = NMB_PACKET;
    1745          33 :                         attrs[num].broadcast = false;
    1746          33 :                         num += 1;
    1747             :                 }
    1748             : 
    1749          33 :                 if (subrec->nmb_bcast != -1) {
    1750          33 :                         attrs[num].fd = subrec->nmb_bcast;
    1751          33 :                         attrs[num].type = NMB_PACKET;
    1752          33 :                         attrs[num].broadcast = true;
    1753          33 :                         num += 1;
    1754             :                 }
    1755             : 
    1756          33 :                 if (subrec->dgram_sock != -1) {
    1757          33 :                         attrs[num].fd = subrec->dgram_sock;
    1758          33 :                         attrs[num].type = DGRAM_PACKET;
    1759          33 :                         attrs[num].broadcast = false;
    1760          33 :                         num += 1;
    1761             :                 }
    1762             : 
    1763          33 :                 if (subrec->dgram_bcast != -1) {
    1764          33 :                         attrs[num].fd = subrec->dgram_bcast;
    1765          33 :                         attrs[num].type = DGRAM_PACKET;
    1766          33 :                         attrs[num].broadcast = true;
    1767          33 :                         num += 1;
    1768             :                 }
    1769             :         }
    1770             : 
    1771          33 :         TALLOC_FREE(*pattrs);
    1772          33 :         *pattrs = attrs;
    1773             : 
    1774          33 :         *pnum_sockets = count;
    1775             : 
    1776          33 :         return False;
    1777             : }
    1778             : 
    1779             : /****************************************************************************
    1780             :  List of packets we're processing this select.
    1781             : ***************************************************************************/
    1782             : 
    1783             : struct processed_packet {
    1784             :         struct processed_packet *next;
    1785             :         struct processed_packet *prev;
    1786             :         enum packet_type packet_type;
    1787             :         struct in_addr ip;
    1788             :         int packet_id;
    1789             : };
    1790             : 
    1791             : /****************************************************************************
    1792             :  Have we seen this before ?
    1793             : ***************************************************************************/
    1794             : 
    1795        6453 : static bool is_processed_packet(struct processed_packet *processed_packet_list,
    1796             :                                 struct packet_struct *packet)
    1797             : {
    1798        6453 :         struct processed_packet *p = NULL;
    1799             : 
    1800        6453 :         for (p = processed_packet_list; p; p = p->next) {
    1801           0 :                 if (ip_equal_v4(p->ip, packet->ip) && p->packet_type == packet->packet_type) {
    1802           0 :                         if ((p->packet_type == NMB_PACKET) &&
    1803           0 :                                 (p->packet_id ==
    1804           0 :                                         packet->packet.nmb.header.name_trn_id)) {
    1805           0 :                                 return true;
    1806           0 :                         } else if ((p->packet_type == DGRAM_PACKET) &&
    1807           0 :                                 (p->packet_id ==
    1808           0 :                                         packet->packet.dgram.header.dgm_id)) {
    1809           0 :                                 return true;
    1810             :                         }
    1811             :                 }
    1812             :         }
    1813        6453 :         return false;
    1814             : }
    1815             : 
    1816             : /****************************************************************************
    1817             :  Keep a list of what we've seen before.
    1818             : ***************************************************************************/
    1819             : 
    1820        6453 : static bool store_processed_packet(struct processed_packet **pp_processed_packet_list,
    1821             :                                 struct packet_struct *packet)
    1822             : {
    1823        6453 :         struct processed_packet *p = SMB_MALLOC_P(struct processed_packet);
    1824        6453 :         if (!p) {
    1825           0 :                 return false;
    1826             :         }
    1827        6453 :         p->packet_type = packet->packet_type;
    1828        6453 :         p->ip = packet->ip;
    1829        6453 :         if (packet->packet_type == NMB_PACKET) {
    1830        5148 :                 p->packet_id = packet->packet.nmb.header.name_trn_id;
    1831        1305 :         } else if (packet->packet_type == DGRAM_PACKET) {
    1832        1305 :                 p->packet_id = packet->packet.dgram.header.dgm_id;
    1833             :         } else {
    1834           0 :                 SAFE_FREE(p);
    1835           0 :                 return false;
    1836             :         }
    1837             : 
    1838        6453 :         DLIST_ADD(*pp_processed_packet_list, p);
    1839        6453 :         return true;
    1840             : }
    1841             : 
    1842             : /****************************************************************************
    1843             :  Throw away what we've seen before.
    1844             : ***************************************************************************/
    1845             : 
    1846       15039 : static void free_processed_packet_list(struct processed_packet **pp_processed_packet_list)
    1847             : {
    1848       15039 :         struct processed_packet *p = NULL, *next = NULL;
    1849             : 
    1850       21492 :         for (p = *pp_processed_packet_list; p; p = next) {
    1851        6453 :                 next = p->next;
    1852        6453 :                 DLIST_REMOVE(*pp_processed_packet_list, p);
    1853        6453 :                 SAFE_FREE(p);
    1854             :         }
    1855       15039 : }
    1856             : 
    1857             : /****************************************************************************
    1858             :  Timeout callback - just notice we timed out.
    1859             : ***************************************************************************/
    1860             : 
    1861        5079 : static void nmbd_timeout_handler(struct tevent_context *ev,
    1862             :                         struct tevent_timer *te,
    1863             :                         struct timeval current_time,
    1864             :                         void *private_data)
    1865             : {
    1866        5079 :         bool *got_timeout = private_data;
    1867        5079 :         *got_timeout = true;
    1868        5079 : }
    1869             : 
    1870             : /****************************************************************************
    1871             :  fd callback - remember the fd that triggered.
    1872             : ***************************************************************************/
    1873             : 
    1874        7536 : static void nmbd_fd_handler(struct tevent_context *ev,
    1875             :                                 struct tevent_fd *fde,
    1876             :                                 uint16_t flags,
    1877             :                                 void *private_data)
    1878             : {
    1879        7536 :         struct socket_attributes *attr = private_data;
    1880        7536 :         attr->triggered = true;
    1881        7536 : }
    1882             : 
    1883             : /****************************************************************************
    1884             :  Read from a socket.
    1885             : ****************************************************************************/
    1886             : 
    1887        7536 : static ssize_t read_udp_v4_socket(
    1888             :         int fd,
    1889             :         char *buf,
    1890             :         size_t len,
    1891             :         struct sockaddr_storage *psa)
    1892             : {
    1893             :         ssize_t ret;
    1894        7536 :         socklen_t socklen = sizeof(*psa);
    1895        7536 :         struct sockaddr_in *si = (struct sockaddr_in *)psa;
    1896             : 
    1897        7536 :         memset((char *)psa,'\0',socklen);
    1898             : 
    1899        7536 :         ret = (ssize_t)sys_recvfrom(fd,buf,len,0,
    1900             :                         (struct sockaddr *)psa,&socklen);
    1901        7536 :         if (ret <= 0) {
    1902             :                 /* Don't print a low debug error for a non-blocking socket. */
    1903           0 :                 if (errno == EAGAIN) {
    1904           0 :                         DEBUG(10,("read_udp_v4_socket: returned EAGAIN\n"));
    1905             :                 } else {
    1906           0 :                         DEBUG(2,("read_udp_v4_socket: failed. errno=%s\n",
    1907             :                                 strerror(errno)));
    1908             :                 }
    1909           0 :                 return 0;
    1910             :         }
    1911             : 
    1912        7536 :         if (psa->ss_family != AF_INET) {
    1913           0 :                 DEBUG(2,("read_udp_v4_socket: invalid address family %d "
    1914             :                         "(not IPv4)\n", (int)psa->ss_family));
    1915           0 :                 return 0;
    1916             :         }
    1917             : 
    1918        7536 :         DEBUG(10,("read_udp_v4_socket: ip %s port %d read: %lu\n",
    1919             :                         inet_ntoa(si->sin_addr),
    1920             :                         si->sin_port,
    1921             :                         (unsigned long)ret));
    1922             : 
    1923        7536 :         return ret;
    1924             : }
    1925             : 
    1926             : /*******************************************************************
    1927             :  Read a packet from a socket and parse it, returning a packet ready
    1928             :  to be used or put on the queue. This assumes a UDP socket.
    1929             : ******************************************************************/
    1930             : 
    1931        7536 : static struct packet_struct *read_packet(int fd,enum packet_type packet_type)
    1932             : {
    1933             :         struct packet_struct *packet;
    1934             :         struct sockaddr_storage sa;
    1935        7536 :         struct sockaddr_in *si = (struct sockaddr_in *)&sa;
    1936             :         char buf[MAX_DGRAM_SIZE];
    1937             :         int length;
    1938             : 
    1939        7536 :         length = read_udp_v4_socket(fd,buf,sizeof(buf),&sa);
    1940        7536 :         if (length < MIN_DGRAM_SIZE || sa.ss_family != AF_INET) {
    1941           0 :                 return NULL;
    1942             :         }
    1943             : 
    1944        7536 :         packet = parse_packet(buf,
    1945             :                         length,
    1946             :                         packet_type,
    1947             :                         si->sin_addr,
    1948        7536 :                         ntohs(si->sin_port));
    1949        7536 :         if (!packet)
    1950           0 :                 return NULL;
    1951             : 
    1952        7536 :         packet->recv_fd = fd;
    1953        7536 :         packet->send_fd = -1;
    1954             : 
    1955        7536 :         DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
    1956             :                  length, inet_ntoa(packet->ip), packet->port ) );
    1957             : 
    1958        7536 :         return(packet);
    1959             : }
    1960             : 
    1961             : /****************************************************************************
    1962             :   Listens for NMB or DGRAM packets, and queues them.
    1963             :   return True if the socket is dead
    1964             : ***************************************************************************/
    1965             : 
    1966       20151 : bool listen_for_packets(struct messaging_context *msg, bool run_election)
    1967             : {
    1968             :         static struct socket_attributes *attrs = NULL;
    1969             :         static int listen_number = 0;
    1970             :         int num_sockets;
    1971             :         int i;
    1972             :         int loop_rtn;
    1973             :         int timeout_secs;
    1974             : 
    1975             : #ifndef SYNC_DNS
    1976             :         int dns_fd;
    1977       20151 :         int dns_pollidx = -1;
    1978             : #endif
    1979       20151 :         struct processed_packet *processed_packet_list = NULL;
    1980       20151 :         struct tevent_timer *te = NULL;
    1981       20151 :         bool got_timeout = false;
    1982       20151 :         TALLOC_CTX *frame = talloc_stackframe();
    1983             : 
    1984       20151 :         if ((attrs == NULL) || rescan_listen_set) {
    1985          33 :                 if (create_listen_array(&attrs, &listen_number)) {
    1986           0 :                         DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
    1987           0 :                         TALLOC_FREE(frame);
    1988           0 :                         return True;
    1989             :                 }
    1990          33 :                 rescan_listen_set = False;
    1991             :         }
    1992             : 
    1993       20151 :         num_sockets = listen_number;
    1994             : 
    1995             : #ifndef SYNC_DNS
    1996       20151 :         dns_fd = asyncdns_fd();
    1997       20151 :         if (dns_fd != -1) {
    1998           0 :                 attrs = talloc_realloc(NULL,
    1999             :                                         attrs,
    2000             :                                         struct socket_attributes,
    2001             :                                         num_sockets + 1);
    2002           0 :                 if (attrs == NULL) {
    2003           0 :                         TALLOC_FREE(frame);
    2004           0 :                         return true;
    2005             :                 }
    2006           0 :                 dns_pollidx = num_sockets;
    2007           0 :                 attrs[dns_pollidx].fd = dns_fd;
    2008             :                 /*
    2009             :                  * dummy values, we only need
    2010             :                  * fd and triggered.
    2011             :                  */
    2012           0 :                 attrs[dns_pollidx].type = NMB_PACKET;
    2013           0 :                 attrs[dns_pollidx].broadcast = false;
    2014           0 :                 num_sockets += 1;
    2015             :         }
    2016             : #endif
    2017             : 
    2018      141057 :         for (i=0; i<num_sockets; i++) {
    2019      120906 :                 struct tevent_fd *tfd = tevent_add_fd(nmbd_event_context(),
    2020             :                                                         frame,
    2021             :                                                         attrs[i].fd,
    2022             :                                                         TEVENT_FD_READ,
    2023             :                                                         nmbd_fd_handler,
    2024             :                                                         &attrs[i]);
    2025      120906 :                 if (tfd == NULL) {
    2026           0 :                         TALLOC_FREE(frame);
    2027           0 :                         return true;
    2028             :                 }
    2029      120906 :                 attrs[i].triggered = false;
    2030             :         }
    2031             : 
    2032             :         /*
    2033             :          * During elections and when expecting a netbios response packet we
    2034             :          * need to send election packets at tighter intervals.
    2035             :          * Ideally it needs to be the interval (in ms) between time now and
    2036             :          * the time we are expecting the next netbios packet.
    2037             :          */
    2038             : 
    2039       20151 :         if (run_election||num_response_packets) {
    2040        3422 :                 timeout_secs = 1;
    2041             :         } else {
    2042       16729 :                 timeout_secs = NMBD_SELECT_LOOP;
    2043             :         }
    2044             : 
    2045       20151 :         te = tevent_add_timer(nmbd_event_context(),
    2046             :                                 frame,
    2047             :                                 tevent_timeval_current_ofs(timeout_secs, 0),
    2048             :                                 nmbd_timeout_handler,
    2049             :                                 &got_timeout);
    2050       20151 :         if (te == NULL) {
    2051           0 :                 TALLOC_FREE(frame);
    2052           0 :                 return true;
    2053             :         }
    2054             : 
    2055       20151 :         loop_rtn = tevent_loop_once(nmbd_event_context());
    2056             : 
    2057       20118 :         if (loop_rtn == -1) {
    2058           0 :                 TALLOC_FREE(frame);
    2059           0 :                 return true;
    2060             :         }
    2061             : 
    2062       20118 :         if (got_timeout) {
    2063        5079 :                 TALLOC_FREE(frame);
    2064        5079 :                 return false;
    2065             :         }
    2066             : 
    2067             : #ifndef SYNC_DNS
    2068       15039 :         if ((dns_fd != -1) && (dns_pollidx != -1) &&
    2069           0 :             attrs[dns_pollidx].triggered){
    2070           0 :                 run_dns_queue(msg);
    2071           0 :                 TALLOC_FREE(frame);
    2072           0 :                 return false;
    2073             :         }
    2074             : #endif
    2075             : 
    2076      105273 :         for(i = 0; i < listen_number; i++) {
    2077             :                 enum packet_type packet_type;
    2078             :                 struct packet_struct *packet;
    2079             :                 const char *packet_name;
    2080             :                 int client_fd;
    2081             :                 int client_port;
    2082             : 
    2083       90234 :                 if (!attrs[i].triggered) {
    2084       82698 :                         continue;
    2085             :                 }
    2086             : 
    2087        7536 :                 if (attrs[i].type == NMB_PACKET) {
    2088             :                         /* Port 137 */
    2089        5906 :                         packet_type = NMB_PACKET;
    2090        5906 :                         packet_name = "nmb";
    2091        5906 :                         client_fd = ClientNMB;
    2092        5906 :                         client_port = global_nmb_port;
    2093             :                 } else {
    2094             :                         /* Port 138 */
    2095        1630 :                         packet_type = DGRAM_PACKET;
    2096        1630 :                         packet_name = "dgram";
    2097        1630 :                         client_fd = ClientDGRAM;
    2098        1630 :                         client_port = DGRAM_PORT;
    2099             :                 }
    2100             : 
    2101        7536 :                 packet = read_packet(attrs[i].fd, packet_type);
    2102        7536 :                 if (!packet) {
    2103           0 :                         continue;
    2104             :                 }
    2105             : 
    2106             :                 /*
    2107             :                  * If we got a packet on the broadcast socket and interfaces
    2108             :                  * only is set then check it came from one of our local nets.
    2109             :                  */
    2110       14282 :                 if (lp_bind_interfaces_only() &&
    2111        7536 :                     (attrs[i].fd == client_fd) &&
    2112           0 :                     (!is_local_net_v4(packet->ip))) {
    2113           0 :                         DEBUG(7,("discarding %s packet sent to broadcast socket from %s:%d\n",
    2114             :                                 packet_name, inet_ntoa(packet->ip), packet->port));
    2115           0 :                         free_packet(packet);
    2116           0 :                         continue;
    2117             :                 }
    2118             : 
    2119        7536 :                 if (!IS_DC) {
    2120        5517 :                         if ((is_loopback_ip_v4(packet->ip) || ismyip_v4(packet->ip)) &&
    2121        1111 :                         packet->port == client_port)
    2122             :                         {
    2123        1083 :                                 if (client_port == DGRAM_PORT) {
    2124         325 :                                         DEBUG(7,("discarding own dgram packet from %s:%d\n",
    2125             :                                                 inet_ntoa(packet->ip),packet->port));
    2126         325 :                                         free_packet(packet);
    2127         325 :                                         continue;
    2128             :                                 }
    2129             : 
    2130         758 :                                 if (packet->packet.nmb.header.nm_flags.bcast) {
    2131         758 :                                         DEBUG(7,("discarding own nmb bcast packet from %s:%d\n",
    2132             :                                                 inet_ntoa(packet->ip),packet->port));
    2133         758 :                                         free_packet(packet);
    2134         758 :                                         continue;
    2135             :                                 }
    2136             :                         }
    2137             :                 }
    2138             : 
    2139        6453 :                 if (is_processed_packet(processed_packet_list, packet)) {
    2140           0 :                         DEBUG(7,("discarding duplicate packet from %s:%d\n",
    2141             :                                 inet_ntoa(packet->ip),packet->port));
    2142           0 :                         free_packet(packet);
    2143           0 :                         continue;
    2144             :                 }
    2145             : 
    2146        6453 :                 store_processed_packet(&processed_packet_list, packet);
    2147             : 
    2148        6453 :                 if (attrs[i].broadcast) {
    2149             :                         /* this is a broadcast socket */
    2150        6453 :                         packet->send_fd = attrs[i-1].fd;
    2151             :                 } else {
    2152             :                         /* this is already a unicast socket */
    2153           0 :                         packet->send_fd = attrs[i].fd;
    2154             :                 }
    2155             : 
    2156        6453 :                 queue_packet(packet);
    2157             :         }
    2158             : 
    2159       15039 :         free_processed_packet_list(&processed_packet_list);
    2160       15039 :         TALLOC_FREE(frame);
    2161       15039 :         return False;
    2162             : }
    2163             : 
    2164             : /****************************************************************************
    2165             :   Construct and send a netbios DGRAM.
    2166             : **************************************************************************/
    2167             : 
    2168         565 : bool send_mailslot(bool unique, const char *mailslot,char *buf, size_t len,
    2169             :                    const char *srcname, int src_type,
    2170             :                    const char *dstname, int dest_type,
    2171             :                    struct in_addr dest_ip,struct in_addr src_ip,
    2172             :                    int dest_port)
    2173             : {
    2174         565 :         bool loopback_this_packet = False;
    2175             :         struct packet_struct p;
    2176         565 :         struct dgram_packet *dgram = &p.packet.dgram;
    2177             :         char *ptr,*p2;
    2178             :         char tmp[4];
    2179             : 
    2180         565 :         memset((char *)&p,'\0',sizeof(p));
    2181             : 
    2182         565 :         if(ismyip_v4(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
    2183           2 :                 loopback_this_packet = True;
    2184             : 
    2185             :         /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
    2186             : 
    2187             :         /* DIRECT GROUP or UNIQUE datagram. */
    2188         565 :         dgram->header.msg_type = unique ? 0x10 : 0x11;
    2189         565 :         dgram->header.flags.node_type = M_NODE;
    2190         565 :         dgram->header.flags.first = True;
    2191         565 :         dgram->header.flags.more = False;
    2192         565 :         dgram->header.dgm_id = generate_name_trn_id();
    2193         565 :         dgram->header.source_ip = src_ip;
    2194         565 :         dgram->header.source_port = DGRAM_PORT;
    2195         565 :         dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
    2196         565 :         dgram->header.packet_offset = 0;
    2197             : 
    2198         565 :         make_nmb_name(&dgram->source_name,srcname,src_type);
    2199         565 :         make_nmb_name(&dgram->dest_name,dstname,dest_type);
    2200             : 
    2201         565 :         ptr = &dgram->data[0];
    2202             : 
    2203             :         /* Setup the smb part. */
    2204         565 :         ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
    2205         565 :         memcpy(tmp,ptr,4);
    2206             : 
    2207         565 :         if (smb_size + 17*2 + strlen(mailslot) + 1 + len > MAX_DGRAM_SIZE) {
    2208           0 :                 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
    2209           0 :                 return false;
    2210             :         }
    2211             : 
    2212         565 :         cli_set_message(ptr,17,strlen(mailslot) + 1 + len,True);
    2213         565 :         memcpy(ptr,tmp,4);
    2214             : 
    2215         565 :         SCVAL(ptr,smb_com,SMBtrans);
    2216         565 :         SSVAL(ptr,smb_vwv1,len);
    2217         565 :         SSVAL(ptr,smb_vwv11,len);
    2218         565 :         SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
    2219         565 :         SSVAL(ptr,smb_vwv13,3);
    2220         565 :         SSVAL(ptr,smb_vwv14,1);
    2221         565 :         SSVAL(ptr,smb_vwv15,1);
    2222         565 :         SSVAL(ptr,smb_vwv16,2);
    2223         565 :         p2 = smb_buf(ptr);
    2224         565 :         strlcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
    2225         565 :         p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2);
    2226             : 
    2227         565 :         if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
    2228           0 :                 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
    2229           0 :                 return False;
    2230             :         } else {
    2231         565 :                 if (len) {
    2232         565 :                         memcpy(p2,buf,len);
    2233             :                 }
    2234         565 :                 p2 += len;
    2235             :         }
    2236             : 
    2237         565 :         dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
    2238             : 
    2239         565 :         p.ip = dest_ip;
    2240         565 :         p.port = dest_port;
    2241         565 :         p.recv_fd = -1;
    2242         565 :         p.send_fd = find_subnet_mailslot_fd_for_address( src_ip );
    2243         565 :         p.timestamp = time(NULL);
    2244         565 :         p.packet_type = DGRAM_PACKET;
    2245             : 
    2246         565 :         DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
    2247             :                         nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
    2248         565 :         DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
    2249             : 
    2250         565 :         debug_browse_data(buf, len);
    2251             : 
    2252         565 :         if(loopback_this_packet) {
    2253           2 :                 struct packet_struct *lo_packet = NULL;
    2254           2 :                 DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
    2255           2 :                 if((lo_packet = copy_packet(&p)) == NULL)
    2256           0 :                         return False;
    2257           2 :                 queue_packet(lo_packet);
    2258           2 :                 return True;
    2259             :         } else {
    2260         563 :                 return(send_packet(&p));
    2261             :         }
    2262             : }

Generated by: LCOV version 1.13