s3-registry: Check return code of push_reg_sz().
[kai/samba.git] / source3 / nmbd / nmbd_packets.c
index cb13febe466830eadb4750f572be98c841363148..7a707a045b989ffeae62da8c6b4af926b0a75eaa 100644 (file)
@@ -4,23 +4,26 @@
    Copyright (C) Andrew Tridgell 1994-1998
    Copyright (C) Luke Kenneth Casson Leighton 1994-1998
    Copyright (C) Jeremy Allison 1994-2003
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-   
 */
 
 #include "includes.h"
+#include "nmbd/nmbd.h"
+#include "../lib/util/select.h"
+#include "system/select.h"
+#include "libsmb/libsmb.h"
 
 extern int ClientNMB;
 extern int ClientDGRAM;
@@ -28,9 +31,25 @@ extern int global_nmb_port;
 
 extern int num_response_packets;
 
-static void queue_packet(struct packet_struct *packet);
+bool rescan_listen_set = False;
 
-BOOL rescan_listen_set = False;
+static struct nb_packet_server *packet_server;
+
+bool nmbd_init_packet_server(void)
+{
+       NTSTATUS status;
+
+       status = nb_packet_server_create(
+               NULL, nmbd_event_context(),
+               lp_parm_int(-1, "nmbd", "unexpected_clients", 200),
+               &packet_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("ERROR: nb_packet_server_create failed: %s\n",
+                         nt_errstr(status)));
+               return false;
+       }
+       return true;
+}
 
 
 /*******************************************************************
@@ -50,7 +69,7 @@ static int find_subnet_fd_for_address( struct in_addr local_ip )
        struct subnet_record *subrec;
 
        for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
-               if(ip_equal(local_ip, subrec->myip))
+               if(ip_equal_v4(local_ip, subrec->myip))
                        return subrec->nmb_sock;
 
        return ClientNMB;
@@ -65,7 +84,7 @@ static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
        struct subnet_record *subrec;
 
        for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
-               if(ip_equal(local_ip, subrec->myip))
+               if(ip_equal_v4(local_ip, subrec->myip))
                        return subrec->dgram_sock;
 
        return ClientDGRAM;
@@ -90,7 +109,7 @@ void set_nb_flags(char *buf, uint16 nb_flags)
 Dumps out the browse packet data.
 **************************************************************************/
 
-static void debug_browse_data(char *outbuf, int len)
+static void debug_browse_data(const char *outbuf, int len)
 {
        int i,j;
 
@@ -106,7 +125,7 @@ static void debug_browse_data(char *outbuf, int len)
                        x = outbuf[i+j];
                        if (x < 32 || x > 127) 
                                x = '.';
-           
+
                        DEBUGADD( 4, ( "%c", x ) );
                }
 
@@ -131,7 +150,7 @@ static uint16 name_trn_id=0;
 static uint16 generate_name_trn_id(void)
 {
        if (!name_trn_id) {
-               name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
+               name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)getpid()%(unsigned)100);
        }
        name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
        return name_trn_id;
@@ -141,9 +160,9 @@ static uint16 generate_name_trn_id(void)
  Either loops back or sends out a completed NetBIOS packet.
 **************************************************************************/
 
-static BOOL send_netbios_packet(struct packet_struct *p)
+static bool send_netbios_packet(struct packet_struct *p)
 {
-       BOOL loopback_this_packet = False;
+       bool loopback_this_packet = False;
 
        /* Check if we are sending to or from ourselves as a WINS server. */
        if(ismyip_v4(p->ip) && (p->port == global_nmb_port))
@@ -160,7 +179,7 @@ static BOOL send_netbios_packet(struct packet_struct *p)
                        inet_ntoa(p->ip),p->port));
                return False;
        }
-  
+
        return True;
 } 
 
@@ -174,7 +193,7 @@ static BOOL send_netbios_packet(struct packet_struct *p)
 **************************************************************************/
 
 static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
-                                                            BOOL bcast, BOOL rec_des,
+                                                            bool bcast, bool rec_des,
                                                             struct in_addr to_ip)
 {
        struct packet_struct *packet = NULL;
@@ -185,7 +204,7 @@ static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmb
                DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
                return NULL;
        }
-    
+
        memset((char *)packet,'\0',sizeof(*packet));
 
        nmb = &packet->packet.nmb;
@@ -197,7 +216,7 @@ static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmb
        nmb->header.nm_flags.trunc = False;
        nmb->header.nm_flags.authoritative = False;
        nmb->header.nm_flags.bcast = bcast;
-  
+
        nmb->header.rcode = 0;
        nmb->header.qdcount = 1;
        nmb->header.ancount = 0;
@@ -209,11 +228,12 @@ static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmb
 
        packet->ip = to_ip;
        packet->port = NMB_PORT;
-       packet->fd = ClientNMB;
+       packet->recv_fd = -1;
+       packet->send_fd = ClientNMB;
        packet->timestamp = time(NULL);
        packet->packet_type = NMB_PACKET;
        packet->locked = False;
-  
+
        return packet; /* Caller must free. */
 }
 
@@ -221,7 +241,7 @@ static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmb
  Sets up the common elements of register, refresh or release packet.
 **************************************************************************/
 
-static BOOL create_and_init_additional_record(struct packet_struct *packet,
+static bool create_and_init_additional_record(struct packet_struct *packet,
                                                      uint16 nb_flags,
                                                      const struct in_addr *register_ip)
 {
@@ -237,20 +257,20 @@ static BOOL create_and_init_additional_record(struct packet_struct *packet,
        nmb->additional->rr_name  = nmb->question.question_name;
        nmb->additional->rr_type  = RR_TYPE_NB;
        nmb->additional->rr_class = RR_CLASS_IN;
-       
+
        /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
        if (nmb->header.nm_flags.bcast)
                nmb->additional->ttl = PERMANENT_TTL;
        else
                nmb->additional->ttl = lp_max_ttl();
-       
+
        nmb->additional->rdlength = 6;
-       
+
        set_nb_flags(nmb->additional->rdata,nb_flags);
-       
+
        /* Set the address for the name we are registering. */
        putip(&nmb->additional->rdata[2], register_ip);
-       
+
        /* 
           it turns out that Jeremys code was correct, we are supposed
           to send registrations from the IP we are registering. The
@@ -260,7 +280,8 @@ static BOOL create_and_init_additional_record(struct packet_struct *packet,
           our standard refresh cycle for that name which copes nicely
           with disconnected networks.
        */
-       packet->fd = find_subnet_fd_for_address(*register_ip);
+       packet->recv_fd = -1;
+       packet->send_fd = find_subnet_fd_for_address(*register_ip);
 
        return True;
 }
@@ -269,7 +290,7 @@ static BOOL create_and_init_additional_record(struct packet_struct *packet,
  Sends out a name query.
 **************************************************************************/
 
-static BOOL initiate_name_query_packet( struct packet_struct *packet)
+static bool initiate_name_query_packet( struct packet_struct *packet)
 {
        struct nmb_packet *nmb = NULL;
 
@@ -291,21 +312,21 @@ static BOOL initiate_name_query_packet( struct packet_struct *packet)
  Sends out a name query - from a WINS server. 
 **************************************************************************/
 
-static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
+static bool initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
 {   
        struct nmb_packet *nmb = NULL;
-  
+
        nmb = &packet->packet.nmb;
 
        nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
        nmb->header.arcount = 0;
-    
+
        nmb->header.nm_flags.recursion_desired = False;
-  
+
        DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
                nmb_namestr(&nmb->question.question_name),
                BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
-    
+
        return send_netbios_packet( packet );
 } 
 
@@ -313,7 +334,7 @@ static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *p
  Sends out a name register.
 **************************************************************************/
 
-static BOOL initiate_name_register_packet( struct packet_struct *packet,
+static bool initiate_name_register_packet( struct packet_struct *packet,
                                     uint16 nb_flags, const struct in_addr *register_ip)
 {
        struct nmb_packet *nmb = &packet->packet.nmb;
@@ -337,7 +358,7 @@ static BOOL initiate_name_register_packet( struct packet_struct *packet,
  Sends out a multihomed name register.
 **************************************************************************/
 
-static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packet,
+static bool initiate_multihomed_name_register_packet(struct packet_struct *packet,
                                                     uint16 nb_flags, struct in_addr *register_ip)
 {
        struct nmb_packet *nmb = &packet->packet.nmb;
@@ -349,10 +370,10 @@ static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packe
        nmb->header.arcount = 1;
 
        nmb->header.nm_flags.recursion_desired = True;
-       
+
        if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
                return False;
-       
+
        DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
 for name %s IP %s (bcast=%s) to IP %s\n",
                 nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
@@ -365,7 +386,7 @@ for name %s IP %s (bcast=%s) to IP %s\n",
  Sends out a name refresh.
 **************************************************************************/
 
-static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
+static bool initiate_name_refresh_packet( struct packet_struct *packet,
                                    uint16 nb_flags, struct in_addr *refresh_ip)
 {
        struct nmb_packet *nmb = &packet->packet.nmb;
@@ -389,7 +410,7 @@ static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
  Sends out a name release.
 **************************************************************************/
 
-static BOOL initiate_name_release_packet( struct packet_struct *packet,
+static bool initiate_name_release_packet( struct packet_struct *packet,
                                    uint16 nb_flags, struct in_addr *release_ip)
 {
        struct nmb_packet *nmb = &packet->packet.nmb;
@@ -413,7 +434,7 @@ static BOOL initiate_name_release_packet( struct packet_struct *packet,
  Sends out a node status.
 **************************************************************************/
 
-static BOOL initiate_node_status_packet( struct packet_struct *packet )
+static bool initiate_node_status_packet( struct packet_struct *packet )
 {
        struct nmb_packet *nmb = &packet->packet.nmb;
 
@@ -442,7 +463,7 @@ static BOOL initiate_node_status_packet( struct packet_struct *packet )
  broadcast subnet.
 ****************************************************************************/
 
-static BOOL assert_check_subnet(struct subnet_record *subrec)
+static bool assert_check_subnet(struct subnet_record *subrec)
 {
        if( subrec == remote_broadcast_subnet) {
                DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
@@ -478,7 +499,7 @@ struct response_record *queue_register_name( struct subnet_record *subrec,
                return NULL;
 
        in_addr_to_sockaddr_storage(&ss, subrec->bcast_ip);
-       pss = iface_ip(&ss);
+       pss = iface_ip((struct sockaddr *)(void *)&ss);
        if (!pss || pss->ss_family != AF_INET) {
                p->locked = False;
                free_packet(p);
@@ -587,8 +608,8 @@ struct response_record *queue_register_multihomed_name( struct subnet_record *su
 {
        struct packet_struct *p;
        struct response_record *rrec;
-       BOOL ret;
-       
+       bool ret;
+
        /* Sanity check. */
        if(subrec != unicast_subnet) {
                DEBUG(0,("queue_register_multihomed_name: should only be done on \
@@ -598,7 +619,7 @@ unicast subnet. subnet is %s\n.", subrec->subnet_name ));
 
        if(assert_check_subnet(subrec))
                return NULL;
-     
+
        if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
                return NULL;
 
@@ -612,7 +633,7 @@ unicast subnet. subnet is %s\n.", subrec->subnet_name ));
                free_packet(p);
                return NULL;
        }  
-  
+
        if ((rrec = make_response_record(subrec,    /* subnet record. */
                                         p,                     /* packet we sent. */
                                         resp_fn,               /* function to call on response. */
@@ -624,7 +645,7 @@ unicast subnet. subnet is %s\n.", subrec->subnet_name ));
                free_packet(p);
                return NULL;
        }  
-       
+
        return rrec;
 }
 
@@ -686,7 +707,7 @@ struct response_record *queue_release_name( struct subnet_record *subrec,
 /****************************************************************************
  Queue a query name packet to the broadcast address of a subnet.
 ****************************************************************************/
+
 struct response_record *queue_query_name( struct subnet_record *subrec,
                           response_function resp_fn,
                           timeout_response_function timeout_fn,
@@ -703,7 +724,7 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
                return NULL;
 
        to_ip = subrec->bcast_ip;
-  
+
        /* queries to the WINS server turn up here as queries to IP 0.0.0.0 
                        These need to be handled a bit differently */
        if (subrec->type == UNICAST_SUBNET && is_zero_ip_v4(to_ip)) {
@@ -745,7 +766,7 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
                        }
 
                        DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
-                               p->fd = find_subnet_fd_for_address( *ifip );
+                               p->send_fd = find_subnet_fd_for_address( *ifip );
                                break;
                }
        }
@@ -872,7 +893,7 @@ void reply_netbios_packet(struct packet_struct *orig_packet,
        struct nmb_packet *nmb = NULL;
        struct res_rec answers;
        struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
-       BOOL loopback_this_packet = False;
+       bool loopback_this_packet = False;
        int rr_type = RR_TYPE_NB;
        const char *packet_type = "unknown";
 
@@ -942,9 +963,10 @@ void reply_netbios_packet(struct packet_struct *orig_packet,
                        return;
        }
 
-       DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
-for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
-                       inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
+       DEBUG(4, ("reply_netbios_packet: sending a reply of packet type: %s "
+                 "%s to ip %s for id %d\n", packet_type,
+                 nmb_namestr(&orig_nmb->question.question_name),
+                 inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
 
        nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
        nmb->header.opcode = opcode;
@@ -970,14 +992,25 @@ for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
        nmb->answers->ttl      = ttl;
 
        if (data && len) {
+               if (len < 0 || len > sizeof(nmb->answers->rdata)) {
+                       DEBUG(5,("reply_netbios_packet: "
+                               "invalid packet len (%d)\n",
+                               len ));
+                       return;
+               }
                nmb->answers->rdlength = len;
                memcpy(nmb->answers->rdata, data, len);
        }
 
        packet.packet_type = NMB_PACKET;
+       packet.recv_fd = -1;
        /* Ensure we send out on the same fd that the original
                packet came in on to give the correct source IP address. */
-       packet.fd = orig_packet->fd;
+       if (orig_packet->send_fd != -1) {
+               packet.send_fd = orig_packet->send_fd;
+       } else {
+               packet.send_fd = orig_packet->recv_fd;
+       }
        packet.timestamp = time(NULL);
 
        debug_nmb_packet(&packet);
@@ -998,24 +1031,9 @@ for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
   Queue a packet into a packet queue
 ******************************************************************/
 
-static void queue_packet(struct packet_struct *packet)
+void queue_packet(struct packet_struct *packet)
 {
-       struct packet_struct *p;
-
-       if (!packet_queue) {
-               packet->prev = NULL;
-               packet->next = NULL;
-               packet_queue = packet;
-               return;
-       }
-
-       /* find the bottom */
-       for (p=packet_queue;p->next;p=p->next)
-               ;
-
-       p->next = packet;
-       packet->next = NULL;
-       packet->prev = p;
+       DLIST_ADD_END(packet_queue, packet, struct packet_struct *);
 }
 
 /****************************************************************************
@@ -1046,7 +1064,7 @@ static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_s
 Dispatch a browse frame from port 138 to the correct processing function.
 ****************************************************************************/
 
-static void process_browse_packet(struct packet_struct *p, char *buf,int len)
+static void process_browse_packet(struct packet_struct *p, const char *buf,int len)
 {
        struct dgram_packet *dgram = &p->packet.dgram;
        int command = CVAL(buf,0);
@@ -1056,15 +1074,15 @@ static void process_browse_packet(struct packet_struct *p, char *buf,int len)
 
        /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
        pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
-       if (!strequal(scope, global_scope())) {
+       if (!strequal(scope, lp_netbios_scope())) {
                DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
-mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
+mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, lp_netbios_scope()));
                return;
        }
 
        pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
        if (is_myname(src_name)) {
-               DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
+               DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Source name \
 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
                return;
        }
@@ -1133,7 +1151,7 @@ command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namest
  Dispatch a LanMan browse frame from port 138 to the correct processing function.
 ****************************************************************************/
 
-static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
+static void process_lanman_packet(struct packet_struct *p, const char *buf,int len)
 {
        struct dgram_packet *dgram = &p->packet.dgram;
        int command = SVAL(buf,0);
@@ -1144,9 +1162,9 @@ static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
        /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
 
        pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
-       if (!strequal(scope, global_scope())) {
+       if (!strequal(scope, lp_netbios_scope())) {
                DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
-mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
+mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, lp_netbios_scope()));
                return;
        }
 
@@ -1179,7 +1197,7 @@ command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namest
   stage as subsequent processing is expensive. 
 ****************************************************************************/
 
-static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
+static bool listening(struct packet_struct *p,struct nmb_name *nbname)
 {
        struct subnet_record *subrec = NULL;
 
@@ -1200,21 +1218,21 @@ static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
 
 static void process_dgram(struct packet_struct *p)
 {
-       char *buf;
-       char *buf2;
+       const char *buf;
+       const char *buf2;
        int len;
        struct dgram_packet *dgram = &p->packet.dgram;
 
        /* If we aren't listening to the destination name then ignore the packet */
        if (!listening(p,&dgram->dest_name)) {
-                       unexpected_packet(p);
+                       nb_packet_dispatch(packet_server, p);
                        DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
                                nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
                        return;
        }
 
        if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
-               unexpected_packet(p);
+               nb_packet_dispatch(packet_server, p);
                /* Don't process error packets etc yet */
                DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
 an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
@@ -1274,42 +1292,42 @@ packet sent to name %s from IP %s\n",
 
        DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
                nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
-               inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
+               inet_ntoa(p->ip), smb_buf_const(buf),CVAL(buf2,0),len));
 
        /* Datagram packet received for the browser mailslot */
-       if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
+       if (strequal(smb_buf_const(buf),BROWSE_MAILSLOT)) {
                process_browse_packet(p,buf2,len);
                return;
        }
 
        /* Datagram packet received for the LAN Manager mailslot */
-       if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
+       if (strequal(smb_buf_const(buf),LANMAN_MAILSLOT)) {
                process_lanman_packet(p,buf2,len);
                return;
        }
 
        /* Datagram packet received for the domain logon mailslot */
-       if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
+       if (strequal(smb_buf_const(buf),NET_LOGON_MAILSLOT)) {
                process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
                return;
        }
 
        /* Datagram packet received for the NT domain logon mailslot */
-       if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
+       if (strequal(smb_buf_const(buf),NT_LOGON_MAILSLOT)) {
                process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
                return;
        }
 
-       unexpected_packet(p);
+       nb_packet_dispatch(packet_server, p);
 }
 
 /****************************************************************************
   Validate a response nmb packet.
 ****************************************************************************/
 
-static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
+static bool validate_nmb_response_packet( struct nmb_packet *nmb )
 {
-       BOOL ignore = False;
+       bool ignore = False;
 
        switch (nmb->header.opcode) {
                case NMB_NAME_REG_OPCODE:
@@ -1358,9 +1376,9 @@ static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
   Validate a request nmb packet.
 ****************************************************************************/
 
-static BOOL validate_nmb_packet( struct nmb_packet *nmb )
+static bool validate_nmb_packet( struct nmb_packet *nmb )
 {
-       BOOL ignore = False;
+       bool ignore = False;
 
        switch (nmb->header.opcode) {
                case NMB_NAME_REG_OPCODE:
@@ -1418,15 +1436,17 @@ static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p
 
                rrec = find_response_record( &subrec, nmb->header.name_trn_id);
                if(rrec == NULL) {
-                       DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
-                               nmb->header.name_trn_id));
-                       unexpected_packet(p);
+                       DEBUG(3, ("find_subnet_for_nmb_packet: response "
+                                 "record not found for response id %d\n",
+                                 nmb->header.name_trn_id));
+                       nb_packet_dispatch(packet_server, p);
                        return NULL;
                }
 
                if(subrec == NULL) {
-                       DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
-                               nmb->header.name_trn_id));
+                       DEBUG(0, ("find_subnet_for_nmb_packet: subnet record "
+                                 "not found for response id %d\n",
+                                 nmb->header.name_trn_id));
                        return NULL;
                }
 
@@ -1548,8 +1568,9 @@ static void process_nmb_response(struct packet_struct *p)
                return;
 
        if(rrec == NULL) {
-               DEBUG(0,("process_nmb_response: response packet received but no response record \
-found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
+               DEBUG(0, ("process_nmb_response: response packet received but "
+                         "no response record found for id = %d. Ignoring "
+                         "packet.\n", nmb->header.name_trn_id));
                return;
        }
 
@@ -1571,10 +1592,7 @@ void run_packet_queue(void)
        struct packet_struct *p;
 
        while ((p = packet_queue)) {
-               packet_queue = p->next;
-               if (packet_queue)
-                       packet_queue->prev = NULL;
-               p->next = p->prev = NULL;
+               DLIST_REMOVE(packet_queue, p);
 
                switch (p->packet_type) {
                        case NMB_PACKET:
@@ -1607,6 +1625,8 @@ void retransmit_or_expire_response_records(time_t t)
        for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
                struct response_record *rrec, *nextrrec;
 
+  restart:
+
                for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
                        nextrrec = rrec->next;
 
@@ -1645,6 +1665,9 @@ on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_
                                                                        no timeout function. */
                                                        remove_response_record(subrec, rrec);
                                                }
+                                               /* We have changed subrec->responselist,
+                                                * restart from the beginning of this list. */
+                                               goto restart;
                                        } /* !rrec->in_expitation_processing */
                                } /* rrec->repeat_count > 0 */
                        } /* rrec->repeat_time <= t */
@@ -1657,113 +1680,252 @@ on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_
   plus the broadcast sockets.
 ***************************************************************************/
 
-static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
+struct socket_attributes {
+       enum packet_type type;
+       bool broadcast;
+};
+
+static bool create_listen_pollfds(struct pollfd **pfds,
+                                 struct socket_attributes **pattrs,
+                                 int *pnum_sockets)
 {
-       int *sock_array = NULL;
        struct subnet_record *subrec = NULL;
        int count = 0;
        int num = 0;
-       fd_set *pset = SMB_MALLOC_P(fd_set);
+       struct pollfd *fds;
+       struct socket_attributes *attrs;
 
-       if(pset == NULL) {
-               DEBUG(0,("create_listen_fdset: malloc fail !\n"));
-               return True;
-       }
+       /* The ClientNMB and ClientDGRAM sockets */
+       count = 2;
 
        /* Check that we can add all the fd's we need. */
-       for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
-               count++;
+       for (subrec = FIRST_SUBNET;
+            subrec != NULL;
+            subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+               if (subrec->nmb_sock != -1) {
+                       count += 1;
+               }
+               if (subrec->dgram_sock != -1) {
+                       count += 1;
+               }
+               if (subrec->nmb_bcast != -1) {
+                       count += 1;
+               }
+               if (subrec->dgram_bcast != -1) {
+                       count += 1;
+               }
+       }
 
-       if((count*2) + 2 > FD_SETSIZE) {
-               DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
-only use %d.\n", (count*2) + 2, FD_SETSIZE));
-               SAFE_FREE(pset);
-               return True;
+       fds = talloc_zero_array(NULL, struct pollfd, count);
+       if (fds == NULL) {
+               DEBUG(1, ("create_listen_pollfds: malloc fail for fds. "
+                         "size %d\n", count));
+               return true;
        }
 
-       if((sock_array = SMB_MALLOC_ARRAY(int, (count*2) + 2)) == NULL) {
-               DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
-               SAFE_FREE(pset);
-               return True;
+       attrs = talloc_array(NULL, struct socket_attributes, count);
+       if (fds == NULL) {
+               DEBUG(1, ("create_listen_pollfds: malloc fail for attrs. "
+                         "size %d\n", count));
+               TALLOC_FREE(fds);
+               return true;
        }
 
-       FD_ZERO(pset);
+       num = 0;
+
+       fds[num].fd = ClientNMB;
+       attrs[num].type = NMB_PACKET;
+       attrs[num].broadcast = false;
+       num += 1;
 
-       /* Add in the broadcast socket on 137. */
-       FD_SET(ClientNMB,pset);
-       sock_array[num++] = ClientNMB;
-       *maxfd = MAX( *maxfd, ClientNMB);
+       fds[num].fd = ClientDGRAM;
+       attrs[num].type = DGRAM_PACKET;
+       attrs[num].broadcast = false;
+       num += 1;
 
-       /* Add in the 137 sockets on all the interfaces. */
        for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
-               FD_SET(subrec->nmb_sock,pset);
-               sock_array[num++] = subrec->nmb_sock;
-               *maxfd = MAX( *maxfd, subrec->nmb_sock);
-       }
 
-       /* Add in the broadcast socket on 138. */
-       FD_SET(ClientDGRAM,pset);
-       sock_array[num++] = ClientDGRAM;
-       *maxfd = MAX( *maxfd, ClientDGRAM);
+               if (subrec->nmb_sock != -1) {
+                       fds[num].fd = subrec->nmb_sock;
+                       attrs[num].type = NMB_PACKET;
+                       attrs[num].broadcast = false;
+                       num += 1;
+               }
 
-       /* Add in the 138 sockets on all the interfaces. */
-       for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
-               FD_SET(subrec->dgram_sock,pset);
-               sock_array[num++] = subrec->dgram_sock;
-               *maxfd = MAX( *maxfd, subrec->dgram_sock);
+               if (subrec->nmb_bcast != -1) {
+                       fds[num].fd = subrec->nmb_bcast;
+                       attrs[num].type = NMB_PACKET;
+                       attrs[num].broadcast = true;
+                       num += 1;
+               }
+
+               if (subrec->dgram_sock != -1) {
+                       fds[num].fd = subrec->dgram_sock;
+                       attrs[num].type = DGRAM_PACKET;
+                       attrs[num].broadcast = false;
+                       num += 1;
+               }
+
+               if (subrec->dgram_bcast != -1) {
+                       fds[num].fd = subrec->dgram_bcast;
+                       attrs[num].type = DGRAM_PACKET;
+                       attrs[num].broadcast = true;
+                       num += 1;
+               }
        }
 
-       *listen_number = (count*2) + 2;
+       TALLOC_FREE(*pfds);
+       *pfds = fds;
 
-       SAFE_FREE(*ppset);
-       SAFE_FREE(*psock_array);
+       TALLOC_FREE(*pattrs);
+       *pattrs = attrs;
 
-       *ppset = pset;
-       *psock_array = sock_array;
+       *pnum_sockets = count;
 
        return False;
 }
 
+/****************************************************************************
+ List of packets we're processing this select.
+***************************************************************************/
+
+struct processed_packet {
+       struct processed_packet *next;
+       struct processed_packet *prev;
+       enum packet_type packet_type;
+       struct in_addr ip;
+       int packet_id;
+};
+
+/****************************************************************************
+ Have we seen this before ?
+***************************************************************************/
+
+static bool is_processed_packet(struct processed_packet *processed_packet_list,
+                               struct packet_struct *packet)
+{
+       struct processed_packet *p = NULL;
+
+       for (p = processed_packet_list; p; p = p->next) {
+               if (ip_equal_v4(p->ip, packet->ip) && p->packet_type == packet->packet_type) {
+                       if ((p->packet_type == NMB_PACKET) &&
+                               (p->packet_id ==
+                                       packet->packet.nmb.header.name_trn_id)) {
+                               return true;
+                       } else if ((p->packet_type == DGRAM_PACKET) &&
+                               (p->packet_id ==
+                                       packet->packet.dgram.header.dgm_id)) {
+                               return true;
+                       }
+               }
+       }
+       return false;
+}
+
+/****************************************************************************
+ Keep a list of what we've seen before.
+***************************************************************************/
+
+static bool store_processed_packet(struct processed_packet **pp_processed_packet_list,
+                               struct packet_struct *packet)
+{
+       struct processed_packet *p = SMB_MALLOC_P(struct processed_packet);
+       if (!p) {
+               return false;
+       }
+       p->packet_type = packet->packet_type;
+       p->ip = packet->ip;
+       if (packet->packet_type == NMB_PACKET) {
+               p->packet_id = packet->packet.nmb.header.name_trn_id;
+       } else if (packet->packet_type == DGRAM_PACKET) {
+               p->packet_id = packet->packet.dgram.header.dgm_id;
+       } else {
+               SAFE_FREE(p);
+               return false;
+       }
+
+       DLIST_ADD(*pp_processed_packet_list, p);
+       return true;
+}
+
+/****************************************************************************
+ Throw away what we've seen before.
+***************************************************************************/
+
+static void free_processed_packet_list(struct processed_packet **pp_processed_packet_list)
+{
+       struct processed_packet *p = NULL, *next = NULL;
+
+       for (p = *pp_processed_packet_list; p; p = next) {
+               next = p->next;
+               DLIST_REMOVE(*pp_processed_packet_list, p);
+               SAFE_FREE(p);
+       }
+}
+
 /****************************************************************************
   Listens for NMB or DGRAM packets, and queues them.
   return True if the socket is dead
 ***************************************************************************/
 
-BOOL listen_for_packets(BOOL run_election)
+bool listen_for_packets(struct messaging_context *msg, bool run_election)
 {
-       static fd_set *listen_set = NULL;
+       static struct pollfd *fds = NULL;
+       static struct socket_attributes *attrs = NULL;
        static int listen_number = 0;
-       static int *sock_array = NULL;
+       int num_sockets;
        int i;
-       static int maxfd = 0;
 
-       fd_set r_fds;
-       fd_set w_fds;
-       int selrtn;
-       struct timeval timeout;
+       int pollrtn;
+       int timeout;
 #ifndef SYNC_DNS
        int dns_fd;
+       int dns_pollidx = -1;
 #endif
+       struct processed_packet *processed_packet_list = NULL;
 
-       if(listen_set == NULL || rescan_listen_set) {
-               if(create_listen_fdset(&listen_set, &sock_array, &listen_number, &maxfd)) {
+       if ((fds == NULL) || rescan_listen_set) {
+               if (create_listen_pollfds(&fds, &attrs, &listen_number)) {
                        DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
                        return True;
                }
                rescan_listen_set = False;
        }
 
-       memcpy((char *)&r_fds, (char *)listen_set, sizeof(fd_set));
-       FD_ZERO(&w_fds);
+       /*
+        * "fds" can be enlarged by event_add_to_poll_args
+        * below. Shrink it again to what was given to us by
+        * create_listen_pollfds.
+        */
+
+       fds = talloc_realloc(NULL, fds, struct pollfd, listen_number);
+       if (fds == NULL) {
+               return true;
+       }
+       num_sockets = listen_number;
 
 #ifndef SYNC_DNS
        dns_fd = asyncdns_fd();
        if (dns_fd != -1) {
-               FD_SET(dns_fd, &r_fds);
-               maxfd = MAX( maxfd, dns_fd);
+               fds = talloc_realloc(NULL, fds, struct pollfd, num_sockets+1);
+               if (fds == NULL) {
+                       return true;
+               }
+               dns_pollidx = num_sockets;
+               fds[num_sockets].fd = dns_fd;
+               num_sockets += 1;
        }
 #endif
 
+       for (i=0; i<num_sockets; i++) {
+               fds[i].events = POLLIN|POLLHUP;
+       }
+
+       /* Process a signal and timer events now... */
+       if (run_events_poll(nmbd_event_context(), 0, NULL, 0)) {
+               return False;
+       }
+
        /*
         * During elections and when expecting a netbios response packet we
         * need to send election packets at tighter intervals.
@@ -1771,102 +1933,113 @@ BOOL listen_for_packets(BOOL run_election)
         * the time we are expecting the next netbios packet.
         */
 
-       timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
-       timeout.tv_usec = 0;
-
-       {
-               struct timeval now = timeval_current();
-               event_add_to_select_args(nmbd_event_context(), &now,
-                                        &r_fds, &w_fds, &timeout, &maxfd);
-       }
-
-       if (timeval_is_zero(&timeout)) {
-               /* Process a timed event now... */
-               if (run_events(nmbd_event_context(), 0, NULL, NULL)) {
-                       return False;
-               }
-       }
-
-       /* Prepare for the select - allow certain signals. */
-
-       BlockSignals(False, SIGTERM);
-
-       selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&timeout);
+       timeout = ((run_election||num_response_packets)
+                  ? 1 : NMBD_SELECT_LOOP) * 1000;
 
-       /* We can only take signals when we are in the select - block them again here. */
+       event_add_to_poll_args(nmbd_event_context(), NULL,
+                              &fds, &num_sockets, &timeout);
 
-       BlockSignals(True, SIGTERM);
+       pollrtn = poll(fds, num_sockets, timeout);
 
-       if(selrtn == -1) {
+       if (run_events_poll(nmbd_event_context(), pollrtn, fds, num_sockets)) {
                return False;
        }
 
-       if (run_events(nmbd_event_context(), selrtn, &r_fds, &w_fds)) {
+       if (pollrtn == -1) {
                return False;
        }
 
 #ifndef SYNC_DNS
-       if (dns_fd != -1 && FD_ISSET(dns_fd,&r_fds)) {
-               run_dns_queue();
+       if ((dns_fd != -1) && (dns_pollidx != -1) &&
+           (fds[dns_pollidx].revents & (POLLIN|POLLHUP|POLLERR))) {
+               run_dns_queue(msg);
        }
 #endif
 
        for(i = 0; i < listen_number; i++) {
-               if (i < (listen_number/2)) {
-                       /* Processing a 137 socket. */
-                       if (FD_ISSET(sock_array[i],&r_fds)) {
-                               struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
-                               if (packet) {
-                                       /*
-                                        * If we got a packet on the broadcast socket and interfaces
-                                        * only is set then check it came from one of our local nets. 
-                                        */
-                                       if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) && 
-                                                               (!is_local_net_v4(packet->ip))) {
-                                               DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
-                                                       inet_ntoa(packet->ip),packet->port));     
-                                               free_packet(packet);
-                                       } else if ((is_loopback_ip_v4(packet->ip) || 
-                                                               ismyip_v4(packet->ip)) && packet->port == global_nmb_port &&
-                                                               packet->packet.nmb.header.nm_flags.bcast) {
-                                               DEBUG(7,("discarding own bcast packet from %s:%d\n",
-                                                       inet_ntoa(packet->ip),packet->port));     
-                                               free_packet(packet);
-                                       } else {
-                                               /* Save the file descriptor this packet came in on. */
-                                               packet->fd = sock_array[i];
-                                               queue_packet(packet);
-                                       }
-                               }
-                       }
+               enum packet_type packet_type;
+               struct packet_struct *packet;
+               const char *packet_name;
+               int client_fd;
+               int client_port;
+
+               if ((fds[i].revents & (POLLIN|POLLHUP|POLLERR)) == 0) {
+                       continue;
+               }
+
+               if (attrs[i].type == NMB_PACKET) {
+                       /* Port 137 */
+                       packet_type = NMB_PACKET;
+                       packet_name = "nmb";
+                       client_fd = ClientNMB;
+                       client_port = global_nmb_port;
                } else {
-                       /* Processing a 138 socket. */
-                               if (FD_ISSET(sock_array[i],&r_fds)) {
-                               struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
-                               if (packet) {
-                                       /*
-                                        * If we got a packet on the broadcast socket and interfaces
-                                        * only is set then check it came from one of our local nets. 
-                                        */
-                                       if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) && 
-                                                               (!is_local_net_v4(packet->ip))) {
-                                               DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
-                                               inet_ntoa(packet->ip),packet->port));     
-                                               free_packet(packet);
-                                       } else if ((is_loopback_ip_v4(packet->ip) || 
-                                                       ismyip_v4(packet->ip)) && packet->port == DGRAM_PORT) {
-                                               DEBUG(7,("discarding own dgram packet from %s:%d\n",
-                                                       inet_ntoa(packet->ip),packet->port));     
-                                               free_packet(packet);
-                                       } else {
-                                               /* Save the file descriptor this packet came in on. */
-                                               packet->fd = sock_array[i];
-                                               queue_packet(packet);
-                                       }
+                       /* Port 138 */
+                       packet_type = DGRAM_PACKET;
+                       packet_name = "dgram";
+                       client_fd = ClientDGRAM;
+                       client_port = DGRAM_PORT;
+               }
+
+               packet = read_packet(fds[i].fd, packet_type);
+               if (!packet) {
+                       continue;
+               }
+
+               /*
+                * If we got a packet on the broadcast socket and interfaces
+                * only is set then check it came from one of our local nets.
+                */
+               if (lp_bind_interfaces_only() &&
+                   (fds[i].fd == client_fd) &&
+                   (!is_local_net_v4(packet->ip))) {
+                       DEBUG(7,("discarding %s packet sent to broadcast socket from %s:%d\n",
+                               packet_name, inet_ntoa(packet->ip), packet->port));
+                       free_packet(packet);
+                       continue;
+               }
+
+               if (!IS_DC) {
+                       if ((is_loopback_ip_v4(packet->ip) || ismyip_v4(packet->ip)) &&
+                       packet->port == client_port)
+                       {
+                               if (client_port == DGRAM_PORT) {
+                                       DEBUG(7,("discarding own dgram packet from %s:%d\n",
+                                               inet_ntoa(packet->ip),packet->port));
+                                       free_packet(packet);
+                                       continue;
+                               }
+
+                               if (packet->packet.nmb.header.nm_flags.bcast) {
+                                       DEBUG(7,("discarding own nmb bcast packet from %s:%d\n",
+                                               inet_ntoa(packet->ip),packet->port));
+                                       free_packet(packet);
+                                       continue;
                                }
                        }
-               } /* end processing 138 socket. */
-       } /* end for */
+               }
+
+               if (is_processed_packet(processed_packet_list, packet)) {
+                       DEBUG(7,("discarding duplicate packet from %s:%d\n",
+                               inet_ntoa(packet->ip),packet->port));
+                       free_packet(packet);
+                       continue;
+               }
+
+               store_processed_packet(&processed_packet_list, packet);
+
+               if (attrs[i].broadcast) {
+                       /* this is a broadcast socket */
+                       packet->send_fd = fds[i-1].fd;
+               } else {
+                       /* this is already a unicast socket */
+                       packet->send_fd = fds[i].fd;
+               }
+
+               queue_packet(packet);
+       }
+
+       free_processed_packet_list(&processed_packet_list);
        return False;
 }
 
@@ -1874,13 +2047,13 @@ BOOL listen_for_packets(BOOL run_election)
   Construct and send a netbios DGRAM.
 **************************************************************************/
 
-BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
+bool send_mailslot(bool unique, const char *mailslot,char *buf, size_t len,
                    const char *srcname, int src_type,
                    const char *dstname, int dest_type,
                    struct in_addr dest_ip,struct in_addr src_ip,
                   int dest_port)
 {
-       BOOL loopback_this_packet = False;
+       bool loopback_this_packet = False;
        struct packet_struct p;
        struct dgram_packet *dgram = &p.packet.dgram;
        char *ptr,*p2;
@@ -1912,7 +2085,13 @@ BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
        /* Setup the smb part. */
        ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
        memcpy(tmp,ptr,4);
-       set_message(ptr,17,strlen(mailslot) + 1 + len,True);
+
+       if (smb_size + 17*2 + strlen(mailslot) + 1 + len > MAX_DGRAM_SIZE) {
+               DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
+               return false;
+       }
+
+       cli_set_message(ptr,17,strlen(mailslot) + 1 + len,True);
        memcpy(ptr,tmp,4);
 
        SCVAL(ptr,smb_com,SMBtrans);
@@ -1924,14 +2103,16 @@ BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
        SSVAL(ptr,smb_vwv15,1);
        SSVAL(ptr,smb_vwv16,2);
        p2 = smb_buf(ptr);
-       safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
+       strlcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
        p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2);
 
        if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
                DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
                return False;
        } else {
-               memcpy(p2,buf,len);
+               if (len) {
+                       memcpy(p2,buf,len);
+               }
                p2 += len;
        }
 
@@ -1939,7 +2120,8 @@ BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
 
        p.ip = dest_ip;
        p.port = dest_port;
-       p.fd = find_subnet_mailslot_fd_for_address( src_ip );
+       p.recv_fd = -1;
+       p.send_fd = find_subnet_mailslot_fd_for_address( src_ip );
        p.timestamp = time(NULL);
        p.packet_type = DGRAM_PACKET;