2 Unix SMB/Netbios implementation.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1995
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.
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.
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.
23 14 jan 96: lkcl@pires.co.uk
24 added multiple workgroup domain master support
31 extern int ClientDGRAM;
33 #define TEST_CODE /* want to debug unknown browse packets */
35 extern int DEBUGLEVEL;
37 extern BOOL CanRecurse;
39 extern pstring myname;
42 extern int ClientDGRAM;
44 extern struct in_addr ipzero;
46 extern int workgroup_count; /* total number of workgroups we know about */
48 /* this is our browse cache database */
49 extern struct browse_cache_record *browserlist;
51 /* this is our domain/workgroup/server database */
52 extern struct subnet_record *subnetlist;
54 /* machine comment for host announcements */
55 extern pstring ServerComment;
57 extern int updatecount;
59 /* what server type are we currently */
60 #define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
61 SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX |\
62 SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
64 /* backup request types: which servers are to be included */
65 #define MASTER_TYPE (SV_TYPE_MASTER_BROWSER)
66 #define DOMCTL_TYPE (SV_TYPE_DOMAIN_CTRL )
68 extern time_t StartupTime;
70 #define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
71 #define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
73 #define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
75 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
78 /****************************************************************************
79 tell a server to become a backup browser
80 state - 0x01 become backup instead of master
81 - 0x02 remove all entries in browse list and become non-master
82 - 0x04 stop master browser service altogether. NT ignores this
83 **************************************************************************/
84 void reset_server(char *name, int state, struct in_addr ip)
89 bzero(outbuf,sizeof(outbuf));
92 CVAL(p,0) = ANN_ResetBrowserState;
96 DEBUG(2,("sending reset to %s %s of state %d\n",
97 name,inet_ntoa(ip),state));
99 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
100 myname,name,0x20,0x1d,ip,*iface_ip(ip));
104 /****************************************************************************
105 tell a server to become a backup browser
106 **************************************************************************/
107 void tell_become_backup(void)
109 struct subnet_record *d;
110 for (d = subnetlist; d; d = d->next)
112 struct work_record *work;
113 for (work = d->workgrouplist; work; work = work->next)
115 struct server_record *s;
119 for (s = work->serverlist; s; s = s->next)
121 if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
125 if (strequal(myname, s->serv.name)) continue;
127 if (s->serv.type & SV_TYPE_BACKUP_BROWSER) {
132 if (s->serv.type & SV_TYPE_MASTER_BROWSER) continue;
134 if (!(s->serv.type & SV_TYPE_POTENTIAL_BROWSER)) continue;
136 DEBUG(3,("num servers: %d num backups: %d\n",
137 num_servers, num_backups));
139 /* make first server a backup server. thereafter make every
140 tenth server a backup server */
141 if (num_backups != 0 && (num_servers+9) / num_backups > 10)
146 DEBUG(2,("sending become backup to %s %s for %s\n",
147 s->serv.name, inet_ntoa(d->bcast_ip),
150 /* type 11 request from MYNAME(20) to WG(1e) for SERVER */
151 do_announce_request(s->serv.name, work->work_group,
152 ANN_BecomeBackup, 0x20, 0x1e, d->bcast_ip);
158 /****************************************************************************
159 find a server responsible for a workgroup, and sync browse lists
160 **************************************************************************/
161 static BOOL sync_browse_entry(struct browse_cache_record *b)
163 struct subnet_record *d;
164 struct work_record *work;
166 if (!strequal(serv_name, b->name))
168 DEBUG(0, ("browser's netbios name (%s) does not match %s (%s)",
169 b->name, inet_ntoa(b->ip), serv_name));
172 if (!(d = find_domain(b->ip))) return False;
173 if (!(work = find_workgroupstruct(d, b->group, False))) return False;
175 if (AM_MASTER(work)) {
176 /* only try to sync browse lists if we are the master, otherwise
177 the net could get a little bit too busy */
178 sync_browse_lists(work,b->name,0x20,b->ip);
186 /****************************************************************************
187 search through browser list for an entry to sync with
188 **************************************************************************/
189 void do_browser_lists(void)
191 struct browse_cache_record *b;
192 static time_t last = 0;
193 time_t t = time(NULL);
195 if (t-last < 20) return; /* don't do too many of these at once! */
199 /* pick any entry in the list, preferably one whose time is up */
200 for (b = browserlist; b && b->next; b = b->next)
202 if (b->sync_time < t && b->synced == False) break;
205 if (!b || b->synced || sync_browse_entry(b))
207 /* leave entries (even ones already sync'd) for up to a minute.
208 this stops them getting re-sync'd too often */
209 expire_browse_cache(t - 60);
214 /****************************************************************************
215 find a server responsible for a workgroup, and sync browse lists
216 control ends up back here via response_name_query.
217 **************************************************************************/
218 void sync_server(enum cmd_type cmd, char *serv_name, char *work_name,
222 add_browser_entry(serv_name, name_type, work_name, 0, ip);
224 if (cmd == MASTER_SERVER_CHECK)
226 /* announce ourselves as a master browser to serv_name */
227 do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
233 /****************************************************************************
234 update workgroup database from a name registration
235 **************************************************************************/
236 void update_from_reg(char *name, int type, struct in_addr ip)
238 /* default server type: minimum guess at requirement XXXX */
240 DEBUG(3,("update from registration: host %s ip %s type %0x\n",
241 name, inet_ntoa(ip), type));
243 /* workgroup types, but not a chat type */
244 if (type >= 0x1b && type <= 0x1e)
246 struct work_record *work;
247 struct subnet_record *d;
249 if (!(d = find_domain(ip))) return;
250 if (!(work = find_workgroupstruct(d, name, False))) return;
252 /* request the server to announce if on our subnet */
253 if (d->my_interface) announce_request(work, ip);
255 /* domain master type or master browser type */
256 if (type == 0x1b || type == 0x1d)
258 struct hostent *hp = gethostbyaddr((char*)&ip, sizeof(ip), AF_INET);
260 /* gethostbyaddr name may not match netbios name but who cares */
261 add_browser_entry(hp->h_name, type, work->work_group, 120, ip);
268 /****************************************************************************
269 add the default workgroup into my domain
270 **************************************************************************/
271 void add_my_domains(char *group)
276 if (*group == '*') return;
282 add_subnet_entry(*iface_bcast(*ip),*iface_nmask(*ip),lp_workgroup(),True);
287 /****************************************************************************
288 send a backup list response.
289 **************************************************************************/
290 static void send_backup_list(char *work_name, struct nmb_name *src_name,
291 int info_count, int token, int info,
292 int name_type, struct in_addr ip)
294 struct subnet_record *d;
296 char *p, *countptr, *nameptr;
299 char *theirname = src_name->name;
301 DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n",
302 work_name, inet_ntoa(ip),
303 myname,0x20,theirname,0x0));
305 if (name_type == 0x1d)
307 DEBUG(4,("master browsers: "));
309 else if (name_type == 0x1b)
311 DEBUG(4,("domain controllers: "));
315 DEBUG(0,("backup request for unknown type %0x\n", name_type));
319 bzero(outbuf,sizeof(outbuf));
322 CVAL(p,0) = 10; /* backup list response */
325 countptr = p; /* count pointer */
327 SSVAL(p,1,token); /* sender's workgroup index representation */
328 SSVAL(p,3,info); /* XXXX clueless: info, usually zero */
333 for (d = subnetlist; d; d = d->next)
335 struct work_record *work;
337 for (work = d->workgrouplist; work; work = work->next)
339 struct server_record *s;
341 if (!strequal(work->work_group, work_name)) continue;
343 for (s = work->serverlist; s; s = s->next)
348 if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
350 for (n = nameptr; n < p; n = skip_string(n, 1))
352 if (strequal(n, s->serv.name)) found = True;
355 if (found) continue; /* exclude names already added */
357 /* workgroup request: include all backup browsers in the list */
358 /* domain request: include all domain members in the list */
360 if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
361 (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
363 DEBUG(4, ("%s ", s->serv.name));
366 strcpy(p,s->serv.name);
368 p = skip_string(p,1);
376 DEBUG(4, ("none\n"));
381 DEBUG(4, (" - count %d\n", count));
384 CVAL(countptr,0) = count; /* total number of backup browsers found */
387 int len = PTR_DIFF(p, outbuf);
389 for (i = 0; i < len; i+= 16)
391 DEBUG(4, ("%3x char ", i));
393 for (j = 0; j < 16; j++)
395 unsigned char x = outbuf[i+j];
396 if (x < 32 || x > 127) x = '.';
398 if (i+j >= len) break;
402 DEBUG(4, (" hex ", i));
404 for (j = 0; j < 16; j++)
406 if (i+j >= len) break;
407 DEBUG(4, (" %02x", outbuf[i+j]));
414 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
415 myname,theirname,0x20,0,ip,*iface_ip(ip));
419 /*******************************************************************
420 same context: scope. should check name_type as well, and makes sure
421 we don't process messages from ourselves
422 ******************************************************************/
423 BOOL same_context(struct dgram_packet *dgram)
425 if (!strequal(dgram->dest_name .scope,scope )) return(True);
426 if ( strequal(dgram->source_name.name ,myname)) return(True);
432 /*******************************************************************
433 am I listening on a name. XXXX check the type of name as well.
434 ******************************************************************/
435 BOOL listening_name(struct work_record *work, struct nmb_name *n)
437 if (strequal(n->name,myname) ||
438 strequal(n->name,work->work_group) ||
439 strequal(n->name,MSBROWSE))
448 /*******************************************************************
449 process a domain announcement frame
451 Announce frames come in 3 types. Servers send host announcements
452 (command=1) to let the master browswer know they are
453 available. Master browsers send local master announcements
454 (command=15) to let other masters and backups that they are the
455 master. They also send domain announcements (command=12) to register
458 The comment field of domain announcements contains the master
459 browser name. The servertype is used by NetServerEnum to select
460 resources. We just have to pass it to smbd (via browser.dat) and let
461 the client choose using bit masks.
462 ******************************************************************/
463 static void process_announce(struct packet_struct *p,int command,char *buf)
465 struct dgram_packet *dgram = &p->packet.dgram;
466 struct in_addr ip = dgram->header.source_ip;
467 struct subnet_record *d = find_domain(ip);
468 int update_count = CVAL(buf,0);
469 int ttl = IVAL(buf,1)/1000;
471 int osmajor=CVAL(buf,21);
472 int osminor=CVAL(buf,22);
473 uint32 servertype = IVAL(buf,23);
474 char *comment = buf+31;
475 struct work_record *work;
477 char *serv_name = dgram->source_name.name;
482 DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15]));
483 DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
484 namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
485 servertype,comment));
489 if (dgram->dest_name.name_type == 0 && command == ANN_HostAnnouncement)
491 DEBUG(2,("Announce to nametype(0) not supported yet\n"));
495 if (command == ANN_DomainAnnouncement &&
496 ((!strequal(dgram->dest_name.name, MSBROWSE)) ||
497 dgram->dest_name.name_type != 0x1))
499 DEBUG(0,("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n",
500 command, inet_ntoa(ip), namestr(&dgram->dest_name)));
504 if (same_context(dgram)) return;
506 if (command == ANN_DomainAnnouncement) {
509 work_name = dgram->dest_name.name;
512 /* we need some way of finding out about new workgroups
513 that appear to be sending packets to us. The name_type checks make
514 sure we don't add host names as workgroups */
515 if (command == ANN_HostAnnouncement &&
516 (dgram->dest_name.name_type == 0x1d ||
517 dgram->dest_name.name_type == 0x1e))
520 if (!(work = find_workgroupstruct(d, work_name,add)))
523 DEBUG(4, ("workgroup %s on %s\n", work->work_group, serv_name));
527 /* add them to our browse list */
528 add_server_entry(d,work,name,servertype,ttl,comment,True);
531 /* the tell become backup code is broken, no great harm is done by
533 tell_become_backup();
536 /* get their browse list from them and add it to ours. */
537 add_browser_entry(serv_name,dgram->dest_name.name_type,
538 work->work_group,30,ip);
541 /*******************************************************************
542 process a master announcement frame
543 ******************************************************************/
544 static void process_master_announce(struct packet_struct *p,char *buf)
546 struct dgram_packet *dgram = &p->packet.dgram;
547 struct in_addr ip = dgram->header.source_ip;
548 struct subnet_record *d = find_domain(ip);
549 struct subnet_record *mydomain = find_domain(*iface_bcast(ip));
551 struct work_record *work;
554 DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(ip)));
556 if (same_context(dgram)) return;
558 if (!d || !mydomain) return;
560 if (!lp_domain_master()) return;
562 for (work = mydomain->workgrouplist; work; work = work->next)
566 /* merge browse lists with them */
567 add_browser_entry(name,0x1b, work->work_group,30,ip);
572 /*******************************************************************
573 process a receive backup list request
575 we receive a list of servers, and we attempt to locate them all on
576 our local subnet, and sync browse lists with them on the workgroup
577 they are said to be in.
578 ******************************************************************/
579 static void process_rcv_backup_list(struct packet_struct *p,char *buf)
581 struct dgram_packet *dgram = &p->packet.dgram;
582 struct in_addr ip = dgram->header.source_ip;
583 int count = CVAL(buf,0);
584 int Index = IVAL(buf,1); /* caller's index representing workgroup */
587 DEBUG(3,("Receive Backup ack for %s from %s total=%d index=%d\n",
588 namestr(&dgram->dest_name), inet_ntoa(ip),
591 if (same_context(dgram)) return;
593 if (count <= 0) return;
595 /* go through the list of servers attempting to sync browse lists */
596 for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
598 struct in_addr back_ip;
599 struct subnet_record *d;
601 DEBUG(4,("Searching for backup browser %s at %s...\n",
602 buf1, inet_ntoa(ip)));
604 /* XXXX assume name is a DNS name NOT a netbios name. a more complete
605 approach is to use reply_name_query functionality to find the name */
606 back_ip = *interpret_addr2(buf1);
608 if (zero_ip(back_ip))
610 DEBUG(4,("Failed to find backup browser server using DNS\n"));
614 DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
616 if ((d = find_domain(back_ip)))
618 struct subnet_record *d1;
619 for (d1 = subnetlist; d1; d1 = d1->next)
621 struct work_record *work;
622 for (work = d1->workgrouplist; work; work = work->next)
624 if (work->token == Index)
626 queue_netbios_packet(ClientNMB,NMB_QUERY,SERVER_CHECK,
627 work->work_group,0x1d,0,
628 False,False,back_ip);
637 /*******************************************************************
638 process a send backup list request
640 A client send a backup list request to ask for a list of servers on
641 the net that maintain server lists for a domain. A server is then
642 chosen from this list to send NetServerEnum commands to to list
645 Currently samba only sends back one name in the backup list, its
646 own. For larger nets we'll have to add backups and send "become
647 backup" requests occasionally.
648 ******************************************************************/
649 static void process_send_backup_list(struct packet_struct *p,char *buf)
651 struct dgram_packet *dgram = &p->packet.dgram;
652 struct in_addr ip = dgram->header.source_ip;
653 struct subnet_record *d;
654 struct work_record *work;
656 int count = CVAL(buf,0);
657 int token = SVAL(buf,1); /* sender's key index for the workgroup? */
658 int info = SVAL(buf,3); /* XXXX don't know: some sort of info */
659 int name_type = dgram->dest_name.name_type;
661 if (same_context(dgram)) return;
663 if (count <= 0) return;
665 if (name_type != 0x1b && name_type != 0x1d) {
666 DEBUG(0,("backup request to wrong type %d from %s\n",
667 name_type,inet_ntoa(ip)));
671 for (d = subnetlist; d; d = d->next)
673 for (work = d->workgrouplist; work; work = work->next)
675 if (strequal(work->work_group, dgram->dest_name.name))
677 DEBUG(2,("sending backup list to %s %s count=%d\n",
678 namestr(&dgram->dest_name),inet_ntoa(ip),count));
680 send_backup_list(work->work_group,&dgram->source_name,
681 count,token,info,name_type,ip);
689 /*******************************************************************
690 process a reset browser state
693 0x1 - stop being a master browser
694 0x2 - discard browse lists, stop being a master browser, try again.
695 0x4 - stop being a master browser forever. no way. ain't gonna.
697 ******************************************************************/
698 static void process_reset_browser(struct packet_struct *p,char *buf)
700 struct dgram_packet *dgram = &p->packet.dgram;
701 int state = CVAL(buf,0);
703 DEBUG(1,("received diagnostic browser reset request to %s state=0x%X\n",
704 namestr(&dgram->dest_name), state));
706 /* stop being a master but still deal with being a backup browser */
709 struct subnet_record *d;
710 for (d = subnetlist; d; d = d->next)
712 struct work_record *work;
713 for (work = d->workgrouplist; work; work = work->next)
717 become_nonmaster(d,work);
723 /* totally delete all servers and start afresh */
726 struct subnet_record *d;
727 for (d = subnetlist; d; d = d->next)
729 struct work_record *work;
730 for (work=d->workgrouplist;work;work=remove_workgroup(d,work));
732 add_my_domains(lp_workgroup());
735 /* stop browsing altogether. i don't think this is a good idea! */
738 DEBUG(1,("ignoring request to stop being a browser. sorry!\n"));
743 /*******************************************************************
744 process a announcement request
746 clients send these when they want everyone to send an announcement
747 immediately. This can cause quite a storm of packets!
748 ******************************************************************/
749 static void process_announce_request(struct packet_struct *p,char *buf)
751 struct dgram_packet *dgram = &p->packet.dgram;
752 struct work_record *work;
753 struct in_addr ip = dgram->header.source_ip;
754 struct subnet_record *d = find_domain(ip);
755 int token = CVAL(buf,0);
760 DEBUG(3,("Announce request from %s to %s token=0x%X\n",
761 name,namestr(&dgram->dest_name), token));
763 if (strequal(dgram->source_name.name,myname)) return;
767 if (!d->my_interface) return;
769 for (work = d->workgrouplist; work; work = work->next)
771 if (strequal(dgram->dest_name.name,work->work_group))
773 work->needannounce = True;
779 /****************************************************************************
780 process a domain logon packet
781 **************************************************************************/
782 void process_logon_packet(struct packet_struct *p,char *buf,int len)
784 struct dgram_packet *dgram = &p->packet.dgram;
785 struct in_addr ip = dgram->header.source_ip;
786 struct subnet_record *d = find_domain(ip);
789 BOOL add_slashes = False;
792 struct work_record *work;
796 if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False)))
799 if (!lp_domain_logons()) {
800 DEBUG(3,("No domain logons\n"));
803 if (!listening_name(work, &dgram->dest_name))
805 DEBUG(4,("Not listening to that domain\n"));
813 char *machine = buf+2;
814 char *user = skip_string(machine,1);
815 logname = skip_string(user,1);
819 DEBUG(3,("Domain login request from %s(%s) user=%s\n",
820 machine,inet_ntoa(p->ip),user));
825 char *machine = buf+2;
826 logname = skip_string(machine,1);
828 reply_name = lp_domain_controller();
830 DEBUG(3,("No domain controller configured\n"));
833 DEBUG(3,("GETDC request from %s(%s)\n",
834 machine,inet_ntoa(p->ip)));
838 DEBUG(3,("Unknown domain request %d\n",code));
842 bzero(outbuf,sizeof(outbuf));
844 SSVAL(q,0,reply_code);
850 StrnCpy(q,reply_name,16);
852 q = skip_string(q,1);
856 send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
857 myname,&dgram->source_name.name[0],0x20,0,p->ip,
862 /****************************************************************************
863 depending on what announce has been made, we are only going to
864 accept certain types of name announce. XXXX untested code
866 check listening name type
867 ****************************************************************************/
868 BOOL listening_type(struct packet_struct *p, int command)
870 struct dgram_packet *dgram = &p->packet.dgram;
871 int type = dgram->dest_name.name_type;
875 case ANN_HostAnnouncement:
877 if (type != 0x0 || type != 0x20) return (False);
881 case ANN_AnnouncementRequest:
893 case ANN_GetBackupListReq:
899 case ANN_GetBackupListResp:
905 case ANN_DomainAnnouncement:
907 if (type != 0x1b || type != 0x1c) return (False);
911 case ANN_MasterAnnouncement:
913 if (type != 0x1d) return (False);
917 case ANN_LocalMasterAnnouncement:
919 if (type != 0x1c || type != 0x1d) return (False);
923 return (True); /* we're not dealing with unknown packet types */
927 /****************************************************************************
928 process a browse frame
929 ****************************************************************************/
930 void process_browse_packet(struct packet_struct *p,char *buf,int len)
932 int command = CVAL(buf,0);
935 case ANN_HostAnnouncement:
936 case ANN_DomainAnnouncement:
937 case ANN_LocalMasterAnnouncement:
939 process_announce(p,command,buf+1);
943 case ANN_AnnouncementRequest:
945 process_announce_request(p,buf+1);
951 process_election(p,buf+1);
955 case ANN_GetBackupListReq:
957 process_send_backup_list(p,buf+1);
961 case ANN_GetBackupListResp:
963 process_rcv_backup_list(p, buf+1);
967 case ANN_ResetBrowserState:
969 process_reset_browser(p, buf+1);
973 case ANN_MasterAnnouncement:
975 process_master_announce(p,buf+1);
981 struct dgram_packet *dgram = &p->packet.dgram;
982 DEBUG(4,("ignoring browse packet %d from %s %s to %s\n",
983 command, namestr(&dgram->source_name),
984 inet_ntoa(p->ip), namestr(&dgram->dest_name)));
990 /****************************************************************************
991 process udp 138 datagrams
992 ****************************************************************************/
993 void process_dgram(struct packet_struct *p)
998 struct dgram_packet *dgram = &p->packet.dgram;
1000 if (dgram->header.msg_type != 0x10 &&
1001 dgram->header.msg_type != 0x11 &&
1002 dgram->header.msg_type != 0x12) {
1003 /* don't process error packets etc yet */
1007 buf = &dgram->data[0];
1008 buf -= 4; /* XXXX for the pseudo tcp length -
1009 someday I need to get rid of this */
1011 if (CVAL(buf,smb_com) != SMBtrans) return;
1013 len = SVAL(buf,smb_vwv11);
1014 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1016 DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
1017 namestr(&dgram->source_name),namestr(&dgram->dest_name),
1018 smb_buf(buf),CVAL(buf2,0),len));
1021 if (len <= 0) return;
1023 if (strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE"))
1025 process_browse_packet(p,buf2,len);
1026 } else if (strequal(smb_buf(buf),"\\MAILSLOT\\NET\\NETLOGON")) {
1027 process_logon_packet(p,buf2,len);