00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024 extern struct in_addr lastip;
00025 extern int lastport;
00026
00027 int num_good_sends = 0;
00028 int num_good_receives = 0;
00029
00030 static const struct opcode_names {
00031 const char *nmb_opcode_name;
00032 int opcode;
00033 } nmb_header_opcode_names[] = {
00034 {"Query", 0 },
00035 {"Registration", 5 },
00036 {"Release", 6 },
00037 {"WACK", 7 },
00038 {"Refresh", 8 },
00039 {"Refresh(altcode)", 9 },
00040 {"Multi-homed Registration", 15 },
00041 {0, -1 }
00042 };
00043
00044
00045
00046
00047
00048 static const char *lookup_opcode_name( int opcode )
00049 {
00050 const struct opcode_names *op_namep;
00051 int i;
00052
00053 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
00054 op_namep = &nmb_header_opcode_names[i];
00055 if(opcode == op_namep->opcode)
00056 return op_namep->nmb_opcode_name;
00057 }
00058 return "<unknown opcode>";
00059 }
00060
00061
00062
00063
00064
00065 static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
00066 {
00067 int i, j;
00068
00069 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
00070 hdr,
00071 nmb_namestr(&res->rr_name),
00072 res->rr_type,
00073 res->rr_class,
00074 res->ttl ) );
00075
00076 if( res->rdlength == 0 || res->rdata == NULL )
00077 return;
00078
00079 for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
00080 DEBUGADD(4, (" %s %3x char ", hdr, i));
00081
00082 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
00083 unsigned char x = res->rdata[i+j];
00084 if (x < 32 || x > 127)
00085 x = '.';
00086
00087 if (i+j >= res->rdlength)
00088 break;
00089 DEBUGADD(4, ("%c", x));
00090 }
00091
00092 DEBUGADD(4, (" hex "));
00093
00094 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
00095 if (i+j >= res->rdlength)
00096 break;
00097 DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
00098 }
00099
00100 DEBUGADD(4, ("\n"));
00101 }
00102 }
00103
00104
00105
00106
00107
00108 void debug_nmb_packet(struct packet_struct *p)
00109 {
00110 struct nmb_packet *nmb = &p->packet.nmb;
00111
00112 if( DEBUGLVL( 4 ) ) {
00113 dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
00114 inet_ntoa(p->ip), p->port,
00115 nmb->header.name_trn_id,
00116 lookup_opcode_name(nmb->header.opcode),
00117 nmb->header.opcode,
00118 BOOLSTR(nmb->header.response) );
00119 dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
00120 BOOLSTR(nmb->header.nm_flags.bcast),
00121 BOOLSTR(nmb->header.nm_flags.recursion_available),
00122 BOOLSTR(nmb->header.nm_flags.recursion_desired),
00123 BOOLSTR(nmb->header.nm_flags.trunc),
00124 BOOLSTR(nmb->header.nm_flags.authoritative) );
00125 dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
00126 nmb->header.rcode,
00127 nmb->header.qdcount,
00128 nmb->header.ancount,
00129 nmb->header.nscount,
00130 nmb->header.arcount );
00131 }
00132
00133 if (nmb->header.qdcount) {
00134 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
00135 nmb_namestr(&nmb->question.question_name),
00136 nmb->question.question_type,
00137 nmb->question.question_class) );
00138 }
00139
00140 if (nmb->answers && nmb->header.ancount) {
00141 debug_nmb_res_rec(nmb->answers,"answers");
00142 }
00143 if (nmb->nsrecs && nmb->header.nscount) {
00144 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
00145 }
00146 if (nmb->additional && nmb->header.arcount) {
00147 debug_nmb_res_rec(nmb->additional,"additional");
00148 }
00149 }
00150
00151
00152
00153
00154
00155 static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
00156 BOOL *got_pointer,int *ret)
00157 {
00158 int loop_count=0;
00159
00160 while ((ubuf[*offset] & 0xC0) == 0xC0) {
00161 if (!*got_pointer)
00162 (*ret) += 2;
00163 (*got_pointer)=True;
00164 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
00165 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
00166 return(False);
00167 }
00168 }
00169 return(True);
00170 }
00171
00172
00173
00174
00175
00176
00177 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
00178 {
00179 int m,n=0;
00180 unsigned char *ubuf = (unsigned char *)inbuf;
00181 int ret = 0;
00182 BOOL got_pointer=False;
00183 int loop_count=0;
00184 int offset = ofs;
00185
00186 if (length - offset < 2)
00187 return(0);
00188
00189
00190 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
00191 return(0);
00192
00193 m = ubuf[offset];
00194
00195 if (!m)
00196 return(0);
00197 if ((m & 0xC0) || offset+m+2 > length)
00198 return(0);
00199
00200 memset((char *)name,'\0',sizeof(*name));
00201
00202
00203 if (!got_pointer)
00204 ret += m + 2;
00205 offset++;
00206 while (m > 0) {
00207 unsigned char c1,c2;
00208 c1 = ubuf[offset++]-'A';
00209 c2 = ubuf[offset++]-'A';
00210 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
00211 return(0);
00212 name->name[n++] = (c1<<4) | c2;
00213 m -= 2;
00214 }
00215 name->name[n] = 0;
00216
00217 if (n==MAX_NETBIOSNAME_LEN) {
00218
00219 name->name_type = ((unsigned char)name->name[15]) & 0xff;
00220
00221
00222 name->name[15] = 0;
00223 n = 14;
00224 while (n && name->name[n]==' ')
00225 name->name[n--] = 0;
00226 }
00227
00228
00229 n = 0;
00230 while (ubuf[offset]) {
00231
00232 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
00233 return(0);
00234
00235 m = ubuf[offset];
00236
00237
00238
00239 if (!m)
00240 return(0);
00241 if (!got_pointer)
00242 ret += m+1;
00243 if (n)
00244 name->scope[n++] = '.';
00245 if (m+2+offset>length || n+m+1>sizeof(name->scope))
00246 return(0);
00247 offset++;
00248 while (m--)
00249 name->scope[n++] = (char)ubuf[offset++];
00250
00251
00252
00253
00254 if (loop_count++ == 10)
00255 return 0;
00256 }
00257 name->scope[n++] = 0;
00258
00259 return(ret);
00260 }
00261
00262
00263
00264
00265
00266
00267
00268 void put_name(char *dest, const char *name, int pad, unsigned int name_type)
00269 {
00270 size_t len = strlen(name);
00271
00272 memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? len : MAX_NETBIOSNAME_LEN - 1);
00273 if (len < MAX_NETBIOSNAME_LEN - 1) {
00274 memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
00275 }
00276 dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
00289 {
00290 int ret,m;
00291 nstring buf1;
00292 char *p;
00293
00294 if (strcmp(name->name,"*") == 0) {
00295
00296 put_name(buf1, "*", '\0', name->name_type);
00297 } else {
00298 put_name(buf1, name->name, ' ', name->name_type);
00299 }
00300
00301 buf[offset] = 0x20;
00302
00303 ret = 34;
00304
00305 for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
00306 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
00307 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
00308 }
00309 offset += 33;
00310
00311 buf[offset] = 0;
00312
00313 if (name->scope[0]) {
00314
00315 ret += strlen(name->scope) + 1;
00316 safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope));
00317
00318 p = &buf[offset+1];
00319 while ((p = strchr_m(p,'.'))) {
00320 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
00321 offset += (buf[offset] + 1);
00322 p = &buf[offset+1];
00323 }
00324 buf[offset] = strlen(&buf[offset+1]);
00325 }
00326
00327 return(ret);
00328 }
00329
00330
00331
00332
00333
00334 char *nmb_namestr(const struct nmb_name *n)
00335 {
00336 static int i=0;
00337 static fstring ret[4];
00338 fstring name;
00339 char *p = ret[i];
00340
00341 pull_ascii_fstring(name, n->name);
00342 if (!n->scope[0])
00343 slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type);
00344 else
00345 slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",name,n->name_type,n->scope);
00346
00347 i = (i+1)%4;
00348 return(p);
00349 }
00350
00351
00352
00353
00354
00355 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
00356 struct res_rec **recs, int count)
00357 {
00358 int i;
00359
00360 *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
00361 if (!*recs)
00362 return(False);
00363
00364 memset((char *)*recs,'\0',sizeof(**recs)*count);
00365
00366 for (i=0;i<count;i++) {
00367 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
00368 (*offset) += l;
00369 if (!l || (*offset)+10 > length) {
00370 SAFE_FREE(*recs);
00371 return(False);
00372 }
00373 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
00374 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
00375 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
00376 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
00377 (*offset) += 10;
00378 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
00379 (*offset)+(*recs)[i].rdlength > length) {
00380 SAFE_FREE(*recs);
00381 return(False);
00382 }
00383 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
00384 (*offset) += (*recs)[i].rdlength;
00385 }
00386 return(True);
00387 }
00388
00389
00390
00391
00392
00393 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
00394 {
00395 int ret=0;
00396 int i;
00397
00398 for (i=0;i<count;i++) {
00399 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
00400 offset += l;
00401 ret += l;
00402 RSSVAL(buf,offset,recs[i].rr_type);
00403 RSSVAL(buf,offset+2,recs[i].rr_class);
00404 RSIVAL(buf,offset+4,recs[i].ttl);
00405 RSSVAL(buf,offset+8,recs[i].rdlength);
00406 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
00407 offset += 10+recs[i].rdlength;
00408 ret += 10+recs[i].rdlength;
00409 }
00410
00411 return(ret);
00412 }
00413
00414
00415
00416
00417
00418 static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset)
00419 {
00420 int ret=0;
00421 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
00422 buf[offset+1] = (ptr_offset & 0xFF);
00423 offset += 2;
00424 ret += 2;
00425 RSSVAL(buf,offset,rec->rr_type);
00426 RSSVAL(buf,offset+2,rec->rr_class);
00427 RSIVAL(buf,offset+4,rec->ttl);
00428 RSSVAL(buf,offset+8,rec->rdlength);
00429 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
00430 offset += 10+rec->rdlength;
00431 ret += 10+rec->rdlength;
00432
00433 return(ret);
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
00444 {
00445 int offset;
00446 int flags;
00447
00448 memset((char *)dgram,'\0',sizeof(*dgram));
00449
00450 if (length < 14)
00451 return(False);
00452
00453 dgram->header.msg_type = CVAL(inbuf,0);
00454 flags = CVAL(inbuf,1);
00455 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
00456 if (flags & 1)
00457 dgram->header.flags.more = True;
00458 if (flags & 2)
00459 dgram->header.flags.first = True;
00460 dgram->header.dgm_id = RSVAL(inbuf,2);
00461 putip((char *)&dgram->header.source_ip,inbuf+4);
00462 dgram->header.source_port = RSVAL(inbuf,8);
00463 dgram->header.dgm_length = RSVAL(inbuf,10);
00464 dgram->header.packet_offset = RSVAL(inbuf,12);
00465
00466 offset = 14;
00467
00468 if (dgram->header.msg_type == 0x10 ||
00469 dgram->header.msg_type == 0x11 ||
00470 dgram->header.msg_type == 0x12) {
00471 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
00472 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
00473 }
00474
00475 if (offset >= length || (length-offset > sizeof(dgram->data)))
00476 return(False);
00477
00478 dgram->datasize = length-offset;
00479 memcpy(dgram->data,inbuf+offset,dgram->datasize);
00480
00481
00482
00483 SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
00484 memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
00485
00486 return(True);
00487 }
00488
00489
00490
00491
00492
00493
00494 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
00495 {
00496 int nm_flags,offset;
00497
00498 memset((char *)nmb,'\0',sizeof(*nmb));
00499
00500 if (length < 12)
00501 return(False);
00502
00503
00504 nmb->header.name_trn_id = RSVAL(inbuf,0);
00505
00506 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
00507
00508 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
00509 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
00510 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
00511 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
00512 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
00513 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
00514 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
00515 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
00516 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
00517 nmb->header.qdcount = RSVAL(inbuf,4);
00518 nmb->header.ancount = RSVAL(inbuf,6);
00519 nmb->header.nscount = RSVAL(inbuf,8);
00520 nmb->header.arcount = RSVAL(inbuf,10);
00521
00522 if (nmb->header.qdcount) {
00523 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
00524 if (!offset)
00525 return(False);
00526
00527 if (length - (12+offset) < 4)
00528 return(False);
00529 nmb->question.question_type = RSVAL(inbuf,12+offset);
00530 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
00531
00532 offset += 12+4;
00533 } else {
00534 offset = 12;
00535 }
00536
00537
00538 if (nmb->header.ancount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
00539 nmb->header.ancount))
00540 return(False);
00541
00542 if (nmb->header.nscount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
00543 nmb->header.nscount))
00544 return(False);
00545
00546 if (nmb->header.arcount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
00547 nmb->header.arcount))
00548 return(False);
00549
00550 return(True);
00551 }
00552
00553
00554
00555
00556
00557 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
00558 {
00559 struct nmb_packet *nmb;
00560 struct nmb_packet *copy_nmb;
00561 struct packet_struct *pkt_copy;
00562
00563 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
00564 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
00565 return NULL;
00566 }
00567
00568
00569
00570 *pkt_copy = *packet;
00571
00572
00573 pkt_copy->locked = False;
00574
00575
00576 nmb = &packet->packet.nmb;
00577 copy_nmb = &pkt_copy->packet.nmb;
00578
00579 copy_nmb->answers = NULL;
00580 copy_nmb->nsrecs = NULL;
00581 copy_nmb->additional = NULL;
00582
00583
00584
00585 if (nmb->answers) {
00586 if((copy_nmb->answers = SMB_MALLOC_ARRAY(struct res_rec,nmb->header.ancount)) == NULL)
00587 goto free_and_exit;
00588 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
00589 nmb->header.ancount * sizeof(struct res_rec));
00590 }
00591 if (nmb->nsrecs) {
00592 if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.nscount)) == NULL)
00593 goto free_and_exit;
00594 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
00595 nmb->header.nscount * sizeof(struct res_rec));
00596 }
00597 if (nmb->additional) {
00598 if((copy_nmb->additional = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.arcount)) == NULL)
00599 goto free_and_exit;
00600 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
00601 nmb->header.arcount * sizeof(struct res_rec));
00602 }
00603
00604 return pkt_copy;
00605
00606 free_and_exit:
00607
00608 SAFE_FREE(copy_nmb->answers);
00609 SAFE_FREE(copy_nmb->nsrecs);
00610 SAFE_FREE(copy_nmb->additional);
00611 SAFE_FREE(pkt_copy);
00612
00613 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
00614 return NULL;
00615 }
00616
00617
00618
00619
00620
00621 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
00622 {
00623 struct packet_struct *pkt_copy;
00624
00625 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
00626 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
00627 return NULL;
00628 }
00629
00630
00631
00632 *pkt_copy = *packet;
00633
00634
00635 pkt_copy->locked = False;
00636
00637
00638
00639 return pkt_copy;
00640 }
00641
00642
00643
00644
00645
00646 struct packet_struct *copy_packet(struct packet_struct *packet)
00647 {
00648 if(packet->packet_type == NMB_PACKET)
00649 return copy_nmb_packet(packet);
00650 else if (packet->packet_type == DGRAM_PACKET)
00651 return copy_dgram_packet(packet);
00652 return NULL;
00653 }
00654
00655
00656
00657
00658
00659 static void free_nmb_packet(struct nmb_packet *nmb)
00660 {
00661 SAFE_FREE(nmb->answers);
00662 SAFE_FREE(nmb->nsrecs);
00663 SAFE_FREE(nmb->additional);
00664 }
00665
00666
00667
00668
00669
00670 static void free_dgram_packet(struct dgram_packet *nmb)
00671 {
00672
00673 }
00674
00675
00676
00677
00678
00679 void free_packet(struct packet_struct *packet)
00680 {
00681 if (packet->locked)
00682 return;
00683 if (packet->packet_type == NMB_PACKET)
00684 free_nmb_packet(&packet->packet.nmb);
00685 else if (packet->packet_type == DGRAM_PACKET)
00686 free_dgram_packet(&packet->packet.dgram);
00687 ZERO_STRUCTPN(packet);
00688 SAFE_FREE(packet);
00689 }
00690
00691
00692
00693
00694
00695 struct packet_struct *parse_packet(char *buf,int length,
00696 enum packet_type packet_type)
00697 {
00698 struct packet_struct *p;
00699 BOOL ok=False;
00700
00701 p = SMB_MALLOC_P(struct packet_struct);
00702 if (!p)
00703 return(NULL);
00704
00705 ZERO_STRUCTP(p);
00706
00707 p->next = NULL;
00708 p->prev = NULL;
00709 p->ip = lastip;
00710 p->port = lastport;
00711 p->locked = False;
00712 p->timestamp = time(NULL);
00713 p->packet_type = packet_type;
00714
00715 switch (packet_type) {
00716 case NMB_PACKET:
00717 ok = parse_nmb(buf,length,&p->packet.nmb);
00718 break;
00719
00720 case DGRAM_PACKET:
00721 ok = parse_dgram(buf,length,&p->packet.dgram);
00722 break;
00723 }
00724
00725 if (!ok) {
00726 free_packet(p);
00727 return NULL;
00728 }
00729
00730 return p;
00731 }
00732
00733
00734
00735
00736
00737
00738 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
00739 {
00740 struct packet_struct *packet;
00741 char buf[MAX_DGRAM_SIZE];
00742 int length;
00743
00744 length = read_udp_socket(fd,buf,sizeof(buf));
00745 if (length < MIN_DGRAM_SIZE)
00746 return(NULL);
00747
00748 packet = parse_packet(buf, length, packet_type);
00749 if (!packet)
00750 return NULL;
00751
00752 packet->fd = fd;
00753
00754 num_good_receives++;
00755
00756 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
00757 length, inet_ntoa(packet->ip), packet->port ) );
00758
00759 return(packet);
00760 }
00761
00762
00763
00764
00765
00766 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
00767 {
00768 BOOL ret = False;
00769 int i;
00770 struct sockaddr_in sock_out;
00771
00772
00773 memset((char *)&sock_out,'\0',sizeof(sock_out));
00774 putip((char *)&sock_out.sin_addr,(char *)&ip);
00775 sock_out.sin_port = htons( port );
00776 sock_out.sin_family = AF_INET;
00777
00778 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
00779 len, inet_ntoa(ip), port ) );
00780
00781
00782
00783
00784
00785 for (i = 0; i < 5; i++) {
00786 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
00787 if (ret || errno != ECONNREFUSED)
00788 break;
00789 }
00790
00791 if (!ret)
00792 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
00793 inet_ntoa(ip),port,strerror(errno)));
00794
00795 if (ret)
00796 num_good_sends++;
00797
00798 return(ret);
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817 static int build_dgram(char *buf,struct packet_struct *p)
00818 {
00819 struct dgram_packet *dgram = &p->packet.dgram;
00820 unsigned char *ubuf = (unsigned char *)buf;
00821 int offset=0;
00822
00823
00824 ubuf[0] = dgram->header.msg_type;
00825 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
00826 if (dgram->header.flags.more)
00827 ubuf[1] |= 1;
00828 if (dgram->header.flags.first)
00829 ubuf[1] |= 2;
00830 RSSVAL(ubuf,2,dgram->header.dgm_id);
00831 putip(ubuf+4,(char *)&dgram->header.source_ip);
00832 RSSVAL(ubuf,8,dgram->header.source_port);
00833 RSSVAL(ubuf,12,dgram->header.packet_offset);
00834
00835 offset = 14;
00836
00837 if (dgram->header.msg_type == 0x10 ||
00838 dgram->header.msg_type == 0x11 ||
00839 dgram->header.msg_type == 0x12) {
00840 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
00841 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
00842 }
00843
00844 memcpy(ubuf+offset,dgram->data,dgram->datasize);
00845 offset += dgram->datasize;
00846
00847
00848
00849
00850
00851 dgram->header.dgm_length = (offset - 14);
00852 RSSVAL(ubuf,10,dgram->header.dgm_length);
00853
00854 return(offset);
00855 }
00856
00857
00858
00859
00860
00861 void make_nmb_name( struct nmb_name *n, const char *name, int type)
00862 {
00863 fstring unix_name;
00864 memset( (char *)n, '\0', sizeof(struct nmb_name) );
00865 fstrcpy(unix_name, name);
00866 strupper_m(unix_name);
00867 push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
00868 n->name_type = (unsigned int)type & 0xFF;
00869 push_ascii(n->scope, global_scope(), 64, STR_TERMINATE);
00870 }
00871
00872
00873
00874
00875
00876 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
00877 {
00878 return ((n1->name_type == n2->name_type) &&
00879 strequal(n1->name ,n2->name ) &&
00880 strequal(n1->scope,n2->scope));
00881 }
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892 static int build_nmb(char *buf,struct packet_struct *p)
00893 {
00894 struct nmb_packet *nmb = &p->packet.nmb;
00895 unsigned char *ubuf = (unsigned char *)buf;
00896 int offset=0;
00897
00898
00899 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
00900 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
00901 if (nmb->header.response)
00902 ubuf[offset+2] |= (1<<7);
00903 if (nmb->header.nm_flags.authoritative &&
00904 nmb->header.response)
00905 ubuf[offset+2] |= 0x4;
00906 if (nmb->header.nm_flags.trunc)
00907 ubuf[offset+2] |= 0x2;
00908 if (nmb->header.nm_flags.recursion_desired)
00909 ubuf[offset+2] |= 0x1;
00910 if (nmb->header.nm_flags.recursion_available &&
00911 nmb->header.response)
00912 ubuf[offset+3] |= 0x80;
00913 if (nmb->header.nm_flags.bcast)
00914 ubuf[offset+3] |= 0x10;
00915 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
00916
00917 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
00918 RSSVAL(ubuf,offset+6,nmb->header.ancount);
00919 RSSVAL(ubuf,offset+8,nmb->header.nscount);
00920 RSSVAL(ubuf,offset+10,nmb->header.arcount);
00921
00922 offset += 12;
00923 if (nmb->header.qdcount) {
00924
00925 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
00926 RSSVAL(ubuf,offset,nmb->question.question_type);
00927 RSSVAL(ubuf,offset+2,nmb->question.question_class);
00928 offset += 4;
00929 }
00930
00931 if (nmb->header.ancount)
00932 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
00933 nmb->header.ancount);
00934
00935 if (nmb->header.nscount)
00936 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
00937 nmb->header.nscount);
00938
00939
00940
00941
00942
00943
00944
00945
00946 if((nmb->header.response == False) &&
00947 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
00948 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
00949 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
00950 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
00951 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
00952 (nmb->header.arcount == 1)) {
00953
00954 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
00955
00956 } else if (nmb->header.arcount) {
00957 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
00958 nmb->header.arcount);
00959 }
00960 return(offset);
00961 }
00962
00963
00964
00965
00966
00967 int build_packet(char *buf, struct packet_struct *p)
00968 {
00969 int len = 0;
00970
00971 switch (p->packet_type) {
00972 case NMB_PACKET:
00973 len = build_nmb(buf,p);
00974 break;
00975
00976 case DGRAM_PACKET:
00977 len = build_dgram(buf,p);
00978 break;
00979 }
00980
00981 return len;
00982 }
00983
00984
00985
00986
00987
00988 BOOL send_packet(struct packet_struct *p)
00989 {
00990 char buf[1024];
00991 int len=0;
00992
00993 memset(buf,'\0',sizeof(buf));
00994
00995 len = build_packet(buf, p);
00996
00997 if (!len)
00998 return(False);
00999
01000 return(send_udp(p->fd,buf,len,p->ip,p->port));
01001 }
01002
01003
01004
01005
01006
01007
01008 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
01009 {
01010 fd_set fds;
01011 struct timeval timeout;
01012 int ret;
01013
01014 FD_ZERO(&fds);
01015 FD_SET(fd,&fds);
01016 timeout.tv_sec = t/1000;
01017 timeout.tv_usec = 1000*(t%1000);
01018
01019 if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
01020
01021 DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
01022 return NULL;
01023 }
01024
01025 if (ret == 0)
01026 return NULL;
01027
01028 if (FD_ISSET(fd,&fds))
01029 return(read_packet(fd,type));
01030
01031 return(NULL);
01032 }
01033
01034
01035
01036
01037
01038
01039
01040 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
01041 {
01042 struct packet_struct *p;
01043
01044 p = receive_packet(fd, NMB_PACKET, t);
01045
01046 if (p && p->packet.nmb.header.response &&
01047 p->packet.nmb.header.name_trn_id == trn_id) {
01048 return p;
01049 }
01050 if (p)
01051 free_packet(p);
01052
01053
01054 return receive_unexpected(NMB_PACKET, trn_id, NULL);
01055 }
01056
01057
01058
01059
01060
01061
01062
01063 struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name)
01064 {
01065 struct packet_struct *p;
01066
01067 p = receive_packet(fd, DGRAM_PACKET, t);
01068
01069 if (p && match_mailslot_name(p, mailslot_name)) {
01070 return p;
01071 }
01072 if (p)
01073 free_packet(p);
01074
01075
01076 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
01077 }
01078
01079
01080
01081
01082
01083 BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
01084 {
01085 struct dgram_packet *dgram = &p->packet.dgram;
01086 char *buf;
01087
01088 buf = &dgram->data[0];
01089 buf -= 4;
01090
01091 buf = smb_buf(buf);
01092
01093 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
01094 return True;
01095 }
01096
01097 return False;
01098 }
01099
01100
01101
01102
01103
01104 int matching_quad_bits(unsigned char *p1, unsigned char *p2)
01105 {
01106 int i, j, ret = 0;
01107 for (i=0; i<4; i++) {
01108 if (p1[i] != p2[i])
01109 break;
01110 ret += 8;
01111 }
01112
01113 if (i==4)
01114 return ret;
01115
01116 for (j=0; j<8; j++) {
01117 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
01118 break;
01119 ret++;
01120 }
01121
01122 return ret;
01123 }
01124
01125 static unsigned char sort_ip[4];
01126
01127
01128
01129
01130
01131 static int name_query_comp(unsigned char *p1, unsigned char *p2)
01132 {
01133 return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);
01134 }
01135
01136
01137
01138
01139
01140
01141 void sort_query_replies(char *data, int n, struct in_addr ip)
01142 {
01143 if (n <= 1)
01144 return;
01145
01146 putip(sort_ip, (char *)&ip);
01147
01148 qsort(data, n, 6, QSORT_CAST name_query_comp);
01149 }
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163 char *dns_to_netbios_name(const char *dns_name)
01164 {
01165 static nstring netbios_name;
01166 int i;
01167 StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1);
01168 netbios_name[15] = 0;
01169
01170
01171
01172
01173
01174
01175 for (i = 0; i < 15; i++) {
01176 if (netbios_name[i] == '.') {
01177 netbios_name[i] = 0;
01178 break;
01179 }
01180 }
01181
01182 return netbios_name;
01183 }
01184
01185
01186
01187
01188
01189 static int name_interpret(char *in, fstring name)
01190 {
01191 int ret;
01192 int len = (*in++) / 2;
01193 fstring out_string;
01194 char *out = out_string;
01195
01196 *out=0;
01197
01198 if (len > 30 || len<1)
01199 return(0);
01200
01201 while (len--) {
01202 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
01203 *out = 0;
01204 return(0);
01205 }
01206 *out = ((in[0]-'A')<<4) + (in[1]-'A');
01207 in += 2;
01208 out++;
01209 }
01210 ret = out[-1];
01211 out[-1] = 0;
01212
01213 #ifdef NETBIOS_SCOPE
01214
01215 while(*in) {
01216 *out++ = '.';
01217 len = *(unsigned char *)in++;
01218 StrnCpy(out, in, len);
01219 out += len;
01220 *out=0;
01221 in += len;
01222 }
01223 #endif
01224 pull_ascii_fstring(name, out_string);
01225
01226 return(ret);
01227 }
01228
01229
01230
01231
01232
01233
01234 int name_mangle( char *In, char *Out, char name_type )
01235 {
01236 int i;
01237 int len;
01238 nstring buf;
01239 char *p = Out;
01240
01241
01242 if (strcmp(In,"*") == 0)
01243 put_name(buf, "*", '\0', 0x00);
01244 else {
01245
01246
01247 fstring buf_unix;
01248 nstring buf_dos;
01249
01250 pull_ascii_fstring(buf_unix, In);
01251 strupper_m(buf_unix);
01252
01253 push_ascii_nstring(buf_dos, buf_unix);
01254 put_name(buf, buf_dos, ' ', name_type);
01255 }
01256
01257
01258 p[0] = 32;
01259 p++;
01260
01261
01262 for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
01263 p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
01264 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
01265 }
01266 p += 32;
01267 p[0] = '\0';
01268
01269
01270 for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) {
01271 switch( (global_scope())[i] ) {
01272 case '\0':
01273 p[0] = len;
01274 if( len > 0 )
01275 p[len+1] = 0;
01276 return( name_len(Out) );
01277 case '.':
01278 p[0] = len;
01279 p += (len + 1);
01280 len = -1;
01281 break;
01282 default:
01283 p[len+1] = (global_scope())[i];
01284 break;
01285 }
01286 }
01287
01288 return( name_len(Out) );
01289 }
01290
01291
01292
01293
01294
01295 static char *name_ptr(char *buf,int ofs)
01296 {
01297 unsigned char c = *(unsigned char *)(buf+ofs);
01298
01299 if ((c & 0xC0) == 0xC0) {
01300 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
01301 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
01302 return(buf + l);
01303 } else {
01304 return(buf+ofs);
01305 }
01306 }
01307
01308
01309
01310
01311
01312 int name_extract(char *buf,int ofs, fstring name)
01313 {
01314 char *p = name_ptr(buf,ofs);
01315 int d = PTR_DIFF(p,buf+ofs);
01316
01317 name[0] = '\0';
01318 if (d < -50 || d > 50)
01319 return(0);
01320 return(name_interpret(p,name));
01321 }
01322
01323
01324
01325
01326
01327 int name_len(char *s1)
01328 {
01329
01330 unsigned char *s = (unsigned char *)s1;
01331 int len;
01332
01333
01334 if (0xC0 == (*s & 0xC0))
01335 return(2);
01336
01337
01338 for (len = 1; (*s); s += (*s) + 1) {
01339 len += *s + 1;
01340 SMB_ASSERT(len < 80);
01341 }
01342
01343 return(len);
01344 }