be099340c3961cc13cf24f8b23f9c7584e2344e0
[kai/samba.git] / source3 / namepacket.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines and daemon - version 2
5    Copyright (C) Andrew Tridgell 1994-1997
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21    Revision History:
22
23    14 jan 96: lkcl@pires.co.uk
24    added multiple workgroup domain master support
25
26 */
27
28 #include "includes.h"
29
30 extern int ClientNMB;
31 extern int ClientDGRAM;
32
33 extern int DEBUGLEVEL;
34
35 extern int num_response_packets;
36
37 BOOL CanRecurse = True;
38 extern pstring scope;
39 extern struct in_addr wins_ip;
40 extern struct in_addr loopback_ip;
41
42 static uint16 name_trn_id=0;
43
44
45 /***************************************************************************
46   updates the unique transaction identifier
47   **************************************************************************/
48 void debug_browse_data(char *outbuf, int len)
49 {
50     int i,j;
51     for (i = 0; i < len; i+= 16)
52       {
53         DEBUG(4, ("%3x char ", i));
54         
55         for (j = 0; j < 16; j++)
56           {
57             unsigned char x = outbuf[i+j];
58             if (x < 32 || x > 127) x = '.';
59             
60             if (i+j >= len) break;
61             DEBUG(4, ("%c", x));
62           }
63         
64         DEBUG(4, (" hex ", i));
65         
66         for (j = 0; j < 16; j++)
67           {
68             if (i+j >= len) break;
69             DEBUG(4, (" %02x", (unsigned char)outbuf[i+j]));
70           }
71         
72         DEBUG(4, ("\n"));
73       }
74     
75 }
76
77
78 /***************************************************************************
79   updates the unique transaction identifier
80   **************************************************************************/
81 static void update_name_trn_id(void)
82 {
83   if (!name_trn_id)
84   {
85     name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
86   }
87   name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
88 }
89
90
91 /****************************************************************************
92   initiate a netbios packet
93   ****************************************************************************/
94 void initiate_netbios_packet(uint16 *id,
95                              int fd,int quest_type,char *name,int name_type,
96                              int nb_flags,BOOL bcast,BOOL recurse,
97                              struct in_addr to_ip)
98 {
99   struct packet_struct p;
100   struct nmb_packet *nmb = &p.packet.nmb;
101   struct res_rec additional_rec;
102   char *packet_type = "unknown";
103   int opcode = -1;
104
105   if (!id) return;
106
107   if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
108   if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
109   if (quest_type == NMB_REG   ) { packet_type = "nmb_reg"; opcode = 5; }
110   if (quest_type == NMB_REG_REFRESH ) { packet_type = "nmb_reg_refresh"; opcode = 9; }
111   if (quest_type == NMB_REL   ) { packet_type = "nmb_rel"; opcode = 6; }
112   
113   DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
114            packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
115
116   if (opcode == -1) return;
117
118   bzero((char *)&p,sizeof(p));
119
120   if (*id == 0xffff) {
121     update_name_trn_id();
122     *id = name_trn_id; /* allow resending with same id */
123   }
124
125   nmb->header.name_trn_id = *id;
126   nmb->header.opcode = opcode;
127   nmb->header.response = False;
128
129   nmb->header.nm_flags.bcast = bcast;
130   nmb->header.nm_flags.recursion_available = False;
131   nmb->header.nm_flags.recursion_desired = recurse;
132   nmb->header.nm_flags.trunc = False;
133   nmb->header.nm_flags.authoritative = False;
134
135   nmb->header.rcode = 0;
136   nmb->header.qdcount = 1;
137   nmb->header.ancount = 0;
138   nmb->header.nscount = 0;
139   nmb->header.arcount = (quest_type==NMB_REG || 
140                          quest_type==NMB_REL ||
141                          quest_type==NMB_REG_REFRESH) ? 1 : 0;
142   
143   make_nmb_name(&nmb->question.question_name,name,name_type,scope);
144   
145   nmb->question.question_type = quest_type == NMB_STATUS ? 0x21 : 0x20;
146   nmb->question.question_class = 0x1;
147   
148   if (quest_type == NMB_REG ||
149       quest_type == NMB_REG_REFRESH ||
150       quest_type == NMB_REL)
151   {
152       nmb->additional = &additional_rec;
153       bzero((char *)nmb->additional,sizeof(*nmb->additional));
154       
155       nmb->additional->rr_name  = nmb->question.question_name;
156       nmb->additional->rr_type  = 0x20;
157       nmb->additional->rr_class = 0x1;
158       
159       if (quest_type == NMB_REG || quest_type == NMB_REG_REFRESH)
160         nmb->additional->ttl = lp_max_ttl();
161       else
162         nmb->additional->ttl = 0;
163
164       nmb->additional->rdlength = 6;
165       nmb->additional->rdata[0] = nb_flags;
166       putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
167   }
168   
169   p.ip = to_ip;
170   p.port = NMB_PORT;
171   p.fd = fd;
172   p.timestamp = time(NULL);
173   p.packet_type = NMB_PACKET;
174   p.locked = False;
175   
176   debug_nmb_packet(&p);
177   
178   if (!send_packet(&p)) {
179     DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
180     *id = 0xffff;
181   }
182   
183   return;
184 }
185
186
187 /****************************************************************************
188   reply to a netbios name packet.  see rfc1002.txt
189   ****************************************************************************/
190 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
191                                 int rcode, int rcv_code, int opcode,
192                 BOOL recursion_available,
193                 BOOL recursion_desired,
194                                 struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
195                                 char *data,int len)
196 {
197   struct packet_struct p;
198   struct nmb_packet *nmb = &p.packet.nmb;
199   struct res_rec answers;
200   char *packet_type = "unknown";
201   
202   p = *p1;
203
204   switch (rcv_code)
205   {
206     case NMB_STATUS:
207         {
208       packet_type = "nmb_status";
209       break;
210     }
211     case NMB_QUERY:
212         {
213       packet_type = "nmb_query";
214       break;
215     }
216     case NMB_REG:
217         {
218       packet_type = "nmb_reg";
219       break;
220     }
221     case NMB_REL:
222         {
223       packet_type = "nmb_rel";
224       break;
225     }
226     case NMB_WAIT_ACK:
227         {
228       packet_type = "nmb_wack";
229       break;
230     }
231     default:
232     {
233       DEBUG(1,("replying netbios packet: %s %s %s\n",
234                     packet_type, namestr(rr_name), inet_ntoa(p.ip)));
235
236       return;
237     }
238   }
239
240   DEBUG(4,("replying netbios packet: %s %s %s\n",
241            packet_type, namestr(rr_name), inet_ntoa(p.ip)));
242
243   nmb->header.name_trn_id = trn_id;
244   nmb->header.opcode = opcode;
245   nmb->header.response = True;
246   nmb->header.nm_flags.bcast = False;
247   nmb->header.nm_flags.recursion_available = recursion_available;
248   nmb->header.nm_flags.recursion_desired = recursion_desired;
249   nmb->header.nm_flags.trunc = False;
250   nmb->header.nm_flags.authoritative = True;
251   
252   nmb->header.qdcount = 0;
253   nmb->header.ancount = 1;
254   nmb->header.nscount = 0;
255   nmb->header.arcount = 0;
256   nmb->header.rcode = rcode;
257   
258   bzero((char*)&nmb->question,sizeof(nmb->question));
259   
260   nmb->answers = &answers;
261   bzero((char*)nmb->answers,sizeof(*nmb->answers));
262   
263   nmb->answers->rr_name  = *rr_name;
264   nmb->answers->rr_type  = rr_type;
265   nmb->answers->rr_class = rr_class;
266   nmb->answers->ttl      = ttl;
267   
268   if (data && len)
269     {
270       nmb->answers->rdlength = len;
271       memcpy(nmb->answers->rdata, data, len);
272     }
273   
274   p.packet_type = NMB_PACKET;
275   
276   debug_nmb_packet(&p);
277   
278   send_packet(&p);
279 }
280
281
282 /*******************************************************************
283   the global packet linked-list. incoming entries are added to the
284   end of this list.  it is supposed to remain fairly short so we
285   won't bother with an end pointer.
286   ******************************************************************/
287 static struct packet_struct *packet_queue = NULL;
288
289 /*******************************************************************
290   queue a packet into the packet queue
291   ******************************************************************/
292 void queue_packet(struct packet_struct *packet)
293 {
294   struct packet_struct *p;
295
296   if (!packet_queue) {
297     packet->prev = NULL;
298     packet->next = NULL;
299     packet_queue = packet;
300     return;
301   }
302   
303   /* find the bottom */
304   for (p=packet_queue;p->next;p=p->next) ;
305
306   p->next = packet;
307   packet->next = NULL;
308   packet->prev = p;
309 }
310
311 /****************************************************************************
312   determine if a packet is for us. Note that to have any chance of
313   being efficient we need to drop as many packets as possible at this
314   stage as subsequent processing is expensive. 
315
316   We also must make absolutely sure we don't tread on another machines
317   property by answering a packet that is not for us.
318   ****************************************************************************/
319 static BOOL listening(struct packet_struct *p,struct nmb_name *n)
320 {
321   struct subnet_record *d;
322   struct name_record *n1 = NULL;
323
324   if((d = find_subnet_all(p->ip)) != NULL)
325     n1 = find_name_on_subnet(d, n, FIND_SELF_NAME);
326
327   return (n1 != NULL);
328 }
329
330
331 /****************************************************************************
332   process udp 138 datagrams
333   ****************************************************************************/
334 static void process_dgram(struct packet_struct *p)
335 {
336   char *buf;
337   char *buf2;
338   int len;
339   struct dgram_packet *dgram = &p->packet.dgram;
340
341   /* if we aren't listening to the destination name then ignore the packet */
342   if (!listening(p,&dgram->dest_name))
343   {
344     DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%x) from %s\n",
345            dgram->dest_name.name, dgram->dest_name.name_type, inet_ntoa(p->ip)));
346     return;
347   }
348
349   if (dgram->header.msg_type != 0x10 &&
350       dgram->header.msg_type != 0x11 &&
351       dgram->header.msg_type != 0x12) 
352   {
353     /* don't process error packets etc yet */
354     DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%d) from %s as it is \
355            an error packet of type %x\n",
356            dgram->dest_name.name, dgram->dest_name.name_type, 
357            inet_ntoa(p->ip), dgram->header.msg_type));
358     return;
359   }
360
361   buf = &dgram->data[0];
362   buf -= 4; /* XXXX for the pseudo tcp length - 
363                someday I need to get rid of this */
364
365   if (CVAL(buf,smb_com) != SMBtrans) return;
366
367   len = SVAL(buf,smb_vwv11);
368   buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
369
370   DEBUG(4,("process_dgram: datagram from %s to %s(%s)for %s of type %d len=%d\n",
371            namestr(&dgram->source_name),namestr(&dgram->dest_name),
372            inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
373
374  
375   if (len <= 0) return;
376
377    /* datagram packet received for the browser mailslot */
378    if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
379      process_browse_packet(p,buf2,len);
380      return;
381    }
382
383    /* datagram packet received for the domain log on mailslot */
384    if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
385      process_logon_packet(p,buf2,len, NET_LOGON_MAILSLOT);
386      return;
387    }
388
389    /* datagram packet received for the NT domain log on mailslot */
390    if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
391      process_logon_packet(p,buf2,len, NT_LOGON_MAILSLOT);
392      return;
393    }
394 }
395
396 /****************************************************************************
397   process a nmb packet
398   ****************************************************************************/
399 static void process_nmb(struct packet_struct *p)
400 {
401   struct nmb_packet *nmb = &p->packet.nmb;
402
403   debug_nmb_packet(p);
404
405   switch (nmb->header.opcode) 
406   {
407     case 8: /* what is this?? */
408     case NMB_REG:
409     case NMB_REG_REFRESH:
410     {
411         if (nmb->header.response)
412         {
413           if (nmb->header.ancount ==0) break;
414           response_netbios_packet(p); /* response to registration dealt 
415                                          with here */
416         }
417         else
418         {
419           if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
420           reply_name_reg(p);
421         }
422         break;
423     }
424       
425     case 0:
426     {
427           if (nmb->header.response)
428           {
429             switch (nmb->question.question_type)
430               {
431               case 0x0:
432                 {
433                   response_netbios_packet(p);
434                   break;
435                 }
436               }
437             return;
438           }
439       else if (nmb->header.qdcount>0) 
440           {
441             switch (nmb->question.question_type)
442               {
443               case NMB_QUERY:
444                 {
445                   reply_name_query(p);
446                   break;
447                 }
448               case NMB_STATUS:
449                 {
450                   reply_name_status(p);
451                   break;
452                 }
453               }
454             return;
455           }
456         break;
457       }
458       
459     case NMB_REL:
460     {
461         if (nmb->header.response)
462         {
463           if (nmb->header.ancount ==0) break;
464           response_netbios_packet(p); /* response to release dealt 
465                                          with here */
466         }
467         else
468         {
469           if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
470           reply_name_release(p);
471         }
472       break;
473     }
474   }
475 }
476
477
478 /*******************************************************************
479   run elements off the packet queue till its empty
480   ******************************************************************/
481 void run_packet_queue()
482 {
483         struct packet_struct *p;
484
485         while ((p=packet_queue)) {
486                 packet_queue = p->next;
487                 if (packet_queue) packet_queue->prev = NULL;
488                 p->next = p->prev = NULL;
489
490                 switch (p->packet_type) {
491                 case NMB_PACKET:
492                         process_nmb(p);
493                         break;
494                         
495                 case DGRAM_PACKET:
496                         process_dgram(p);
497                         break;
498                 }
499                 free_packet(p);
500         }
501 }
502
503
504 /****************************************************************************
505   Create an fd_set containing all the sockets in the subnet structures,
506   plus the broadcast sockets.
507   ***************************************************************************/
508 static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number)
509 {
510   int *sock_array = NULL;
511   struct subnet_record *d = NULL;
512   int count = 0;
513   int num = 0;
514   fd_set *pset = (fd_set *)malloc(sizeof(fd_set));
515
516   if(pset == NULL)
517   {
518     DEBUG(0,("create_listen_fdset: malloc fail !\n"));
519     return True;
520   }
521
522   /* Check that we can add all the fd's we need. */
523   for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
524     count++;
525
526   if((count*2) + 2 > FD_SETSIZE)
527   {
528     DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
529 only use %d.\n", (count*2) + 2, FD_SETSIZE));
530     return True;
531   }
532
533   if((sock_array = (int *)malloc(((count*2) + 2)*sizeof(int))) == NULL)
534   {
535     DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
536     return True;
537   }
538
539   FD_ZERO(pset);
540
541   /* Add in the broadcast socket on 137. */
542   FD_SET(ClientNMB,pset);
543   sock_array[num++] = ClientNMB;
544
545   /* Add in the 137 sockets on all the interfaces. */
546   for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
547   {
548     FD_SET(d->nmb_sock,pset);
549     sock_array[num++] = d->nmb_sock;
550   }
551
552   /* Add in the broadcast socket on 138. */
553   FD_SET(ClientDGRAM,pset);
554   sock_array[num++] = ClientDGRAM;
555
556   /* Add in the 138 sockets on all the interfaces. */
557   for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
558   {
559     FD_SET(d->dgram_sock,pset);
560     sock_array[num++] = d->dgram_sock;
561   }
562
563   *listen_number = (count*2) + 2;
564   *ppset = pset;
565   *psock_array = sock_array;
566  
567   return False;
568 }
569
570 /****************************************************************************
571   listens for NMB or DGRAM packets, and queues them
572   ***************************************************************************/
573 BOOL listen_for_packets(BOOL run_election)
574 {
575   static fd_set *listen_set = NULL;
576   static int listen_number = 0;
577   static int *sock_array = NULL;
578
579   fd_set fds;
580   int selrtn;
581   struct timeval timeout;
582 #ifndef SYNC_DNS
583   int dns_fd;
584 #endif
585
586   if(listen_set == NULL)
587   {
588     if(create_listen_fdset(&listen_set, &sock_array, &listen_number))
589     {
590       DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
591       return True;
592     }
593   }
594
595   memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
596
597 #ifndef SYNC_DNS
598   dns_fd = asyncdns_fd();
599   if (dns_fd != -1) {
600           FD_SET(dns_fd, &fds);
601   }
602 #endif
603
604
605   /* during elections and when expecting a netbios response packet we
606   need to send election packets at tighter intervals 
607
608   ideally it needs to be the interval (in ms) between time now and
609   the time we are expecting the next netbios packet */
610
611   timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
612   timeout.tv_usec = 0;
613
614   /* We can only take term signals when we are in the select. */
615   BlockSignals(False, SIGTERM);
616   selrtn = sys_select(&fds,&timeout);
617   BlockSignals(True, SIGTERM);
618
619   if(selrtn > 0)
620   {
621     int i;
622
623 #ifndef SYNC_DNS
624     if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
625             run_dns_queue();
626     }
627 #endif
628
629     for(i = 0; i < listen_number; i++)
630     {
631       if(i < (listen_number/2))
632       {
633         /* Processing a 137 socket. */
634         if (FD_ISSET(sock_array[i],&fds))
635         {
636           struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
637           if (packet)
638           {
639             /*
640              * If we got a packet on the broadcast socket and interfaces
641              * only is set then check it came from one of our local nets. 
642              */
643             if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) && 
644                (!is_local_net(packet->ip)))
645             {
646               DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
647                         inet_ntoa(packet->ip),packet->port));     
648               free_packet(packet);
649             }
650             else if ((ip_equal(loopback_ip, packet->ip) || 
651               ismyip(packet->ip)) && packet->port == NMB_PORT)
652             {
653               DEBUG(7,("discarding own packet from %s:%d\n",
654                         inet_ntoa(packet->ip),packet->port));     
655               free_packet(packet);
656             }
657             else
658             {
659               queue_packet(packet);
660             }
661           }
662         }
663       }
664       else
665       {
666         /* Processing a 138 socket. */
667
668         if (FD_ISSET(sock_array[i],&fds))
669         {
670           struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
671           if (packet)
672           {
673             /*
674              * If we got a packet on the broadcast socket and interfaces
675              * only is set then check it came from one of our local nets. 
676              */
677             if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) && 
678                  (!is_local_net(packet->ip)))
679             {
680               DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
681                         inet_ntoa(packet->ip),packet->port));     
682               free_packet(packet);
683             }
684             else if ((ip_equal(loopback_ip, packet->ip) || 
685                  ismyip(packet->ip)) && packet->port == DGRAM_PORT)
686             {
687               DEBUG(7,("discarding own packet from %s:%d\n",
688                         inet_ntoa(packet->ip),packet->port));     
689               free_packet(packet);
690             }
691             else
692             {
693               queue_packet(packet);
694             }
695           }
696         }
697       } /* end processing 138 socket. */
698     } /* end for */
699   } /* end if selret > 0 */
700   return False;
701 }
702
703
704
705 /****************************************************************************
706   construct and send a netbios DGRAM
707
708   Note that this currently sends all answers to port 138. thats the
709   wrong things to do! I should send to the requestors port. XXX
710   **************************************************************************/
711 BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,char *srcname,
712                          char *dstname,int src_type,int dest_type,
713                          struct in_addr dest_ip,struct in_addr src_ip)
714 {
715   struct packet_struct p;
716   struct dgram_packet *dgram = &p.packet.dgram;
717   char *ptr,*p2;
718   char tmp[4];
719
720   /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
721   if (ip_equal(wins_ip, dest_ip)) return False;
722
723   bzero((char *)&p,sizeof(p));
724
725   update_name_trn_id();
726
727   /* DIRECT GROUP or UNIQUE datagram */
728   dgram->header.msg_type = unique ? 0x10 : 0x11; 
729   dgram->header.flags.node_type = M_NODE;
730   dgram->header.flags.first = True;
731   dgram->header.flags.more = False;
732   dgram->header.dgm_id = name_trn_id;
733   dgram->header.source_ip = src_ip;
734   dgram->header.source_port = DGRAM_PORT;
735   dgram->header.dgm_length = 0; /* let build_dgram() handle this */
736   dgram->header.packet_offset = 0;
737   
738   make_nmb_name(&dgram->source_name,srcname,src_type,scope);
739   make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
740
741   ptr = &dgram->data[0];
742
743   /* now setup the smb part */
744   ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
745   memcpy(tmp,ptr,4);
746   set_message(ptr,17,17 + len,True);
747   memcpy(ptr,tmp,4);
748
749   CVAL(ptr,smb_com) = SMBtrans;
750   SSVAL(ptr,smb_vwv1,len);
751   SSVAL(ptr,smb_vwv11,len);
752   SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
753   SSVAL(ptr,smb_vwv13,3);
754   SSVAL(ptr,smb_vwv14,1);
755   SSVAL(ptr,smb_vwv15,1);
756   SSVAL(ptr,smb_vwv16,2);
757   p2 = smb_buf(ptr);
758   strcpy(p2,mailslot);
759   p2 = skip_string(p2,1);
760
761   memcpy(p2,buf,len);
762   p2 += len;
763
764   dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
765
766   p.ip = dest_ip;
767   p.port = DGRAM_PORT;
768   p.fd = fd;
769   p.timestamp = time(NULL);
770   p.packet_type = DGRAM_PACKET;
771
772   DEBUG(4,("send mailslot %s from %s %s", mailslot,
773                     inet_ntoa(src_ip),namestr(&dgram->source_name)));
774   DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
775
776   return(send_packet(&p));
777 }