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
32 #define TEST_CODE /* want to debug unknown browse packets */
34 extern int DEBUGLEVEL;
36 extern BOOL CanRecurse;
38 extern struct in_addr myip;
39 extern struct in_addr bcast_ip;
40 extern struct in_addr Netmask;
42 extern pstring myname;
45 extern int ClientDGRAM;
47 extern int workgroup_count; /* total number of workgroups we know about */
49 /* this is our browse cache database */
50 extern struct browse_cache_record *browserlist;
52 /* this is our domain/workgroup/server database */
53 extern struct domain_record *domainlist;
55 /* machine comment for host announcements */
56 extern pstring ServerComment;
58 extern int updatecount;
60 /* what server type are we currently */
61 #define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
62 SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX |\
63 SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
65 /* backup request types: which servers are to be included */
66 #define MASTER_TYPE (SV_TYPE_MASTER_BROWSER)
67 #define DOMCTL_TYPE (SV_TYPE_DOMAIN_CTRL )
69 extern time_t StartupTime;
71 #define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
72 #define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
74 #define MSBROWSE "\001\002__MSBROWSE__\002"
75 #define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
77 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
80 /****************************************************************************
81 tell a server to become a backup browser
82 state - 0x01 become backup instead of master
83 - 0x02 remove all entries in browse list and become non-master
84 - 0x04 stop master browser service altogether. NT ignores this
85 **************************************************************************/
86 void reset_server(char *name, int state, struct in_addr ip)
91 bzero(outbuf,sizeof(outbuf));
94 CVAL(p,0) = 14; /* request reset browser state */
95 CVAL(p,2) = state; /* type of request */
98 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
99 myname,name,0x20,0x1d,ip,myip);
102 /****************************************************************************
103 tell a server to become a backup browser
104 **************************************************************************/
105 void tell_become_backup(void)
107 struct domain_record *d;
108 for (d = domainlist; d; d = d->next)
110 struct work_record *work;
111 for (work = d->workgrouplist; work; work = work->next)
113 struct server_record *s;
117 for (s = work->serverlist; s; s = s->next)
119 if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
123 if (strequal(myname, s->serv.name)) continue;
125 if (s->serv.type & SV_TYPE_BACKUP_BROWSER)
131 if (s->serv.type & SV_TYPE_MASTER_BROWSER) continue;
133 if (!(s->serv.type & SV_TYPE_POTENTIAL_BROWSER)) continue;
135 DEBUG(3,("num servers: %d num backups: %d\n",
136 num_servers, num_backups));
138 /* make first server a backup server. thereafter make every
139 tenth server a backup server */
140 if (num_backups != 0 && (num_servers+9) / num_backups > 10)
145 DEBUG(3,("workgroup %s subnet %s: make backup: %s %8x \n",
146 work->work_group, inet_ntoa(d->bcast_ip),
147 s->serv.name, s->serv.type));
149 /* type 11 request from MYNAME(20) to WG(1e) for SERVER */
150 do_announce_request(s->serv.name, work->work_group,
151 11, 0x20, 0x1e, d->bcast_ip);
157 /****************************************************************************
158 find a server responsible for a workgroup, and sync browse lists
159 **************************************************************************/
160 static BOOL sync_browse_entry(struct browse_cache_record *b)
162 struct domain_record *d;
163 struct work_record *work;
165 if (!strequal(serv_name, b->name))
167 DEBUG(0, ("browser's netbios name (%s) does not match %s (%s)",
168 b->name, inet_ntoa(b->ip), serv_name));
171 if (!(d = find_domain(b->ip))) return False;
172 if (!(work = find_workgroupstruct(d, b->group, False))) return False;
174 sync_browse_lists(work,b->name,0x20,b->ip);
181 /****************************************************************************
182 search through browser list for an entry to sync with
183 **************************************************************************/
184 void do_browser_lists(void)
186 struct browse_cache_record *b;
187 static time_t last = 0;
188 time_t t = time(NULL);
190 if (t-last < 4) return; /* don't do too many of these at once! */
194 /* pick any entry in the list, preferably one whose time is up */
195 for (b = browserlist; b && b->next; b = b->next)
197 if (b->sync_time < t && b->synced == False) break;
200 if (!b || b->synced || sync_browse_entry(b))
202 /* leave entries (even ones already sync'd) for up to a minute.
203 this stops them getting re-sync'd too often */
204 expire_browse_cache(t - 60);
209 /****************************************************************************
210 find a server responsible for a workgroup, and sync browse lists
211 control ends up back here via response_name_query.
212 **************************************************************************/
213 void sync_server(enum cmd_type cmd, char *serv_name, char *work_name, int name_type,
216 add_browser_entry(serv_name, name_type, work_name, 0, ip);
218 if (cmd == MASTER_SERVER_CHECK)
220 /* announce ourselves as a master browser to serv_name */
221 do_announce_request(myname, serv_name, 13, 0x20, 0, ip);
226 /****************************************************************************
227 update workgroup database from a name registration
228 **************************************************************************/
229 void update_from_reg(char *name, int type, struct in_addr ip)
231 /* default server type: minimum guess at requirement XXXX */
233 DEBUG(4,("update from registration: host %s ip %s type %0x\n",
234 name, inet_ntoa(ip), type));
236 /* workgroup types, but not a chat type */
237 if (type >= 0x1b && type <= 0x1e)
239 struct work_record *work;
240 struct domain_record *d;
242 if (!(d = find_domain(ip))) return;
243 if (!(work = find_workgroupstruct(d, name, False))) return;
245 /* request the server to announce if on our subnet */
246 if (ip_equal(bcast_ip, d->bcast_ip)) announce_request(work, ip);
248 /* domain master type or master browser type */
249 if (type == 0x1b || type == 0x1d)
251 struct hostent *hp = gethostbyaddr((char*)&ip, sizeof(ip), AF_INET);
253 /* gethostbyaddr name may not match netbios name but who cares */
254 add_browser_entry(hp->h_name, type, work->work_group, 120, ip);
261 /****************************************************************************
262 add the default workgroup into my domain
263 **************************************************************************/
264 void add_my_domains(void)
266 /* add or find domain on our local subnet, in the default workgroup */
268 if (*lp_workgroup() != '*')
270 add_domain_entry(bcast_ip,Netmask,lp_workgroup(), True);
275 /****************************************************************************
276 send a backup list response.
277 **************************************************************************/
278 static void send_backup_list(char *work_name, struct nmb_name *src_name,
279 int info_count, int token, int info,
280 int name_type, struct in_addr ip)
282 struct domain_record *d;
284 char *p, *countptr, *nameptr;
287 char *theirname = src_name->name;
289 DEBUG(3,("Backup list of %s to %s: %s(%x) %s(%x)\n",
290 work_name, inet_ntoa(ip),
291 myname,0x20,theirname,0x0));
293 if (name_type == 0x1d)
295 DEBUG(4,("master browsers: "));
297 else if (name_type == 0x1b)
299 DEBUG(4,("domain controllers: "));
303 DEBUG(0,("backup request for unknown type %0x\n", name_type));
307 bzero(outbuf,sizeof(outbuf));
310 CVAL(p,0) = 10; /* backup list response */
313 countptr = p; /* count pointer */
315 SSVAL(p,1,token); /* sender's workgroup index representation */
316 SSVAL(p,3,info); /* XXXX clueless: info, usually zero */
321 for (d = domainlist; d; d = d->next)
323 struct work_record *work;
325 for (work = d->workgrouplist; work; work = work->next)
327 struct server_record *s;
329 if (!strequal(work->work_group, work_name)) continue;
331 for (s = work->serverlist; s; s = s->next)
336 if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
338 for (n = nameptr; n < p; n = skip_string(n, 1))
340 if (strequal(n, s->serv.name)) found = True;
343 if (found) continue; /* exclude names already added */
345 /* workgroup request: include all backup browsers in the list */
346 /* domain request: include all domain members in the list */
348 if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
349 (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
351 DEBUG(4, ("%s ", s->serv.name));
354 strcpy(p,s->serv.name);
356 p = skip_string(p,1);
364 DEBUG(4, ("none\n"));
369 DEBUG(4, (" - count %d\n", count));
372 CVAL(countptr,0) = count; /* total number of backup browsers found */
375 int len = PTR_DIFF(p, outbuf);
377 for (i = 0; i < len; i+= 16)
379 DEBUG(4, ("%3x char ", i));
381 for (j = 0; j < 16; j++)
383 unsigned char x = outbuf[i+j];
384 if (x < 32 || x > 127) x = '.';
386 if (i+j >= len) break;
390 DEBUG(4, (" hex ", i));
392 for (j = 0; j < 16; j++)
394 if (i+j >= len) break;
395 DEBUG(4, (" %02x", outbuf[i+j]));
402 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
403 myname,theirname,0x20,0,ip,myip);
407 /*******************************************************************
408 same context: scope. should check name_type as well, and makes sure
409 we don't process messages from ourselves
410 ******************************************************************/
411 BOOL same_context(struct dgram_packet *dgram)
413 if (!strequal(dgram->dest_name .scope,scope )) return(True);
414 if ( strequal(dgram->source_name.name ,myname)) return(True);
420 /*******************************************************************
421 am I listening on a name. XXXX check the type of name as well.
422 ******************************************************************/
423 BOOL listening_name(struct work_record *work, struct nmb_name *n)
425 if (strequal(n->name,myname) ||
426 strequal(n->name,work->work_group) ||
427 strequal(n->name,MSBROWSE))
436 /*******************************************************************
437 process a domain announcement frame
439 Announce frames come in 3 types. Servers send host announcements
440 (command=1) to let the master browswer know they are
441 available. Master browsers send local master announcements
442 (command=15) to let other masters and backups that they are the
443 master. They also send domain announcements (command=12) to register
446 The comment field of domain announcements contains the master
447 browser name. The servertype is used by NetServerEnum to select
448 resources. We just have to pass it to smbd (via browser.dat) and let
449 the client choose using bit masks.
450 ******************************************************************/
451 static void process_announce(struct packet_struct *p,int command,char *buf)
453 struct dgram_packet *dgram = &p->packet.dgram;
454 struct in_addr ip = dgram->header.source_ip;
455 struct domain_record *d = find_domain(ip);
457 int update_count = CVAL(buf,0);
458 int ttl = IVAL(buf,1)/1000;
460 int osmajor=CVAL(buf,21);
461 int osminor=CVAL(buf,22);
462 uint32 servertype = IVAL(buf,23);
463 char *comment = buf+31;
464 struct work_record *work;
466 char *serv_name = dgram->source_name.name;
470 DEBUG(3,("Announce(%d) %s(%x)",command,name,name[15]));
471 DEBUG(3,("%s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
472 namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
473 servertype,comment));
477 if (dgram->dest_name.name_type == 0 && command == 1)
479 DEBUG(2,("Announce to nametype(0) not supported yet\n"));
482 if (command == 12 && ((!strequal(dgram->dest_name.name, MSBROWSE)) ||
483 dgram->dest_name.name_type != 0x1))
485 DEBUG(0, ("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n",
486 command, inet_ntoa(ip), namestr(&dgram->dest_name)));
490 if (same_context(dgram)) return;
498 work_name = dgram->dest_name.name;
501 if (!(work = find_workgroupstruct(d, work_name, False))) return;
503 DEBUG(4, ("workgroup %s on %s\n", work->work_group, serv_name));
507 /* add them to our browse list */
508 add_server_entry(d,work,name,servertype,ttl,comment,True);
510 /* make a selection of machines become backup browsers (1 in 10) */
511 tell_become_backup();
513 /* get their browse list from them and add it to ours. */
514 add_browser_entry(serv_name,dgram->dest_name.name_type,
515 work->work_group,30,ip);
518 /*******************************************************************
519 process a master announcement frame
520 ******************************************************************/
521 static void process_master_announce(struct packet_struct *p,char *buf)
523 struct dgram_packet *dgram = &p->packet.dgram;
524 struct in_addr ip = dgram->header.source_ip;
525 struct domain_record *d = find_domain(ip);
526 struct domain_record *mydomain = find_domain(bcast_ip);
528 struct work_record *work;
531 DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(ip)));
533 if (same_context(dgram)) return;
535 if (!d || !mydomain) return;
537 if (!lp_domain_master()) return;
539 for (work = mydomain->workgrouplist; work; work = work->next)
543 /* merge browse lists with them */
544 add_browser_entry(name,0x1b, work->work_group,30,ip);
549 /*******************************************************************
550 process a receive backup list request
552 we receive a list of servers, and we attempt to locate them all on
553 our local subnet, and sync browse lists with them on the workgroup
554 they are said to be in.
555 ******************************************************************/
556 static void process_rcv_backup_list(struct packet_struct *p,char *buf)
558 struct dgram_packet *dgram = &p->packet.dgram;
559 struct in_addr ip = dgram->header.source_ip;
560 int count = CVAL(buf,0);
561 int Index = IVAL(buf,1); /* caller's index representing workgroup */
564 DEBUG(3,("Receive Backup ack for %s from %s total=%d index=%d\n",
565 namestr(&dgram->dest_name), inet_ntoa(ip),
568 if (same_context(dgram)) return;
570 if (count <= 0) return;
572 /* go through the list of servers attempting to sync browse lists */
573 for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
575 struct in_addr back_ip;
576 struct domain_record *d;
578 DEBUG(4, ("Searching for backup browser %s at %s...\n",
579 buf1, inet_ntoa(ip)));
581 /* XXXX assume name is a DNS name NOT a netbios name. a more complete
582 approach is to use reply_name_query functionality to find the name */
583 back_ip = *interpret_addr2(buf1);
585 if (zero_ip(back_ip))
587 DEBUG(4,("Failed to find backup browser server using DNS\n"));
591 DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
593 if ((d = find_domain(back_ip)))
595 struct domain_record *d1;
596 for (d1 = domainlist; d1; d1 = d1->next)
598 struct work_record *work;
599 for (work = d1->workgrouplist; work; work = work->next)
601 if (work->token == Index)
603 queue_netbios_packet(ClientNMB,NMB_QUERY,SERVER_CHECK,
604 work->work_group,0x1d,0,
605 False,False,back_ip);
614 /*******************************************************************
615 process a send backup list request
617 A client send a backup list request to ask for a list of servers on
618 the net that maintain server lists for a domain. A server is then
619 chosen from this list to send NetServerEnum commands to to list
622 Currently samba only sends back one name in the backup list, its
623 own. For larger nets we'll have to add backups and send "become
624 backup" requests occasionally.
625 ******************************************************************/
626 static void process_send_backup_list(struct packet_struct *p,char *buf)
628 struct dgram_packet *dgram = &p->packet.dgram;
629 struct in_addr ip = dgram->header.source_ip;
630 struct domain_record *d; /* = find_domain(ip); */
631 struct work_record *work;
633 int count = CVAL(buf,0);
634 int token = SVAL(buf,1); /* sender's key index for the workgroup? */
635 int info = SVAL(buf,3); /* XXXX don't know: some sort of info */
636 int name_type = dgram->dest_name.name_type;
638 DEBUG(0,("Send Backup request to %s token=%d info = %x count=%d\n",
639 namestr(&dgram->dest_name), token, info, count));
641 if (same_context(dgram)) return;
643 if (count <= 0) return;
645 if (name_type != 0x1b && name_type != 0x1d)
647 DEBUG(0, ("backup request to wrong type %d\n", name_type));
651 for (d = domainlist; d; d = d->next)
653 for (work = d->workgrouplist; work; work = work->next)
655 if (strequal(work->work_group, dgram->dest_name.name))
657 DEBUG(3, ("found workgroup %s(%d)\n",
658 work->work_group, work->token));
659 send_backup_list(work->work_group,&dgram->source_name,
660 count,token,info,name_type,ip);
668 /*******************************************************************
669 process a reset browser state
672 0x1 - stop being a master browser
673 0x2 - discard browse lists, stop being a master browser, try again.
674 0x4 - stop being a master browser forever. no way. ain't gonna.
676 ******************************************************************/
677 static void process_reset_browser(struct packet_struct *p,char *buf)
679 struct dgram_packet *dgram = &p->packet.dgram;
680 int state = CVAL(buf,0);
682 DEBUG(1,("Diagnostic browser reset request to %s state=0x%X\n",
683 namestr(&dgram->dest_name), state));
685 /* stop being a master but still deal with being a backup browser */
688 struct domain_record *d;
689 for (d = domainlist; d; d = d->next)
691 struct work_record *work;
692 for (work = d->workgrouplist; work; work = work->next)
696 become_nonmaster(d,work);
702 /* totally delete all servers and start afresh */
705 struct domain_record *d;
706 for (d = domainlist; d; d = d->next)
708 struct work_record *work;
709 for (work=d->workgrouplist;work;work=remove_workgroup(d,work));
714 /* stop browsing altogether. i don't think this is a good idea! */
717 DEBUG(1, ("ignoring request to stop being a browser. sorry!\n"));
722 /*******************************************************************
723 process a announcement request
725 clients send these when they want everyone to send an announcement
726 immediately. This can cause quite a storm of packets!
727 ******************************************************************/
728 static void process_announce_request(struct packet_struct *p,char *buf)
730 struct dgram_packet *dgram = &p->packet.dgram;
731 struct work_record *work;
732 struct in_addr ip = dgram->header.source_ip;
733 struct domain_record *d = find_domain(ip);
734 int token = CVAL(buf,0);
739 DEBUG(3,("Announce request from %s to %s token=0x%X\n",
740 name,namestr(&dgram->dest_name), token));
742 if (strequal(dgram->source_name.name,myname)) return;
746 if (!ip_equal(bcast_ip, d->bcast_ip)) return;
748 for (work = d->workgrouplist; work; work = work->next)
750 if (strequal(dgram->dest_name.name,work->work_group))
752 work->needannounce = True;
758 /****************************************************************************
759 process a domain logon packet
760 **************************************************************************/
761 void process_logon_packet(struct packet_struct *p,char *buf,int len)
763 struct dgram_packet *dgram = &p->packet.dgram;
764 struct in_addr ip = dgram->header.source_ip;
765 struct domain_record *d = find_domain(ip);
768 BOOL add_slashes = False;
771 struct work_record *work;
775 if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False)))
778 if (!lp_domain_logons()) {
779 DEBUG(3,("No domain logons\n"));
782 if (!listening_name(work, &dgram->dest_name))
784 DEBUG(4,("Not listening to that domain\n"));
792 char *machine = buf+2;
793 char *user = skip_string(machine,1);
794 logname = skip_string(user,1);
798 DEBUG(3,("Domain login request from %s(%s) user=%s\n",
799 machine,inet_ntoa(p->ip),user));
804 char *machine = buf+2;
805 logname = skip_string(machine,1);
807 reply_name = lp_domain_controller();
809 DEBUG(3,("No domain controller configured\n"));
812 DEBUG(3,("GETDC request from %s(%s)\n",
813 machine,inet_ntoa(p->ip)));
817 DEBUG(3,("Unknown domain request %d\n",code));
821 bzero(outbuf,sizeof(outbuf));
823 SSVAL(q,0,reply_code);
829 StrnCpy(q,reply_name,16);
831 q = skip_string(q,1);
835 send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
836 myname,&dgram->source_name.name[0],0x20,0,p->ip,myip);
840 /****************************************************************************
841 depending on what announce has been made, we are only going to
842 accept certain types of name announce. XXXX untested code
844 check listening name type
845 ****************************************************************************/
846 BOOL listening_type(struct packet_struct *p, int command)
848 struct dgram_packet *dgram = &p->packet.dgram;
849 int type = dgram->dest_name.name_type;
853 case 1: /* host announce */
855 if (type != 0x0 || type != 0x20) return (False);
859 case 2: /* announce request */
865 case 8: /* election */
871 case 9: /* get backup list */
877 case 10: /* receive backup list */
883 case 12: /* domain announce */
885 if (type != 0x1b || type != 0x1c) return (False);
889 case 13: /* master announcement */
891 if (type != 0x1d) return (False);
895 case 15: /* local master announce */
897 if (type != 0x1c || type != 0x1d) return (False);
901 return (True); /* we're not dealing with unknown packet types */
905 /****************************************************************************
906 process a browse frame
907 ****************************************************************************/
908 void process_browse_packet(struct packet_struct *p,char *buf,int len)
910 int command = CVAL(buf,0);
913 case 1: /* host announce */
914 case 12: /* domain announce */
915 case 15: /* local master announce */
917 process_announce(p,command,buf+1);
921 case 2: /* announce request */
923 process_announce_request(p,buf+1);
927 case 8: /* election */
929 process_election(p,buf+1);
933 case 9: /* get backup list */
935 process_send_backup_list(p,buf+1);
939 case 10: /* receive backup list */
942 struct dgram_packet *dgram = &p->packet.dgram;
945 DEBUG(4, ("ignoring browse packet %d from %s %s to %s\n",
946 command, namestr(&dgram->source_name),
947 inet_ntoa(p->ip), namestr(&dgram->dest_name)));
949 for (i = 0; i < len; i+= 16)
951 DEBUG(4, ("%3x char ", i));
953 for (j = 0; j < 16; j++)
955 unsigned char x = buf[i+j];
956 if (x < 32 || x > 127) x = '.';
958 if (i+j >= len) break;
962 DEBUG(4, (" hex ", i));
964 for (j = 0; j < 16; j++)
966 if (i+j >= len) break;
967 DEBUG(4, (" %02x", buf[i+j]));
973 #endif /* TEST_CODE */
974 process_rcv_backup_list(p, buf+1);
978 case 11: /* reset browser state */
980 process_reset_browser(p, buf+1);
984 case 13: /* master announcement */
986 process_master_announce(p,buf+1);
993 struct dgram_packet *dgram = &p->packet.dgram;
996 DEBUG(4, ("ignoring browse packet %d from %s %s to %s\n",
997 command, namestr(&dgram->source_name),
998 inet_ntoa(p->ip), namestr(&dgram->dest_name)));
1000 for (i = 0; i < len; i+= 16)
1002 DEBUG(4, ("%3x char ", i));
1004 for (j = 0; j < 16; j++)
1006 unsigned char x = buf[i+j];
1007 if (x < 32 || x > 127) x = '.';
1009 if (i+j >= len) break;
1010 DEBUG(4, ("%c", x));
1013 DEBUG(4, (" hex ", i));
1015 for (j = 0; j < 16; j++)
1017 if (i+j >= len) break;
1018 DEBUG(4, (" %02x", buf[i+j]));
1025 #endif /* TEST_CODE */
1030 /****************************************************************************
1031 process udp 138 datagrams
1032 ****************************************************************************/
1033 void process_dgram(struct packet_struct *p)
1038 struct dgram_packet *dgram = &p->packet.dgram;
1040 if (dgram->header.msg_type != 0x10 &&
1041 dgram->header.msg_type != 0x11 &&
1042 dgram->header.msg_type != 0x12) {
1043 /* don't process error packets etc yet */
1047 buf = &dgram->data[0];
1048 buf -= 4; /* XXXX for the pseudo tcp length -
1049 someday I need to get rid of this */
1051 if (CVAL(buf,smb_com) != SMBtrans) return;
1053 len = SVAL(buf,smb_vwv11);
1054 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1056 DEBUG(3,("datagram from %s to %s for %s of type %d len=%d\n",
1057 namestr(&dgram->source_name),namestr(&dgram->dest_name),
1058 smb_buf(buf),CVAL(buf2,0),len));
1061 if (len <= 0) return;
1063 if (strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE"))
1065 process_browse_packet(p,buf2,len);
1066 } else if (strequal(smb_buf(buf),"\\MAILSLOT\\NET\\NETLOGON")) {
1067 process_logon_packet(p,buf2,len);