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

Generated by: LCOV version 1.14