nmbd/nmbd_packets.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    NBT netbios routines and daemon - version 2
00004    Copyright (C) Andrew Tridgell 1994-1998
00005    Copyright (C) Luke Kenneth Casson Leighton 1994-1998
00006    Copyright (C) Jeremy Allison 1994-2003
00007    
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021    
00022 */
00023 
00024 #include "includes.h"
00025 
00026 extern int ClientNMB;
00027 extern int ClientDGRAM;
00028 extern int global_nmb_port;
00029 
00030 extern int num_response_packets;
00031 
00032 extern struct in_addr loopback_ip;
00033 
00034 static void queue_packet(struct packet_struct *packet);
00035 
00036 BOOL rescan_listen_set = False;
00037 
00038 
00039 /*******************************************************************
00040   The global packet linked-list. Incoming entries are 
00041   added to the end of this list. It is supposed to remain fairly 
00042   short so we won't bother with an end pointer.
00043 ******************************************************************/
00044 
00045 static struct packet_struct *packet_queue = NULL;
00046 
00047 /***************************************************************************
00048 Utility function to find the specific fd to send a packet out on.
00049 **************************************************************************/
00050 
00051 static int find_subnet_fd_for_address( struct in_addr local_ip )
00052 {
00053         struct subnet_record *subrec;
00054 
00055         for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
00056                 if(ip_equal(local_ip, subrec->myip))
00057                         return subrec->nmb_sock;
00058 
00059         return ClientNMB;
00060 }
00061 
00062 /***************************************************************************
00063 Utility function to find the specific fd to send a mailslot packet out on.
00064 **************************************************************************/
00065 
00066 static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
00067 {
00068         struct subnet_record *subrec;
00069 
00070         for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
00071                 if(ip_equal(local_ip, subrec->myip))
00072                         return subrec->dgram_sock;
00073 
00074         return ClientDGRAM;
00075 }
00076 
00077 /***************************************************************************
00078 Get/Set problematic nb_flags as network byte order 16 bit int.
00079 **************************************************************************/
00080 
00081 uint16 get_nb_flags(char *buf)
00082 {
00083         return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
00084 }
00085 
00086 void set_nb_flags(char *buf, uint16 nb_flags)
00087 {
00088         *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
00089         *buf = '\0';
00090 }
00091 
00092 /***************************************************************************
00093 Dumps out the browse packet data.
00094 **************************************************************************/
00095 
00096 static void debug_browse_data(char *outbuf, int len)
00097 {
00098         int i,j;
00099 
00100         DEBUG( 4, ( "debug_browse_data():\n" ) );
00101         for (i = 0; i < len; i+= 16) {
00102                 DEBUGADD( 4, ( "%3x char ", i ) );
00103 
00104                 for (j = 0; j < 16; j++) {
00105                         unsigned char x;
00106                         if (i+j >= len)
00107                                 break;
00108 
00109                         x = outbuf[i+j];
00110                         if (x < 32 || x > 127) 
00111                                 x = '.';
00112             
00113                         DEBUGADD( 4, ( "%c", x ) );
00114                 }
00115 
00116                 DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
00117 
00118                 for (j = 0; j < 16; j++) {
00119                         if (i+j >= len) 
00120                                 break;
00121                         DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
00122                 }
00123 
00124                 DEBUGADD( 4, ("\n") );
00125         }
00126 }
00127 
00128 /***************************************************************************
00129   Generates the unique transaction identifier
00130 **************************************************************************/
00131 
00132 static uint16 name_trn_id=0;
00133 
00134 static uint16 generate_name_trn_id(void)
00135 {
00136         if (!name_trn_id) {
00137                 name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
00138         }
00139         name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
00140         return name_trn_id;
00141 }
00142 
00143 /***************************************************************************
00144  Either loops back or sends out a completed NetBIOS packet.
00145 **************************************************************************/
00146 
00147 static BOOL send_netbios_packet(struct packet_struct *p)
00148 {
00149         BOOL loopback_this_packet = False;
00150 
00151         /* Check if we are sending to or from ourselves as a WINS server. */
00152         if(ismyip(p->ip) && (p->port == global_nmb_port))
00153                 loopback_this_packet = True;
00154 
00155         if(loopback_this_packet) {
00156                 struct packet_struct *lo_packet = NULL;
00157                 DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
00158                 if((lo_packet = copy_packet(p)) == NULL)
00159                         return False;
00160                 queue_packet(lo_packet);
00161         } else if (!send_packet(p)) {
00162                 DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
00163                         inet_ntoa(p->ip),p->port));
00164                 return False;
00165         }
00166   
00167         return True;
00168 } 
00169 
00170 /***************************************************************************
00171  Sets up the common elements of an outgoing NetBIOS packet.
00172 
00173  Note: do not attempt to rationalise whether rec_des should be set or not
00174  in a particular situation. Just follow rfc_1002 or look at examples from WinXX.
00175  It does NOT follow the rule that requests to the wins server always have
00176  rec_des true. See for example name releases and refreshes
00177 **************************************************************************/
00178 
00179 static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
00180                                                             BOOL bcast, BOOL rec_des,
00181                                                             struct in_addr to_ip)
00182 {
00183         struct packet_struct *packet = NULL;
00184         struct nmb_packet *nmb = NULL;
00185 
00186         /* Allocate the packet_struct we will return. */
00187         if((packet = SMB_MALLOC_P(struct packet_struct)) == NULL) {
00188                 DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
00189                 return NULL;
00190         }
00191     
00192         memset((char *)packet,'\0',sizeof(*packet));
00193 
00194         nmb = &packet->packet.nmb;
00195 
00196         nmb->header.name_trn_id = generate_name_trn_id();
00197         nmb->header.response = False;
00198         nmb->header.nm_flags.recursion_desired = rec_des;
00199         nmb->header.nm_flags.recursion_available = False;
00200         nmb->header.nm_flags.trunc = False;
00201         nmb->header.nm_flags.authoritative = False;
00202         nmb->header.nm_flags.bcast = bcast;
00203   
00204         nmb->header.rcode = 0;
00205         nmb->header.qdcount = 1;
00206         nmb->header.ancount = 0;
00207         nmb->header.nscount = 0;
00208 
00209         nmb->question.question_name = *nmbname;
00210         nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
00211         nmb->question.question_class = QUESTION_CLASS_IN;
00212 
00213         packet->ip = to_ip;
00214         packet->port = NMB_PORT;
00215         packet->fd = ClientNMB;
00216         packet->timestamp = time(NULL);
00217         packet->packet_type = NMB_PACKET;
00218         packet->locked = False;
00219   
00220         return packet; /* Caller must free. */
00221 }
00222 
00223 /***************************************************************************
00224  Sets up the common elements of register, refresh or release packet.
00225 **************************************************************************/
00226 
00227 static BOOL create_and_init_additional_record(struct packet_struct *packet,
00228                                                      uint16 nb_flags,
00229                                                      struct in_addr *register_ip)
00230 {
00231         struct nmb_packet *nmb = &packet->packet.nmb;
00232 
00233         if((nmb->additional = SMB_MALLOC_P(struct res_rec)) == NULL) {
00234                 DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
00235                 return False;
00236         }
00237 
00238         memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
00239 
00240         nmb->additional->rr_name  = nmb->question.question_name;
00241         nmb->additional->rr_type  = RR_TYPE_NB;
00242         nmb->additional->rr_class = RR_CLASS_IN;
00243         
00244         /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
00245         if (nmb->header.nm_flags.bcast)
00246                 nmb->additional->ttl = PERMANENT_TTL;
00247         else
00248                 nmb->additional->ttl = lp_max_ttl();
00249         
00250         nmb->additional->rdlength = 6;
00251         
00252         set_nb_flags(nmb->additional->rdata,nb_flags);
00253         
00254         /* Set the address for the name we are registering. */
00255         putip(&nmb->additional->rdata[2], register_ip);
00256         
00257         /* 
00258            it turns out that Jeremys code was correct, we are supposed
00259            to send registrations from the IP we are registering. The
00260            trick is what to do on timeouts! When we send on a
00261            non-routable IP then the reply will timeout, and we should
00262            treat this as success, not failure. That means we go into
00263            our standard refresh cycle for that name which copes nicely
00264            with disconnected networks.
00265         */
00266         packet->fd = find_subnet_fd_for_address(*register_ip);
00267 
00268         return True;
00269 }
00270 
00271 /***************************************************************************
00272  Sends out a name query.
00273 **************************************************************************/
00274 
00275 static BOOL initiate_name_query_packet( struct packet_struct *packet)
00276 {
00277         struct nmb_packet *nmb = NULL;
00278 
00279         nmb = &packet->packet.nmb;
00280 
00281         nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
00282         nmb->header.arcount = 0;
00283 
00284         nmb->header.nm_flags.recursion_desired = True;
00285 
00286         DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
00287                 nmb_namestr(&nmb->question.question_name), 
00288                 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
00289 
00290         return send_netbios_packet( packet );
00291 }
00292 
00293 /***************************************************************************
00294  Sends out a name query - from a WINS server. 
00295 **************************************************************************/
00296 
00297 static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
00298 {   
00299         struct nmb_packet *nmb = NULL;
00300   
00301         nmb = &packet->packet.nmb;
00302 
00303         nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
00304         nmb->header.arcount = 0;
00305     
00306         nmb->header.nm_flags.recursion_desired = False;
00307   
00308         DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
00309                 nmb_namestr(&nmb->question.question_name),
00310                 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
00311     
00312         return send_netbios_packet( packet );
00313 } 
00314 
00315 /***************************************************************************
00316  Sends out a name register.
00317 **************************************************************************/
00318 
00319 static BOOL initiate_name_register_packet( struct packet_struct *packet,
00320                                     uint16 nb_flags, struct in_addr *register_ip)
00321 {
00322         struct nmb_packet *nmb = &packet->packet.nmb;
00323 
00324         nmb->header.opcode = NMB_NAME_REG_OPCODE;
00325         nmb->header.arcount = 1;
00326 
00327         nmb->header.nm_flags.recursion_desired = True;
00328 
00329         if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
00330                 return False;
00331 
00332         DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
00333                 nmb_namestr(&nmb->additional->rr_name),
00334                 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
00335 
00336         return send_netbios_packet( packet );
00337 }
00338 
00339 /***************************************************************************
00340  Sends out a multihomed name register.
00341 **************************************************************************/
00342 
00343 static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packet,
00344                                                      uint16 nb_flags, struct in_addr *register_ip)
00345 {
00346         struct nmb_packet *nmb = &packet->packet.nmb;
00347         fstring second_ip_buf;
00348 
00349         fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
00350 
00351         nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
00352         nmb->header.arcount = 1;
00353 
00354         nmb->header.nm_flags.recursion_desired = True;
00355         
00356         if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
00357                 return False;
00358         
00359         DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
00360 for name %s IP %s (bcast=%s) to IP %s\n",
00361                  nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
00362                  BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
00363 
00364         return send_netbios_packet( packet );
00365 } 
00366 
00367 /***************************************************************************
00368  Sends out a name refresh.
00369 **************************************************************************/
00370 
00371 static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
00372                                    uint16 nb_flags, struct in_addr *refresh_ip)
00373 {
00374         struct nmb_packet *nmb = &packet->packet.nmb;
00375 
00376         nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
00377         nmb->header.arcount = 1;
00378 
00379         nmb->header.nm_flags.recursion_desired = False;
00380 
00381         if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
00382                 return False;
00383 
00384         DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
00385                 nmb_namestr(&nmb->additional->rr_name),
00386                 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
00387 
00388         return send_netbios_packet( packet );
00389 } 
00390 
00391 /***************************************************************************
00392  Sends out a name release.
00393 **************************************************************************/
00394 
00395 static BOOL initiate_name_release_packet( struct packet_struct *packet,
00396                                    uint16 nb_flags, struct in_addr *release_ip)
00397 {
00398         struct nmb_packet *nmb = &packet->packet.nmb;
00399 
00400         nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
00401         nmb->header.arcount = 1;
00402 
00403         nmb->header.nm_flags.recursion_desired = False;
00404 
00405         if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
00406                 return False;
00407 
00408         DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
00409                 nmb_namestr(&nmb->additional->rr_name),
00410                 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
00411 
00412         return send_netbios_packet( packet );
00413 } 
00414 
00415 /***************************************************************************
00416  Sends out a node status.
00417 **************************************************************************/
00418 
00419 static BOOL initiate_node_status_packet( struct packet_struct *packet )
00420 {
00421         struct nmb_packet *nmb = &packet->packet.nmb;
00422 
00423         nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
00424         nmb->header.arcount = 0;
00425 
00426         nmb->header.nm_flags.recursion_desired = False;
00427 
00428         nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
00429 
00430         DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
00431                 nmb_namestr(&nmb->question.question_name),
00432                 inet_ntoa(packet->ip)));
00433 
00434         return send_netbios_packet( packet );
00435 }
00436 
00437 /****************************************************************************
00438   Simplification functions for queuing standard packets.
00439   These should be the only publicly callable functions for sending
00440   out packets.
00441 ****************************************************************************/
00442 
00443 /****************************************************************************
00444  Assertion - we should never be sending nmbd packets on the remote
00445  broadcast subnet.
00446 ****************************************************************************/
00447 
00448 static BOOL assert_check_subnet(struct subnet_record *subrec)
00449 {
00450         if( subrec == remote_broadcast_subnet) {
00451                 DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
00452 This is a bug.\n"));
00453                 return True;
00454         }
00455         return False;
00456 }
00457 
00458 /****************************************************************************
00459  Queue a register name packet to the broadcast address of a subnet.
00460 ****************************************************************************/
00461 
00462 struct response_record *queue_register_name( struct subnet_record *subrec,
00463                           response_function resp_fn,
00464                           timeout_response_function timeout_fn,
00465                           register_name_success_function success_fn,
00466                           register_name_fail_function fail_fn,
00467                           struct userdata_struct *userdata,
00468                           struct nmb_name *nmbname,
00469                           uint16 nb_flags)
00470 {
00471         struct packet_struct *p;
00472         struct response_record *rrec;
00473 
00474         if(assert_check_subnet(subrec))
00475                 return NULL;
00476 
00477         /* note that all name registration requests have RD set (rfc1002 - section 4.2.2 */
00478         if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
00479                                 subrec->bcast_ip)) == NULL)
00480                 return NULL;
00481 
00482         if(initiate_name_register_packet( p, nb_flags, iface_ip(subrec->bcast_ip)) == False) {
00483                 p->locked = False;
00484                 free_packet(p);
00485                 return NULL;
00486         }
00487 
00488         if((rrec = make_response_record(subrec,        /* subnet record. */
00489                                 p,                     /* packet we sent. */
00490                                 resp_fn,               /* function to call on response. */
00491                                 timeout_fn,            /* function to call on timeout. */
00492                                 (success_function)success_fn,            /* function to call on operation success. */
00493                                 (fail_function)fail_fn,               /* function to call on operation fail. */
00494                                 userdata)) == NULL)  {
00495                 p->locked = False;
00496                 free_packet(p);
00497                 return NULL;
00498         }
00499 
00500         return rrec;
00501 }
00502 
00503 /****************************************************************************
00504  Queue a refresh name packet to the broadcast address of a subnet.
00505 ****************************************************************************/
00506 
00507 void queue_wins_refresh(struct nmb_name *nmbname,
00508                         response_function resp_fn,
00509                         timeout_response_function timeout_fn,
00510                         uint16 nb_flags,
00511                         struct in_addr refresh_ip,
00512                         const char *tag)
00513 {
00514         struct packet_struct *p;
00515         struct response_record *rrec;
00516         struct in_addr wins_ip;
00517         struct userdata_struct *userdata;
00518         fstring ip_str;
00519 
00520         wins_ip = wins_srv_ip_tag(tag, refresh_ip);
00521 
00522         if ((p = create_and_init_netbios_packet(nmbname, False, False, wins_ip)) == NULL) {
00523                 return;
00524         }
00525 
00526         if (!initiate_name_refresh_packet(p, nb_flags, &refresh_ip)) {
00527                 p->locked = False;
00528                 free_packet(p);
00529                 return;
00530         }
00531 
00532         fstrcpy(ip_str, inet_ntoa(refresh_ip));
00533 
00534         DEBUG(6,("Refreshing name %s IP %s with WINS server %s using tag '%s'\n",
00535                  nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
00536 
00537         userdata = (struct userdata_struct *)SMB_MALLOC(sizeof(*userdata) + strlen(tag) + 1);
00538         if (!userdata) {
00539                 p->locked = False;
00540                 free_packet(p);
00541                 DEBUG(0,("Failed to allocate userdata structure!\n"));
00542                 return;
00543         }
00544         ZERO_STRUCTP(userdata);
00545         userdata->userdata_len = strlen(tag) + 1;
00546         strlcpy(userdata->data, tag, userdata->userdata_len);   
00547 
00548         if ((rrec = make_response_record(unicast_subnet,
00549                                          p,
00550                                          resp_fn, timeout_fn,
00551                                          NULL,
00552                                          NULL,
00553                                          userdata)) == NULL) {
00554                 p->locked = False;
00555                 free_packet(p);
00556                 return;
00557         }
00558 
00559         free(userdata);
00560 
00561         /* we don't want to repeat refresh packets */
00562         rrec->repeat_count = 0;
00563 }
00564 
00565 
00566 /****************************************************************************
00567  Queue a multihomed register name packet to a given WINS server IP
00568 ****************************************************************************/
00569 
00570 struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
00571                                                         response_function resp_fn,
00572                                                         timeout_response_function timeout_fn,
00573                                                         register_name_success_function success_fn,
00574                                                         register_name_fail_function fail_fn,
00575                                                         struct userdata_struct *userdata,
00576                                                         struct nmb_name *nmbname,
00577                                                         uint16 nb_flags,
00578                                                         struct in_addr register_ip,
00579                                                         struct in_addr wins_ip)
00580 {
00581         struct packet_struct *p;
00582         struct response_record *rrec;
00583         BOOL ret;
00584         
00585         /* Sanity check. */
00586         if(subrec != unicast_subnet) {
00587                 DEBUG(0,("queue_register_multihomed_name: should only be done on \
00588 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
00589                 return NULL;
00590         }
00591 
00592         if(assert_check_subnet(subrec))
00593                 return NULL;
00594      
00595         if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
00596                 return NULL;
00597 
00598         if (nb_flags & NB_GROUP)
00599                 ret = initiate_name_register_packet( p, nb_flags, &register_ip);
00600         else
00601                 ret = initiate_multihomed_name_register_packet(p, nb_flags, &register_ip);
00602 
00603         if (ret == False) {  
00604                 p->locked = False;
00605                 free_packet(p);
00606                 return NULL;
00607         }  
00608   
00609         if ((rrec = make_response_record(subrec,    /* subnet record. */
00610                                          p,                     /* packet we sent. */
00611                                          resp_fn,               /* function to call on response. */
00612                                          timeout_fn,            /* function to call on timeout. */
00613                                          (success_function)success_fn, /* function to call on operation success. */
00614                                          (fail_function)fail_fn,       /* function to call on operation fail. */
00615                                          userdata)) == NULL) {  
00616                 p->locked = False;
00617                 free_packet(p);
00618                 return NULL;
00619         }  
00620         
00621         return rrec;
00622 }
00623 
00624 /****************************************************************************
00625  Queue a release name packet to the broadcast address of a subnet.
00626 ****************************************************************************/
00627 
00628 struct response_record *queue_release_name( struct subnet_record *subrec,
00629                                             response_function resp_fn,
00630                                             timeout_response_function timeout_fn,
00631                                             release_name_success_function success_fn,
00632                                             release_name_fail_function fail_fn,
00633                                             struct userdata_struct *userdata,
00634                                             struct nmb_name *nmbname,
00635                                             uint16 nb_flags,
00636                                             struct in_addr release_ip,
00637                                             struct in_addr dest_ip)
00638 {
00639         struct packet_struct *p;
00640         struct response_record *rrec;
00641 
00642         if(assert_check_subnet(subrec))
00643                 return NULL;
00644 
00645         if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False, dest_ip)) == NULL)
00646                 return NULL;
00647 
00648         if(initiate_name_release_packet( p, nb_flags, &release_ip) == False) {
00649                 p->locked = False;
00650                 free_packet(p);
00651                 return NULL;
00652         }
00653 
00654         if((rrec = make_response_record(subrec,                /* subnet record. */
00655                                         p,                     /* packet we sent. */
00656                                         resp_fn,               /* function to call on response. */
00657                                         timeout_fn,            /* function to call on timeout. */
00658                                         (success_function)success_fn,            /* function to call on operation success. */
00659                                         (fail_function)fail_fn,               /* function to call on operation fail. */
00660                                         userdata)) == NULL)  {
00661                 p->locked = False;
00662                 free_packet(p);
00663                 return NULL;
00664         }
00665 
00666         /*
00667          * For a broadcast release packet, only send once.
00668          * This will cause us to remove the name asap. JRA.
00669          */
00670 
00671         if (subrec != unicast_subnet) {
00672                 rrec->repeat_count = 0;
00673                 rrec->repeat_time = 0;
00674         }
00675 
00676         return rrec;
00677 }
00678 
00679 /****************************************************************************
00680  Queue a query name packet to the broadcast address of a subnet.
00681 ****************************************************************************/
00682  
00683 struct response_record *queue_query_name( struct subnet_record *subrec,
00684                           response_function resp_fn,
00685                           timeout_response_function timeout_fn,
00686                           query_name_success_function success_fn,
00687                           query_name_fail_function fail_fn,
00688                           struct userdata_struct *userdata,
00689                           struct nmb_name *nmbname)
00690 {
00691         struct packet_struct *p;
00692         struct response_record *rrec;
00693         struct in_addr to_ip;
00694 
00695         if(assert_check_subnet(subrec))
00696                 return NULL;
00697 
00698         to_ip = subrec->bcast_ip;
00699   
00700         /* queries to the WINS server turn up here as queries to IP 0.0.0.0 
00701                         These need to be handled a bit differently */
00702         if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
00703                 /* What we really need to do is loop over each of our wins
00704                  * servers and wins server tags here, but that just doesn't
00705                  * fit our architecture at the moment (userdata may already
00706                  * be used when we get here). For now we just query the first
00707                  * active wins server on the first tag.
00708                  */ 
00709                 char **tags = wins_srv_tags();
00710                 if (!tags) {
00711                         return NULL;
00712                 }
00713                 to_ip = wins_srv_ip_tag(tags[0], to_ip);
00714                 wins_srv_tags_free(tags);
00715         }
00716 
00717         if(( p = create_and_init_netbios_packet(nmbname, 
00718                                         (subrec != unicast_subnet), 
00719                                         (subrec == unicast_subnet), 
00720                                         to_ip)) == NULL)
00721                 return NULL;
00722 
00723         if(lp_bind_interfaces_only()) {
00724                 int i;
00725 
00726                 DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
00727                 for(i = 0; i < iface_count(); i++) {
00728                         struct in_addr *ifip = iface_n_ip(i);
00729 
00730                         if(ifip == NULL) {
00731                                 DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
00732                                 continue;
00733                         }
00734 
00735                         if (ip_equal(*ifip,loopback_ip)) {
00736                                 DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
00737                                 continue;
00738                         }
00739 
00740                         DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
00741                                 p->fd = find_subnet_fd_for_address( *ifip );
00742                                 break;
00743                 }
00744         }
00745 
00746         if(initiate_name_query_packet( p ) == False) {
00747                 p->locked = False;
00748                 free_packet(p);
00749                 return NULL;
00750         }
00751 
00752         if((rrec = make_response_record(subrec,                /* subnet record. */
00753                                         p,                     /* packet we sent. */
00754                                         resp_fn,               /* function to call on response. */
00755                                         timeout_fn,            /* function to call on timeout. */
00756                                         (success_function)success_fn,            /* function to call on operation success. */
00757                                         (fail_function)fail_fn,               /* function to call on operation fail. */
00758                                         userdata)) == NULL) {
00759                 p->locked = False;
00760                 free_packet(p);
00761                 return NULL;
00762         }
00763 
00764         return rrec;
00765 }
00766 
00767 /****************************************************************************
00768  Queue a query name packet to a given address from the WINS subnet.
00769 ****************************************************************************/
00770  
00771 struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
00772                           response_function resp_fn,
00773                           timeout_response_function timeout_fn,
00774                           query_name_success_function success_fn,
00775                           query_name_fail_function fail_fn,
00776                           struct userdata_struct *userdata,
00777                           struct nmb_name *nmbname)
00778 {
00779         struct packet_struct *p;
00780         struct response_record *rrec;
00781 
00782         if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
00783                 return NULL;
00784 
00785         if(initiate_name_query_packet_from_wins_server( p ) == False) {
00786                 p->locked = False;
00787                 free_packet(p);
00788                 return NULL;
00789         }
00790 
00791         if((rrec = make_response_record(wins_server_subnet,            /* subnet record. */
00792                                                 p,                     /* packet we sent. */
00793                                                 resp_fn,               /* function to call on response. */
00794                                                 timeout_fn,            /* function to call on timeout. */
00795                                                 (success_function)success_fn,            /* function to call on operation success. */
00796                                                 (fail_function)fail_fn,               /* function to call on operation fail. */
00797                                                 userdata)) == NULL) {
00798                 p->locked = False;
00799                 free_packet(p);
00800                 return NULL;
00801         }
00802 
00803         return rrec;
00804 }
00805 
00806 /****************************************************************************
00807  Queue a node status packet to a given name and address.
00808 ****************************************************************************/
00809  
00810 struct response_record *queue_node_status( struct subnet_record *subrec,
00811                           response_function resp_fn,
00812                           timeout_response_function timeout_fn,
00813                           node_status_success_function success_fn,
00814                           node_status_fail_function fail_fn,
00815                           struct userdata_struct *userdata,
00816                           struct nmb_name *nmbname,
00817                           struct in_addr send_ip)
00818 {
00819         struct packet_struct *p;
00820         struct response_record *rrec;
00821 
00822         /* Sanity check. */
00823         if(subrec != unicast_subnet) {
00824                 DEBUG(0,("queue_register_multihomed_name: should only be done on \
00825 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
00826                 return NULL;
00827         }
00828 
00829         if(assert_check_subnet(subrec))
00830                 return NULL;
00831 
00832         if(( p = create_and_init_netbios_packet(nmbname, False, False, send_ip)) == NULL)
00833                 return NULL;
00834 
00835         if(initiate_node_status_packet(p) == False) {
00836                 p->locked = False;
00837                 free_packet(p);
00838                 return NULL;
00839         } 
00840 
00841         if((rrec = make_response_record(subrec,           /* subnet record. */
00842                                         p,                     /* packet we sent. */
00843                                         resp_fn,               /* function to call on response. */
00844                                         timeout_fn,            /* function to call on timeout. */
00845                                         (success_function)success_fn,            /* function to call on operation success. */
00846                                         (fail_function)fail_fn,               /* function to call on operation fail. */
00847                                         userdata)) == NULL) {
00848                 p->locked = False;
00849                 free_packet(p);
00850                 return NULL;
00851         }
00852 
00853         return rrec;
00854 }
00855 
00856 /****************************************************************************
00857   Reply to a netbios name packet.  see rfc1002.txt
00858 ****************************************************************************/
00859 
00860 void reply_netbios_packet(struct packet_struct *orig_packet,
00861                           int rcode, enum netbios_reply_type_code rcv_code, int opcode,
00862                           int ttl, char *data,int len)
00863 {
00864         struct packet_struct packet;
00865         struct nmb_packet *nmb = NULL;
00866         struct res_rec answers;
00867         struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
00868         BOOL loopback_this_packet = False;
00869         int rr_type = RR_TYPE_NB;
00870         const char *packet_type = "unknown";
00871   
00872         /* Check if we are sending to or from ourselves. */
00873         if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
00874                 loopback_this_packet = True;
00875   
00876         nmb = &packet.packet.nmb;
00877 
00878         /* Do a partial copy of the packet. We clear the locked flag and
00879                         the resource record pointers. */
00880         packet = *orig_packet;   /* Full structure copy. */
00881         packet.locked = False;
00882         nmb->answers = NULL;
00883         nmb->nsrecs = NULL;
00884         nmb->additional = NULL;
00885 
00886         switch (rcv_code) {
00887                 case NMB_STATUS:
00888                         packet_type = "nmb_status";
00889                         nmb->header.nm_flags.recursion_desired = False;
00890                         nmb->header.nm_flags.recursion_available = False;
00891                         rr_type = RR_TYPE_NBSTAT;
00892                         break;
00893                 case NMB_QUERY:
00894                         packet_type = "nmb_query";
00895                         nmb->header.nm_flags.recursion_desired = True;
00896                         nmb->header.nm_flags.recursion_available = True;
00897                         if (rcode) {
00898                                 rr_type = RR_TYPE_NULL;
00899                         }
00900                         break;
00901                 case NMB_REG:
00902                 case NMB_REG_REFRESH:
00903                         packet_type = "nmb_reg";
00904                         nmb->header.nm_flags.recursion_desired = True;
00905                         nmb->header.nm_flags.recursion_available = True;
00906                         break;
00907                 case NMB_REL:
00908                         packet_type = "nmb_rel";
00909                         nmb->header.nm_flags.recursion_desired = False;
00910                         nmb->header.nm_flags.recursion_available = False;
00911                         break;
00912                 case NMB_WAIT_ACK:
00913                         packet_type = "nmb_wack";
00914                         nmb->header.nm_flags.recursion_desired = False;
00915                         nmb->header.nm_flags.recursion_available = False;
00916                         rr_type = RR_TYPE_NULL;
00917                         break;
00918                 case WINS_REG:
00919                         packet_type = "wins_reg";
00920                         nmb->header.nm_flags.recursion_desired = True;
00921                         nmb->header.nm_flags.recursion_available = True;
00922                         break;
00923                 case WINS_QUERY:
00924                         packet_type = "wins_query";
00925                         nmb->header.nm_flags.recursion_desired = True;
00926                         nmb->header.nm_flags.recursion_available = True;
00927                         if (rcode) {
00928                                 rr_type = RR_TYPE_NULL;
00929                         }
00930                         break;
00931                 default:
00932                         DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
00933                                 packet_type, nmb_namestr(&orig_nmb->question.question_name),
00934                                 inet_ntoa(packet.ip)));
00935                         return;
00936         }
00937 
00938         DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
00939 for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
00940                         inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
00941 
00942         nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
00943         nmb->header.opcode = opcode;
00944         nmb->header.response = True;
00945         nmb->header.nm_flags.bcast = False;
00946         nmb->header.nm_flags.trunc = False;
00947         nmb->header.nm_flags.authoritative = True;
00948   
00949         nmb->header.rcode = rcode;
00950         nmb->header.qdcount = 0;
00951         nmb->header.ancount = 1;
00952         nmb->header.nscount = 0;
00953         nmb->header.arcount = 0;
00954   
00955         memset((char*)&nmb->question,'\0',sizeof(nmb->question));
00956   
00957         nmb->answers = &answers;
00958         memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
00959   
00960         nmb->answers->rr_name  = orig_nmb->question.question_name;
00961         nmb->answers->rr_type  = rr_type;
00962         nmb->answers->rr_class = RR_CLASS_IN;
00963         nmb->answers->ttl      = ttl;
00964   
00965         if (data && len) {
00966                 if (len < 0 || len > sizeof(nmb->answers->rdata)) {
00967                         DEBUG(5,("reply_netbios_packet: "
00968                                 "invalid packet len (%d)\n",
00969                                 len ));
00970                         return;
00971                 }
00972                 nmb->answers->rdlength = len;
00973                 memcpy(nmb->answers->rdata, data, len);
00974         }
00975   
00976         packet.packet_type = NMB_PACKET;
00977         /* Ensure we send out on the same fd that the original
00978                 packet came in on to give the correct source IP address. */
00979         packet.fd = orig_packet->fd;
00980         packet.timestamp = time(NULL);
00981 
00982         debug_nmb_packet(&packet);
00983   
00984         if(loopback_this_packet) {
00985                 struct packet_struct *lo_packet;
00986                 DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
00987                 if((lo_packet = copy_packet(&packet)) == NULL)
00988                         return;
00989                 queue_packet(lo_packet);
00990         } else if (!send_packet(&packet)) {
00991                 DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
00992                         inet_ntoa(packet.ip),packet.port));
00993         }
00994 }
00995 
00996 /*******************************************************************
00997   Queue a packet into a packet queue
00998 ******************************************************************/
00999 
01000 static void queue_packet(struct packet_struct *packet)
01001 {
01002         struct packet_struct *p;
01003 
01004         if (!packet_queue) {
01005                 packet->prev = NULL;
01006                 packet->next = NULL;
01007                 packet_queue = packet;
01008                 return;
01009         }
01010   
01011         /* find the bottom */
01012         for (p=packet_queue;p->next;p=p->next) 
01013                 ;
01014 
01015         p->next = packet;
01016         packet->next = NULL;
01017         packet->prev = p;
01018 }
01019 
01020 /****************************************************************************
01021  Try and find a matching subnet record for a datagram port 138 packet.
01022 ****************************************************************************/
01023 
01024 static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
01025 {
01026         struct subnet_record *subrec;
01027 
01028         /* Go through all the broadcast subnets and see if the mask matches. */
01029         for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
01030                 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
01031                         return subrec;
01032         }
01033 
01034         /* If the subnet record is the remote announce broadcast subnet,
01035                 hack it here to be the first subnet. This is really gross and
01036                 is needed due to people turning on port 137/138 broadcast
01037                 forwarding on their routers. May fire and brimstone rain
01038                 down upon them...
01039         */
01040 
01041         return FIRST_SUBNET;
01042 }
01043 
01044 /****************************************************************************
01045 Dispatch a browse frame from port 138 to the correct processing function.
01046 ****************************************************************************/
01047 
01048 static void process_browse_packet(struct packet_struct *p, char *buf,int len)
01049 {
01050         struct dgram_packet *dgram = &p->packet.dgram;
01051         int command = CVAL(buf,0);
01052         struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
01053         char scope[64];
01054         unstring src_name;
01055 
01056         /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
01057         pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
01058         if (!strequal(scope, global_scope())) {
01059                 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
01060 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
01061                 return;
01062         }
01063 
01064         pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
01065         if (is_myname(src_name)) {
01066                 DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
01067 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
01068                 return;
01069         }
01070 
01071         switch (command) {
01072                 case ANN_HostAnnouncement:
01073                         debug_browse_data(buf, len);
01074                         process_host_announce(subrec, p, buf+1);
01075                         break;
01076                 case ANN_DomainAnnouncement:
01077                         debug_browse_data(buf, len);
01078                         process_workgroup_announce(subrec, p, buf+1);
01079                         break;
01080                 case ANN_LocalMasterAnnouncement:
01081                         debug_browse_data(buf, len);
01082                         process_local_master_announce(subrec, p, buf+1);
01083                         break;
01084                 case ANN_AnnouncementRequest:
01085                         debug_browse_data(buf, len);
01086                         process_announce_request(subrec, p, buf+1);
01087                         break;
01088                 case ANN_Election:
01089                         debug_browse_data(buf, len);
01090                         process_election(subrec, p, buf+1);
01091                         break;
01092                 case ANN_GetBackupListReq:
01093                         debug_browse_data(buf, len);
01094                         process_get_backup_list_request(subrec, p, buf+1);
01095                         break;
01096                 case ANN_GetBackupListResp:
01097                         debug_browse_data(buf, len);
01098                         /* We never send ANN_GetBackupListReq so we should never get these. */
01099                         DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
01100 packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
01101                         break;
01102                 case ANN_ResetBrowserState:
01103                         debug_browse_data(buf, len);
01104                         process_reset_browser(subrec, p, buf+1);
01105                         break;
01106                 case ANN_MasterAnnouncement:
01107                         /* Master browser datagrams must be processed on the unicast subnet. */
01108                         subrec = unicast_subnet;
01109 
01110                         debug_browse_data(buf, len);
01111                         process_master_browser_announce(subrec, p, buf+1);
01112                         break;
01113                 case ANN_BecomeBackup:
01114                         /* 
01115                          * We don't currently implement this. Log it just in case.
01116                          */
01117                         debug_browse_data(buf, len);
01118                         DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
01119 command ANN_BecomeBackup from %s IP %s to %s\n", subrec->subnet_name, nmb_namestr(&dgram->source_name),
01120                                         inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
01121                         break;
01122                 default:
01123                         debug_browse_data(buf, len);
01124                         DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
01125 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
01126                                 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
01127                         break;
01128         } 
01129 }
01130 
01131 /****************************************************************************
01132  Dispatch a LanMan browse frame from port 138 to the correct processing function.
01133 ****************************************************************************/
01134 
01135 static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
01136 {
01137         struct dgram_packet *dgram = &p->packet.dgram;
01138         int command = SVAL(buf,0);
01139         struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
01140         char scope[64];
01141         unstring src_name;
01142 
01143         /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
01144 
01145         pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
01146         if (!strequal(scope, global_scope())) {
01147                 DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
01148 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
01149                 return;
01150         }
01151 
01152         pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
01153         if (is_myname(src_name)) {
01154                 DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
01155 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
01156                 return;
01157         }
01158 
01159         switch (command) {
01160                 case ANN_HostAnnouncement:
01161                         debug_browse_data(buf, len);
01162                         process_lm_host_announce(subrec, p, buf+1, len > 1 ? len-1 : 0);
01163                         break;
01164                 case ANN_AnnouncementRequest:
01165                         process_lm_announce_request(subrec, p, buf+1, len > 1 ? len-1 : 0);
01166                         break;
01167                 default:
01168                         DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
01169 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
01170                                 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
01171                         break;
01172         }
01173 }
01174 
01175 /****************************************************************************
01176   Determine if a packet is for us on port 138. Note that to have any chance of
01177   being efficient we need to drop as many packets as possible at this
01178   stage as subsequent processing is expensive. 
01179 ****************************************************************************/
01180 
01181 static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
01182 {
01183         struct subnet_record *subrec = NULL;
01184 
01185         for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
01186                 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
01187                         break;
01188         }
01189 
01190         if(subrec == NULL)
01191                 subrec = unicast_subnet;
01192 
01193         return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
01194 }
01195 
01196 /****************************************************************************
01197   Process udp 138 datagrams
01198 ****************************************************************************/
01199 
01200 static void process_dgram(struct packet_struct *p)
01201 {
01202         char *buf;
01203         char *buf2;
01204         int len;
01205         struct dgram_packet *dgram = &p->packet.dgram;
01206 
01207         /* If we aren't listening to the destination name then ignore the packet */
01208         if (!listening(p,&dgram->dest_name)) {
01209                         unexpected_packet(p);
01210                         DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
01211                                 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
01212                         return;
01213         }
01214 
01215         if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
01216                 unexpected_packet(p);
01217                 /* Don't process error packets etc yet */
01218                 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
01219 an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
01220                 return;
01221         }
01222 
01223         /* Ensure we have a large enough packet before looking inside. */
01224         if (dgram->datasize < (smb_vwv12 - 2)) {
01225                 /* That's the offset minus the 4 byte length + 2 bytes of offset. */
01226                 DEBUG(0,("process_dgram: ignoring too short dgram packet (%u) sent to name %s from IP %s\n",
01227                         (unsigned int)dgram->datasize,
01228                         nmb_namestr(&dgram->dest_name),
01229                         inet_ntoa(p->ip) ));
01230                 return;
01231         }
01232 
01233         buf = &dgram->data[0];
01234         buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */
01235 
01236         if (CVAL(buf,smb_com) != SMBtrans)
01237                 return;
01238 
01239         len = SVAL(buf,smb_vwv11);
01240         buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
01241 
01242         if (len <= 0 || len > dgram->datasize) {
01243                 DEBUG(0,("process_dgram: ignoring malformed1 (datasize = %d, len = %d) datagram \
01244 packet sent to name %s from IP %s\n",
01245                         dgram->datasize,
01246                         len,
01247                         nmb_namestr(&dgram->dest_name),
01248                         inet_ntoa(p->ip) ));
01249                 return;
01250         }
01251 
01252         if (buf2 < dgram->data || (buf2 >= dgram->data + dgram->datasize)) {
01253                 DEBUG(0,("process_dgram: ignoring malformed2 (datasize = %d, len=%d, off=%d) datagram \
01254 packet sent to name %s from IP %s\n",
01255                         dgram->datasize,
01256                         len,
01257                         (int)PTR_DIFF(buf2, dgram->data),
01258                         nmb_namestr(&dgram->dest_name),
01259                         inet_ntoa(p->ip) ));
01260                 return;
01261         }
01262 
01263         if ((buf2 + len < dgram->data) || (buf2 + len > dgram->data + dgram->datasize)) {
01264                 DEBUG(0,("process_dgram: ignoring malformed3 (datasize = %d, len=%d, off=%d) datagram \
01265 packet sent to name %s from IP %s\n",
01266                         dgram->datasize,
01267                         len,
01268                         (int)PTR_DIFF(buf2, dgram->data),
01269                         nmb_namestr(&dgram->dest_name),
01270                         inet_ntoa(p->ip) ));
01271                 return;
01272         }
01273 
01274         DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
01275                 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
01276                 inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
01277 
01278         /* Datagram packet received for the browser mailslot */
01279         if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
01280                 process_browse_packet(p,buf2,len);
01281                 return;
01282         }
01283 
01284         /* Datagram packet received for the LAN Manager mailslot */
01285         if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
01286                 process_lanman_packet(p,buf2,len);
01287                 return;
01288         }
01289 
01290         /* Datagram packet received for the domain logon mailslot */
01291         if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
01292                 process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
01293                 return;
01294         }
01295 
01296         /* Datagram packet received for the NT domain logon mailslot */
01297         if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
01298                 process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
01299                 return;
01300         }
01301 
01302         unexpected_packet(p);
01303 }
01304 
01305 /****************************************************************************
01306   Validate a response nmb packet.
01307 ****************************************************************************/
01308 
01309 static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
01310 {
01311         BOOL ignore = False;
01312 
01313         switch (nmb->header.opcode) {
01314                 case NMB_NAME_REG_OPCODE:
01315                 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
01316                 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
01317                         if (nmb->header.ancount == 0) {
01318                                 DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
01319                                 ignore = True;
01320                         }
01321                         break;
01322 
01323                 case NMB_NAME_QUERY_OPCODE:
01324                         if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {
01325                                 DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
01326                                 ignore = True;
01327                         }
01328                         break;
01329 
01330                 case NMB_NAME_RELEASE_OPCODE:
01331                         if (nmb->header.ancount == 0) {
01332                                 DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
01333                                 ignore = True;
01334                         }
01335                         break;
01336 
01337                 case NMB_WACK_OPCODE:
01338                         /* Check WACK response here. */
01339                         if (nmb->header.ancount != 1) {
01340                                 DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
01341                                 ignore = True;
01342                         }
01343                         break;
01344                 default:
01345                         DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
01346                                         nmb->header.opcode));
01347                         return True;
01348         }
01349 
01350         if(ignore)
01351                 DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
01352 
01353         return ignore;
01354 }
01355  
01356 /****************************************************************************
01357   Validate a request nmb packet.
01358 ****************************************************************************/
01359 
01360 static BOOL validate_nmb_packet( struct nmb_packet *nmb )
01361 {
01362         BOOL ignore = False;
01363 
01364         switch (nmb->header.opcode) {
01365                 case NMB_NAME_REG_OPCODE:
01366                 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
01367                 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
01368                 case NMB_NAME_MULTIHOMED_REG_OPCODE:
01369                         if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
01370                                 DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
01371                                 ignore = True;
01372                         }
01373                         break;
01374 
01375                 case NMB_NAME_QUERY_OPCODE:
01376                         if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
01377                                         (nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {
01378                                 DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
01379                                 ignore = True;
01380                         }
01381                         break;
01382 
01383                 case NMB_NAME_RELEASE_OPCODE:
01384                         if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
01385                                 DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
01386                                 ignore = True;
01387                         }
01388                         break;
01389                 default:
01390                         DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
01391                                 nmb->header.opcode));
01392                         return True;
01393         }
01394 
01395         if(ignore)
01396                 DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
01397 
01398         return ignore;
01399 }
01400 
01401 /****************************************************************************
01402   Find a subnet (and potentially a response record) for a packet.
01403 ****************************************************************************/
01404 
01405 static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
01406                                                          struct response_record **pprrec)
01407 {
01408         struct nmb_packet *nmb = &p->packet.nmb;
01409         struct response_record *rrec = NULL;
01410         struct subnet_record *subrec = NULL;
01411 
01412         if(pprrec != NULL)
01413                 *pprrec = NULL;
01414 
01415         if(nmb->header.response) {
01416                 /* It's a response packet. Find a record for it or it's an error. */
01417 
01418                 rrec = find_response_record( &subrec, nmb->header.name_trn_id);
01419                 if(rrec == NULL) {
01420                         DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
01421                                 nmb->header.name_trn_id));
01422                         unexpected_packet(p);
01423                         return NULL;
01424                 }
01425 
01426                 if(subrec == NULL) {
01427                         DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
01428                                 nmb->header.name_trn_id));
01429                         return NULL;
01430                 }
01431 
01432                 if(pprrec != NULL)
01433                         *pprrec = rrec;
01434                 return subrec;
01435         }
01436 
01437         /* Try and see what subnet this packet belongs to. */
01438 
01439         /* WINS server ? */
01440         if(packet_is_for_wins_server(p))
01441                 return wins_server_subnet;
01442 
01443         /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
01444         if(nmb->header.nm_flags.bcast == False)
01445                 return unicast_subnet;
01446 
01447         /* Go through all the broadcast subnets and see if the mask matches. */
01448         for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
01449                 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
01450                         return subrec;
01451         }
01452 
01453         /* If none match it must have been a directed broadcast - assign the remote_broadcast_subnet. */
01454         return remote_broadcast_subnet;
01455 }
01456 
01457 /****************************************************************************
01458   Process a nmb request packet - validate the packet and route it.
01459 ****************************************************************************/
01460 
01461 static void process_nmb_request(struct packet_struct *p)
01462 {
01463         struct nmb_packet *nmb = &p->packet.nmb;
01464         struct subnet_record *subrec = NULL;
01465 
01466         debug_nmb_packet(p);
01467 
01468         /* Ensure we have a good packet. */
01469         if(validate_nmb_packet(nmb))
01470                 return;
01471 
01472         /* Allocate a subnet to this packet - if we cannot - fail. */
01473         if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
01474                 return;
01475 
01476         switch (nmb->header.opcode) {
01477                 case NMB_NAME_REG_OPCODE:
01478                         if(subrec == wins_server_subnet)
01479                                 wins_process_name_registration_request(subrec, p);
01480                         else
01481                                 process_name_registration_request(subrec, p);
01482                         break;
01483 
01484                 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
01485                 case NMB_NAME_REFRESH_OPCODE_9:
01486                         if(subrec == wins_server_subnet)
01487                                 wins_process_name_refresh_request(subrec, p);
01488                         else
01489                                 process_name_refresh_request(subrec, p);
01490                         break;
01491 
01492                 case NMB_NAME_MULTIHOMED_REG_OPCODE:
01493                         if(subrec == wins_server_subnet) {
01494                                 wins_process_multihomed_name_registration_request(subrec, p);
01495                         } else {
01496                                 DEBUG(0,("process_nmb_request: Multihomed registration request must be \
01497 directed at a WINS server.\n"));
01498                         }
01499                         break;
01500 
01501                 case NMB_NAME_QUERY_OPCODE:
01502                         switch (nmb->question.question_type) {
01503                                 case QUESTION_TYPE_NB_QUERY:
01504                                         if(subrec == wins_server_subnet)
01505                                                 wins_process_name_query_request(subrec, p);
01506                                         else
01507                                                 process_name_query_request(subrec, p);
01508                                         break;
01509                                 case QUESTION_TYPE_NB_STATUS:
01510                                         if(subrec == wins_server_subnet) {
01511                                                 DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
01512 not allowed.\n"));
01513                                                 break;
01514                                         } else {
01515                                                 process_node_status_request(subrec, p);
01516                                         }
01517                                         break;
01518                         }
01519                         break;
01520       
01521                 case NMB_NAME_RELEASE_OPCODE:
01522                         if(subrec == wins_server_subnet)
01523                                 wins_process_name_release_request(subrec, p);
01524                         else
01525                                 process_name_release_request(subrec, p);
01526                         break;
01527         }
01528 }
01529 
01530 /****************************************************************************
01531   Process a nmb response packet - validate the packet and route it.
01532   to either the WINS server or a normal response.
01533 ****************************************************************************/
01534 
01535 static void process_nmb_response(struct packet_struct *p)
01536 {
01537         struct nmb_packet *nmb = &p->packet.nmb;
01538         struct subnet_record *subrec = NULL;
01539         struct response_record *rrec = NULL;
01540 
01541         debug_nmb_packet(p);
01542 
01543         if(validate_nmb_response_packet(nmb))
01544                 return;
01545 
01546         if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
01547                 return;
01548 
01549         if(rrec == NULL) {
01550                 DEBUG(0,("process_nmb_response: response packet received but no response record \
01551 found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
01552                 return;
01553         }
01554 
01555         /* Increment the number of responses received for this record. */
01556         rrec->num_msgs++;
01557         /* Ensure we don't re-send the request. */
01558         rrec->repeat_count = 0;
01559   
01560         /* Call the response received function for this packet. */
01561         (*rrec->resp_fn)(subrec, rrec, p);
01562 }
01563 
01564 /*******************************************************************
01565   Run elements off the packet queue till its empty
01566 ******************************************************************/
01567 
01568 void run_packet_queue(void)
01569 {
01570         struct packet_struct *p;
01571 
01572         while ((p = packet_queue)) {
01573                 packet_queue = p->next;
01574                 if (packet_queue)
01575                         packet_queue->prev = NULL;
01576                 p->next = p->prev = NULL;
01577 
01578                 switch (p->packet_type) {
01579                         case NMB_PACKET:
01580                                 if(p->packet.nmb.header.response)
01581                                         process_nmb_response(p);
01582                                 else
01583                                         process_nmb_request(p);
01584                                 break;
01585 
01586                         case DGRAM_PACKET:
01587                                 process_dgram(p);
01588                                 break;
01589                 }
01590                 free_packet(p);
01591         }
01592 } 
01593 
01594 /*******************************************************************
01595  Retransmit or timeout elements from all the outgoing subnet response
01596  record queues. NOTE that this code must also check the WINS server
01597  subnet for response records to timeout as the WINS server code
01598  can send requests to check if a client still owns a name.
01599  (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
01600 ******************************************************************/
01601 
01602 void retransmit_or_expire_response_records(time_t t)
01603 {
01604         struct subnet_record *subrec;
01605 
01606         for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
01607                 struct response_record *rrec, *nextrrec;
01608 
01609   restart:
01610 
01611                 for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
01612                         nextrrec = rrec->next;
01613    
01614                         if (rrec->repeat_time <= t) {
01615                                 if (rrec->repeat_count > 0) {
01616                                         /* Resend while we have a non-zero repeat_count. */
01617                                         if(!send_packet(rrec->packet)) {
01618                                                 DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
01619 to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
01620                                         }
01621                                         rrec->repeat_time = t + rrec->repeat_interval;
01622                                         rrec->repeat_count--;
01623                                 } else {
01624                                         DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
01625 on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
01626 
01627                                         /*
01628                                          * Check the flag in this record to prevent recursion if we end
01629                                          * up in this function again via the timeout function call.
01630                                          */
01631 
01632                                         if(!rrec->in_expiration_processing) {
01633 
01634                                                 /*
01635                                                  * Set the recursion protection flag in this record.
01636                                                  */
01637 
01638                                                 rrec->in_expiration_processing = True;
01639 
01640                                                 /* Call the timeout function. This will deal with removing the
01641                                                                 timed out packet. */
01642                                                 if(rrec->timeout_fn) {
01643                                                         (*rrec->timeout_fn)(subrec, rrec);
01644                                                 } else {
01645                                                         /* We must remove the record ourself if there is
01646                                                                         no timeout function. */
01647                                                         remove_response_record(subrec, rrec);
01648                                                 }
01649                                                 /* We have changed subrec->responselist,
01650                                                  * restart from the beginning of this list. */
01651                                                 goto restart;
01652                                         } /* !rrec->in_expitation_processing */
01653                                 } /* rrec->repeat_count > 0 */
01654                         } /* rrec->repeat_time <= t */
01655                 } /* end for rrec */
01656         } /* end for subnet */
01657 }
01658 
01659 /****************************************************************************
01660   Create an fd_set containing all the sockets in the subnet structures,
01661   plus the broadcast sockets.
01662 ***************************************************************************/
01663 
01664 static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
01665 {
01666         int *sock_array = NULL;
01667         struct subnet_record *subrec = NULL;
01668         int count = 0;
01669         int num = 0;
01670         fd_set *pset = SMB_MALLOC_P(fd_set);
01671 
01672         if(pset == NULL) {
01673                 DEBUG(0,("create_listen_fdset: malloc fail !\n"));
01674                 return True;
01675         }
01676 
01677         /* Check that we can add all the fd's we need. */
01678         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
01679                 count++;
01680 
01681         if((count*2) + 2 > FD_SETSIZE) {
01682                 DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
01683 only use %d.\n", (count*2) + 2, FD_SETSIZE));
01684                 SAFE_FREE(pset);
01685                 return True;
01686         }
01687 
01688         if((sock_array = SMB_MALLOC_ARRAY(int, (count*2) + 2)) == NULL) {
01689                 DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
01690                 SAFE_FREE(pset);
01691                 return True;
01692         }
01693 
01694         FD_ZERO(pset);
01695 
01696         /* Add in the broadcast socket on 137. */
01697         FD_SET(ClientNMB,pset);
01698         sock_array[num++] = ClientNMB;
01699         *maxfd = MAX( *maxfd, ClientNMB);
01700 
01701         /* Add in the 137 sockets on all the interfaces. */
01702         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
01703                 FD_SET(subrec->nmb_sock,pset);
01704                 sock_array[num++] = subrec->nmb_sock;
01705                 *maxfd = MAX( *maxfd, subrec->nmb_sock);
01706         }
01707 
01708         /* Add in the broadcast socket on 138. */
01709         FD_SET(ClientDGRAM,pset);
01710         sock_array[num++] = ClientDGRAM;
01711         *maxfd = MAX( *maxfd, ClientDGRAM);
01712 
01713         /* Add in the 138 sockets on all the interfaces. */
01714         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
01715                 FD_SET(subrec->dgram_sock,pset);
01716                 sock_array[num++] = subrec->dgram_sock;
01717                 *maxfd = MAX( *maxfd, subrec->dgram_sock);
01718         }
01719 
01720         *listen_number = (count*2) + 2;
01721 
01722         SAFE_FREE(*ppset);
01723         SAFE_FREE(*psock_array);
01724 
01725         *ppset = pset;
01726         *psock_array = sock_array;
01727  
01728         return False;
01729 }
01730 
01731 /****************************************************************************
01732   Listens for NMB or DGRAM packets, and queues them.
01733   return True if the socket is dead
01734 ***************************************************************************/
01735 
01736 BOOL listen_for_packets(BOOL run_election)
01737 {
01738         static fd_set *listen_set = NULL;
01739         static int listen_number = 0;
01740         static int *sock_array = NULL;
01741         int i;
01742         static int maxfd = 0;
01743 
01744         fd_set fds;
01745         int selrtn;
01746         struct timeval timeout;
01747 #ifndef SYNC_DNS
01748         int dns_fd;
01749 #endif
01750 
01751         if(listen_set == NULL || rescan_listen_set) {
01752                 if(create_listen_fdset(&listen_set, &sock_array, &listen_number, &maxfd)) {
01753                         DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
01754                         return True;
01755                 }
01756                 rescan_listen_set = False;
01757         }
01758 
01759         memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
01760 
01761 #ifndef SYNC_DNS
01762         dns_fd = asyncdns_fd();
01763         if (dns_fd != -1) {
01764                 FD_SET(dns_fd, &fds);
01765                 maxfd = MAX( maxfd, dns_fd);
01766         }
01767 #endif
01768 
01769         /* 
01770          * During elections and when expecting a netbios response packet we
01771          * need to send election packets at tighter intervals.
01772          * Ideally it needs to be the interval (in ms) between time now and
01773          * the time we are expecting the next netbios packet.
01774          */
01775 
01776         timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
01777         timeout.tv_usec = 0;
01778 
01779         /* Prepare for the select - allow certain signals. */
01780 
01781         BlockSignals(False, SIGTERM);
01782 
01783         selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&timeout);
01784 
01785         /* We can only take signals when we are in the select - block them again here. */
01786 
01787         BlockSignals(True, SIGTERM);
01788 
01789         if(selrtn == -1) {
01790                 return False;
01791         }
01792 
01793 #ifndef SYNC_DNS
01794         if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
01795                 run_dns_queue();
01796         }
01797 #endif
01798 
01799         for(i = 0; i < listen_number; i++) {
01800                 if (i < (listen_number/2)) {
01801                         /* Processing a 137 socket. */
01802                         if (FD_ISSET(sock_array[i],&fds)) {
01803                                 struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
01804                                 if (packet) {
01805                                         /*
01806                                          * If we got a packet on the broadcast socket and interfaces
01807                                          * only is set then check it came from one of our local nets. 
01808                                          */
01809                                         if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) && 
01810                                                                 (!is_local_net(packet->ip))) {
01811                                                 DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
01812                                                         inet_ntoa(packet->ip),packet->port));     
01813                                                 free_packet(packet);
01814                                         } else if ((ip_equal(loopback_ip, packet->ip) || 
01815                                                                 ismyip(packet->ip)) && packet->port == global_nmb_port &&
01816                                                                 packet->packet.nmb.header.nm_flags.bcast) {
01817                                                 DEBUG(7,("discarding own bcast packet from %s:%d\n",
01818                                                         inet_ntoa(packet->ip),packet->port));     
01819                                                 free_packet(packet);
01820                                         } else {
01821                                                 /* Save the file descriptor this packet came in on. */
01822                                                 packet->fd = sock_array[i];
01823                                                 queue_packet(packet);
01824                                         }
01825                                 }
01826                         }
01827                 } else {
01828                         /* Processing a 138 socket. */
01829                                 if (FD_ISSET(sock_array[i],&fds)) {
01830                                 struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
01831                                 if (packet) {
01832                                         /*
01833                                          * If we got a packet on the broadcast socket and interfaces
01834                                          * only is set then check it came from one of our local nets. 
01835                                          */
01836                                         if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) && 
01837                                                                 (!is_local_net(packet->ip))) {
01838                                                 DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
01839                                                 inet_ntoa(packet->ip),packet->port));     
01840                                                 free_packet(packet);
01841                                         } else if ((ip_equal(loopback_ip, packet->ip) || 
01842                                                         ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
01843                                                 DEBUG(7,("discarding own dgram packet from %s:%d\n",
01844                                                         inet_ntoa(packet->ip),packet->port));     
01845                                                 free_packet(packet);
01846                                         } else {
01847                                                 /* Save the file descriptor this packet came in on. */
01848                                                 packet->fd = sock_array[i];
01849                                                 queue_packet(packet);
01850                                         }
01851                                 }
01852                         }
01853                 } /* end processing 138 socket. */
01854         } /* end for */
01855         return False;
01856 }
01857 
01858 /****************************************************************************
01859   Construct and send a netbios DGRAM.
01860 **************************************************************************/
01861 
01862 BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
01863                    const char *srcname, int src_type,
01864                    const char *dstname, int dest_type,
01865                    struct in_addr dest_ip,struct in_addr src_ip,
01866                    int dest_port)
01867 {
01868         BOOL loopback_this_packet = False;
01869         struct packet_struct p;
01870         struct dgram_packet *dgram = &p.packet.dgram;
01871         char *ptr,*p2;
01872         char tmp[4];
01873 
01874         memset((char *)&p,'\0',sizeof(p));
01875 
01876         if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
01877                 loopback_this_packet = True;
01878 
01879         /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
01880 
01881         /* DIRECT GROUP or UNIQUE datagram. */
01882         dgram->header.msg_type = unique ? 0x10 : 0x11; 
01883         dgram->header.flags.node_type = M_NODE;
01884         dgram->header.flags.first = True;
01885         dgram->header.flags.more = False;
01886         dgram->header.dgm_id = generate_name_trn_id();
01887         dgram->header.source_ip = src_ip;
01888         dgram->header.source_port = DGRAM_PORT;
01889         dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
01890         dgram->header.packet_offset = 0;
01891   
01892         make_nmb_name(&dgram->source_name,srcname,src_type);
01893         make_nmb_name(&dgram->dest_name,dstname,dest_type);
01894 
01895         ptr = &dgram->data[0];
01896 
01897         /* Setup the smb part. */
01898         ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
01899         memcpy(tmp,ptr,4);
01900 
01901         if (smb_size + 17*2 + strlen(mailslot) + 1 + len > MAX_DGRAM_SIZE) {
01902                 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
01903                 return False;
01904         }
01905 
01906         set_message(ptr,17,strlen(mailslot) + 1 + len,True);
01907         memcpy(ptr,tmp,4);
01908 
01909         SCVAL(ptr,smb_com,SMBtrans);
01910         SSVAL(ptr,smb_vwv1,len);
01911         SSVAL(ptr,smb_vwv11,len);
01912         SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
01913         SSVAL(ptr,smb_vwv13,3);
01914         SSVAL(ptr,smb_vwv14,1);
01915         SSVAL(ptr,smb_vwv15,1);
01916         SSVAL(ptr,smb_vwv16,2);
01917         p2 = smb_buf(ptr);
01918         safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
01919         p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2);
01920   
01921         if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
01922                 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
01923                 return False;
01924         } else {
01925                 memcpy(p2,buf,len);
01926                 p2 += len;
01927         }
01928 
01929         dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
01930 
01931         p.ip = dest_ip;
01932         p.port = dest_port;
01933         p.fd = find_subnet_mailslot_fd_for_address( src_ip );
01934         p.timestamp = time(NULL);
01935         p.packet_type = DGRAM_PACKET;
01936 
01937         DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
01938                         nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
01939         DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
01940 
01941         debug_browse_data(buf, len);
01942 
01943         if(loopback_this_packet) {
01944                 struct packet_struct *lo_packet = NULL;
01945                 DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
01946                 if((lo_packet = copy_packet(&p)) == NULL)
01947                         return False;
01948                 queue_packet(lo_packet);
01949                 return True;
01950         } else {
01951                 return(send_packet(&p));
01952         }
01953 }

Sambaに対してSat Aug 29 21:23:08 2009に生成されました。  doxygen 1.4.7