alias_nbt.c revision 99207
11556Srgrimes/*- 21556Srgrimes * Written by Atsushi Murai <amurai@spec.co.jp> 31556Srgrimes * Copyright (c) 1998, System Planning and Engineering Co. 41556Srgrimes * All rights reserved. 51556Srgrimes * 61556Srgrimes * Redistribution and use in source and binary forms, with or without 71556Srgrimes * modification, are permitted provided that the following conditions 81556Srgrimes * are met: 91556Srgrimes * 1. Redistributions of source code must retain the above copyright 101556Srgrimes * notice, this list of conditions and the following disclaimer. 111556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 121556Srgrimes * notice, this list of conditions and the following disclaimer in the 131556Srgrimes * documentation and/or other materials provided with the distribution. 141556Srgrimes * 151556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 161556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 171556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 181556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 191556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 201556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 211556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 221556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 231556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 241556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 251556Srgrimes * SUCH DAMAGE. 261556Srgrimes * TODO: 271556Srgrimes * oClean up. 281556Srgrimes * oConsidering for word alignment for other platform. 291556Srgrimes */ 301556Srgrimes 311556Srgrimes#include <sys/cdefs.h> 321556Srgrimes__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias_nbt.c 99207 2002-07-01 11:19:40Z brian $"); 331556Srgrimes 341556Srgrimes/* 351556Srgrimes alias_nbt.c performs special processing for NetBios over TCP/IP 361556Srgrimes sessions by UDP. 371556Srgrimes 3820412Ssteve Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>) 391556Srgrimes 401556Srgrimes See HISTORY file for record of revisions. 411556Srgrimes*/ 421556Srgrimes 431556Srgrimes/* Includes */ 4435772Scharnier#include <ctype.h> 4536000Scharnier#include <stdio.h> 4635772Scharnier#include <string.h> 4735772Scharnier#include <sys/types.h> 4850471Speter#include <netinet/in_systm.h> 491556Srgrimes#include <netinet/in.h> 501556Srgrimes#include <arpa/inet.h> 511556Srgrimes#include <netinet/ip.h> 521556Srgrimes#include <netinet/udp.h> 5383482Sdillon#include <netinet/tcp.h> 5483482Sdillon 5583482Sdillon#include "alias_local.h" 5683482Sdillon 5783482Sdillontypedef struct { 581556Srgrimes struct in_addr oldaddr; 591556Srgrimes u_short oldport; 601556Srgrimes struct in_addr newaddr; 611556Srgrimes u_short newport; 6218578Sache u_short *uh_sum; 631556Srgrimes} NBTArguments; 641556Srgrimes 6578732Sddtypedef struct { 661556Srgrimes unsigned char type; 6783482Sdillon unsigned char flags; 681556Srgrimes u_short id; 691556Srgrimes struct in_addr source_ip; 701556Srgrimes u_short source_port; 7139065Simp u_short len; 721556Srgrimes u_short offset; 7339138Simp} NbtDataHeader; 741556Srgrimes 7583482Sdillon#define OpQuery 0 7683482Sdillon#define OpUnknown 4 7783482Sdillon#define OpRegist 5 7883482Sdillon#define OpRelease 6 7983482Sdillon#define OpWACK 7 8083482Sdillon#define OpRefresh 8 8183482Sdillontypedef struct { 8283482Sdillon u_short nametrid; 831556Srgrimes u_short dir:1, opcode:4, nmflags:7, rcode:4; 8439138Simp u_short qdcount; 8539138Simp u_short ancount; 8639138Simp u_short nscount; 871556Srgrimes u_short arcount; 881556Srgrimes} NbtNSHeader; 891556Srgrimes 9018578Sache#define FMT_ERR 0x1 9118578Sache#define SRV_ERR 0x2 9224348Simp#define IMP_ERR 0x4 931556Srgrimes#define RFS_ERR 0x5 941556Srgrimes#define ACT_ERR 0x6 951556Srgrimes#define CFT_ERR 0x7 961556Srgrimes 971556Srgrimes 981556Srgrimes#ifdef DEBUG 991556Srgrimesstatic void PrintRcode( u_char rcode ) { 1001556Srgrimes 1011556Srgrimes switch (rcode) { 1021556Srgrimes case FMT_ERR: 1031556Srgrimes printf("\nFormat Error."); 1041556Srgrimes case SRV_ERR: 1051556Srgrimes printf("\nSever failure."); 1061556Srgrimes case IMP_ERR: 1071556Srgrimes printf("\nUnsupported request error.\n"); 1081556Srgrimes case RFS_ERR: 1091556Srgrimes printf("\nRefused error.\n"); 11059239Sasmodai case ACT_ERR: 1111556Srgrimes printf("\nActive error.\n"); 1121556Srgrimes case CFT_ERR: 1131556Srgrimes printf("\nName in conflict error.\n"); 1141556Srgrimes default: 11518546Simp printf("\n?%c?=%0x\n", '?', rcode ); 1161556Srgrimes 1171556Srgrimes } 1181556Srgrimes} 1191556Srgrimes#endif 1201556Srgrimes 1211556Srgrimes 1221556Srgrimes/* Handling Name field */ 12383482Sdillonstatic u_char *AliasHandleName ( u_char *p, char *pmax ) { 1241556Srgrimes 12583482Sdillon u_char *s; 1261556Srgrimes u_char c; 1271556Srgrimes int compress; 1281556Srgrimes 1291556Srgrimes /* Following length field */ 1301556Srgrimes 1311556Srgrimes if (p == NULL || (char *)p >= pmax) 13283482Sdillon return(NULL); 13383482Sdillon 13483482Sdillon if (*p & 0xc0 ) { 1351556Srgrimes p = p + 2; 13683482Sdillon if ((char *)p > pmax) 13783482Sdillon return(NULL); 13883961Sru return ((u_char *)p); 1391556Srgrimes } 14083482Sdillon while ( ( *p & 0x3f) != 0x00 ) { 14183482Sdillon s = p + 1; 14283482Sdillon if ( *p == 0x20 ) 14383482Sdillon compress = 1; 14483482Sdillon else 14583961Sru compress = 0; 14683482Sdillon 14783482Sdillon /* Get next length field */ 14883482Sdillon p = (u_char *)(p + (*p & 0x3f) + 1); 14983482Sdillon if ((char *)p > pmax) { 15083482Sdillon p = NULL; 15183482Sdillon break; 15283482Sdillon } 1531556Srgrimes#ifdef DEBUG 15483482Sdillon printf(":"); 15583482Sdillon#endif 15683482Sdillon while (s < p) { 15783482Sdillon if ( compress == 1 ) { 15883961Sru c = (u_char )(((((*s & 0x0f) << 4) | (*(s+1) & 0x0f)) - 0x11)); 15983961Sru#ifdef DEBUG 16083961Sru if (isprint( c ) ) 16183961Sru printf("%c", c ); 16283961Sru else 16383961Sru printf("<0x%02x>", c ); 16483961Sru#endif 16583482Sdillon s +=2; 16683482Sdillon } else { 16783961Sru#ifdef DEBUG 16883961Sru printf("%c", *s); 16983482Sdillon#endif 17083482Sdillon s++; 17183482Sdillon } 17283482Sdillon } 17383482Sdillon#ifdef DEBUG 1741556Srgrimes printf(":"); 1751556Srgrimes#endif 17683482Sdillon fflush(stdout); 17783482Sdillon } 1781556Srgrimes 1791556Srgrimes /* Set up to out of Name field */ 1801556Srgrimes if (p == NULL || (char *)p >= pmax) 1811556Srgrimes p = NULL; 18283961Sru else 18383961Sru p++; 18483961Sru return ((u_char *)p); 18583961Sru} 1861556Srgrimes 1871556Srgrimes/* 1881556Srgrimes * NetBios Datagram Handler (IP/UDP) 1891556Srgrimes */ 1901556Srgrimes#define DGM_DIRECT_UNIQ 0x10 1911556Srgrimes#define DGM_DIRECT_GROUP 0x11 1921556Srgrimes#define DGM_BROADCAST 0x12 1931556Srgrimes#define DGM_ERROR 0x13 1941556Srgrimes#define DGM_QUERY 0x14 1951556Srgrimes#define DGM_POSITIVE_RES 0x15 1961556Srgrimes#define DGM_NEGATIVE_RES 0x16 1971556Srgrimes 1981556Srgrimesint AliasHandleUdpNbt( 1991556Srgrimes struct ip *pip, /* IP packet to examine/patch */ 2001556Srgrimes struct alias_link *link, 2011556Srgrimes struct in_addr *alias_address, 2021556Srgrimes u_short alias_port 2031556Srgrimes) { 2041556Srgrimes struct udphdr * uh; 2051556Srgrimes NbtDataHeader *ndh; 2061556Srgrimes u_char *p = NULL; 2071556Srgrimes char *pmax; 2081556Srgrimes 2091556Srgrimes /* Calculate data length of UDP packet */ 2101556Srgrimes uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 2111556Srgrimes pmax = (char *)uh + ntohs( uh->uh_ulen ); 2121556Srgrimes 2131556Srgrimes ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr))); 2141556Srgrimes if ((char *)(ndh + 1) > pmax) 2151556Srgrimes return(-1); 2161556Srgrimes#ifdef DEBUG 2171556Srgrimes printf("\nType=%02x,", ndh->type ); 2181556Srgrimes#endif 21918578Sache switch ( ndh->type ) { 2201556Srgrimes case DGM_DIRECT_UNIQ: 2211556Srgrimes case DGM_DIRECT_GROUP: 2221556Srgrimes case DGM_BROADCAST: 2231556Srgrimes p = (u_char *)ndh + 14; 2241556Srgrimes p = AliasHandleName ( p, pmax ); /* Source Name */ 2251556Srgrimes p = AliasHandleName ( p, pmax ); /* Destination Name */ 2261556Srgrimes break; 2271556Srgrimes case DGM_ERROR: 2281556Srgrimes p = (u_char *)ndh + 11; 2291556Srgrimes break; 2301556Srgrimes case DGM_QUERY: 2311556Srgrimes case DGM_POSITIVE_RES: 2321556Srgrimes case DGM_NEGATIVE_RES: 2331556Srgrimes p = (u_char *)ndh + 10; 2341556Srgrimes p = AliasHandleName ( p, pmax ); /* Destination Name */ 2351556Srgrimes break; 2361556Srgrimes } 23711145Sbde if (p == NULL || (char *)p > pmax) 2381556Srgrimes p = NULL; 2391556Srgrimes#ifdef DEBUG 2401556Srgrimes printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); 2411556Srgrimes#endif 2421556Srgrimes /* Doing a IP address and Port number Translation */ 2431556Srgrimes if ( uh->uh_sum != 0 ) { 24483482Sdillon int acc; 2451556Srgrimes u_short *sptr; 2461556Srgrimes acc = ndh->source_port; 2471556Srgrimes acc -= alias_port; 24839065Simp sptr = (u_short *) &(ndh->source_ip); 24939065Simp acc += *sptr++; 25039065Simp acc += *sptr; 2511556Srgrimes sptr = (u_short *) alias_address; 2521556Srgrimes acc -= *sptr++; 2531556Srgrimes acc -= *sptr; 2541556Srgrimes ADJUST_CHECKSUM(acc, uh->uh_sum); 2551556Srgrimes } 2561556Srgrimes ndh->source_ip = *alias_address; 2571556Srgrimes ndh->source_port = alias_port; 2581556Srgrimes#ifdef DEBUG 25939138Simp printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); 26059239Sasmodai fflush(stdout); 2611556Srgrimes#endif 2621556Srgrimes return((p == NULL) ? -1 : 0); 2631556Srgrimes} 26439138Simp/* Question Section */ 2651556Srgrimes#define QS_TYPE_NB 0x0020 26611145Sbde#define QS_TYPE_NBSTAT 0x0021 2671556Srgrimes#define QS_CLAS_IN 0x0001 26811145Sbdetypedef struct { 26911145Sbde u_short type; /* The type of Request */ 2701556Srgrimes u_short class; /* The class of Request */ 27183482Sdillon} NBTNsQuestion; 27283482Sdillon 27383482Sdillonstatic u_char * 27483482SdillonAliasHandleQuestion( 27583482Sdillon u_short count, 27683482Sdillon NBTNsQuestion *q, 27783482Sdillon char *pmax, 27883482Sdillon NBTArguments *nbtarg) 27983482Sdillon{ 28083482Sdillon 28183482Sdillon while ( count != 0 ) { 28283482Sdillon /* Name Filed */ 28383482Sdillon q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax); 28483482Sdillon 28583482Sdillon if (q == NULL || (char *)(q + 1) > pmax) { 28683482Sdillon q = NULL; 28783482Sdillon break; 28883482Sdillon } 28983482Sdillon 29083482Sdillon /* Type and Class filed */ 29183482Sdillon switch ( ntohs(q->type) ) { 29283482Sdillon case QS_TYPE_NB: 29383482Sdillon case QS_TYPE_NBSTAT: 29483482Sdillon q= q+1; 29583482Sdillon break; 29683482Sdillon default: 29783482Sdillon#ifdef DEBUG 29883482Sdillon printf("\nUnknown Type on Question %0x\n", ntohs(q->type) ); 29983482Sdillon#endif 30083482Sdillon break; 30183482Sdillon } 30283482Sdillon count--; 30383482Sdillon } 30483482Sdillon 30583482Sdillon /* Set up to out of Question Section */ 30683482Sdillon return ((u_char *)q); 30783482Sdillon} 30883482Sdillon 30983482Sdillon/* Resource Record */ 31083482Sdillon#define RR_TYPE_A 0x0001 31183482Sdillon#define RR_TYPE_NS 0x0002 31283482Sdillon#define RR_TYPE_NULL 0x000a 31383482Sdillon#define RR_TYPE_NB 0x0020 31483482Sdillon#define RR_TYPE_NBSTAT 0x0021 31583482Sdillon#define RR_CLAS_IN 0x0001 31683482Sdillon#define SizeOfNsResource 8 31783482Sdillontypedef struct { 31883482Sdillon u_short type; 31983482Sdillon u_short class; 32083482Sdillon unsigned int ttl; 321 u_short rdlen; 322} NBTNsResource; 323 324#define SizeOfNsRNB 6 325typedef struct { 326 u_short g:1, ont:2, resv:13; 327 struct in_addr addr; 328} NBTNsRNB; 329 330static u_char * 331AliasHandleResourceNB( 332 NBTNsResource *q, 333 char *pmax, 334 NBTArguments *nbtarg) 335{ 336 NBTNsRNB *nb; 337 u_short bcount; 338 339 if (q == NULL || (char *)(q + 1) > pmax) 340 return(NULL); 341 /* Check out a length */ 342 bcount = ntohs(q->rdlen); 343 344 /* Forward to Resource NB position */ 345 nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource); 346 347 /* Processing all in_addr array */ 348#ifdef DEBUG 349 printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr)); 350 printf("->%s, %dbytes] ",inet_ntoa(nbtarg->newaddr ), bcount); 351#endif 352 while ( nb != NULL && bcount != 0 ) { 353 if ((char *)(nb + 1) > pmax) { 354 nb = NULL; 355 break; 356 } 357#ifdef DEBUG 358 printf("<%s>", inet_ntoa(nb->addr) ); 359#endif 360 if (!bcmp(&nbtarg->oldaddr,&nb->addr, sizeof(struct in_addr) ) ) { 361 if ( *nbtarg->uh_sum != 0 ) { 362 int acc; 363 u_short *sptr; 364 365 sptr = (u_short *) &(nb->addr); 366 acc = *sptr++; 367 acc += *sptr; 368 sptr = (u_short *) &(nbtarg->newaddr); 369 acc -= *sptr++; 370 acc -= *sptr; 371 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum); 372 } 373 374 nb->addr = nbtarg->newaddr; 375#ifdef DEBUG 376 printf("O"); 377#endif 378 } 379#ifdef DEBUG 380 else { 381 printf("."); 382 } 383#endif 384 nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB); 385 bcount -= SizeOfNsRNB; 386 } 387 if (nb == NULL || (char *)(nb + 1) > pmax) { 388 nb = NULL; 389 } 390 391 return ((u_char *)nb); 392} 393 394#define SizeOfResourceA 6 395typedef struct { 396 struct in_addr addr; 397} NBTNsResourceA; 398 399static u_char * 400AliasHandleResourceA( 401 NBTNsResource *q, 402 char *pmax, 403 NBTArguments *nbtarg) 404{ 405 NBTNsResourceA *a; 406 u_short bcount; 407 408 if (q == NULL || (char *)(q + 1) > pmax) 409 return(NULL); 410 411 /* Forward to Resource A position */ 412 a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) ); 413 414 /* Check out of length */ 415 bcount = ntohs(q->rdlen); 416 417 /* Processing all in_addr array */ 418#ifdef DEBUG 419 printf("Arec [%s", inet_ntoa(nbtarg->oldaddr)); 420 printf("->%s]",inet_ntoa(nbtarg->newaddr )); 421#endif 422 while ( bcount != 0 ) { 423 if (a == NULL || (char *)(a + 1) > pmax) 424 return(NULL); 425#ifdef DEBUG 426 printf("..%s", inet_ntoa(a->addr) ); 427#endif 428 if ( !bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr) ) ) { 429 if ( *nbtarg->uh_sum != 0 ) { 430 int acc; 431 u_short *sptr; 432 433 sptr = (u_short *) &(a->addr); /* Old */ 434 acc = *sptr++; 435 acc += *sptr; 436 sptr = (u_short *) &nbtarg->newaddr; /* New */ 437 acc -= *sptr++; 438 acc -= *sptr; 439 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum); 440 } 441 442 a->addr = nbtarg->newaddr; 443 } 444 a++; /*XXXX*/ 445 bcount -= SizeOfResourceA; 446 } 447 if (a == NULL || (char *)(a + 1) > pmax) 448 a = NULL; 449 return ((u_char *)a); 450} 451 452typedef struct { 453 u_short opcode:4, flags:8, resv:4; 454} NBTNsResourceNULL; 455 456static u_char * 457AliasHandleResourceNULL( 458 NBTNsResource *q, 459 char *pmax, 460 NBTArguments *nbtarg) 461{ 462 NBTNsResourceNULL *n; 463 u_short bcount; 464 465 if (q == NULL || (char *)(q + 1) > pmax) 466 return(NULL); 467 468 /* Forward to Resource NULL position */ 469 n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); 470 471 /* Check out of length */ 472 bcount = ntohs(q->rdlen); 473 474 /* Processing all in_addr array */ 475 while ( bcount != 0 ) { 476 if ((char *)(n + 1) > pmax) { 477 n = NULL; 478 break; 479 } 480 n++; 481 bcount -= sizeof(NBTNsResourceNULL); 482 } 483 if ((char *)(n + 1) > pmax) 484 n = NULL; 485 486 return ((u_char *)n); 487} 488 489static u_char * 490AliasHandleResourceNS( 491 NBTNsResource *q, 492 char *pmax, 493 NBTArguments *nbtarg) 494{ 495 NBTNsResourceNULL *n; 496 u_short bcount; 497 498 if (q == NULL || (char *)(q + 1) > pmax) 499 return(NULL); 500 501 /* Forward to Resource NULL position */ 502 n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); 503 504 /* Check out of length */ 505 bcount = ntohs(q->rdlen); 506 507 /* Resource Record Name Filed */ 508 q = (NBTNsResource *)AliasHandleName( (u_char *)n, pmax ); /* XXX */ 509 510 if (q == NULL || (char *)((u_char *)n + bcount) > pmax) 511 return(NULL); 512 else 513 return ((u_char *)n + bcount); 514} 515 516typedef struct { 517 u_short numnames; 518} NBTNsResourceNBSTAT; 519 520static u_char * 521AliasHandleResourceNBSTAT( 522 NBTNsResource *q, 523 char *pmax, 524 NBTArguments *nbtarg) 525{ 526 NBTNsResourceNBSTAT *n; 527 u_short bcount; 528 529 if (q == NULL || (char *)(q + 1) > pmax) 530 return(NULL); 531 532 /* Forward to Resource NBSTAT position */ 533 n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) ); 534 535 /* Check out of length */ 536 bcount = ntohs(q->rdlen); 537 538 if (q == NULL || (char *)((u_char *)n + bcount) > pmax) 539 return(NULL); 540 else 541 return ((u_char *)n + bcount); 542} 543 544static u_char * 545AliasHandleResource( 546 u_short count, 547 NBTNsResource *q, 548 char *pmax, 549 NBTArguments 550 *nbtarg) 551{ 552 while ( count != 0 ) { 553 /* Resource Record Name Filed */ 554 q = (NBTNsResource *)AliasHandleName( (u_char *)q, pmax ); 555 556 if (q == NULL || (char *)(q + 1) > pmax) 557 break; 558#ifdef DEBUG 559 printf("type=%02x, count=%d\n", ntohs(q->type), count ); 560#endif 561 562 /* Type and Class filed */ 563 switch ( ntohs(q->type) ) { 564 case RR_TYPE_NB: 565 q = (NBTNsResource *)AliasHandleResourceNB( 566 q, 567 pmax, 568 nbtarg 569 ); 570 break; 571 case RR_TYPE_A: 572 q = (NBTNsResource *)AliasHandleResourceA( 573 q, 574 pmax, 575 nbtarg 576 ); 577 break; 578 case RR_TYPE_NS: 579 q = (NBTNsResource *)AliasHandleResourceNS( 580 q, 581 pmax, 582 nbtarg 583 ); 584 break; 585 case RR_TYPE_NULL: 586 q = (NBTNsResource *)AliasHandleResourceNULL( 587 q, 588 pmax, 589 nbtarg 590 ); 591 break; 592 case RR_TYPE_NBSTAT: 593 q = (NBTNsResource *)AliasHandleResourceNBSTAT( 594 q, 595 pmax, 596 nbtarg 597 ); 598 break; 599 default: 600#ifdef DEBUG 601 printf( 602 "\nUnknown Type of Resource %0x\n", 603 ntohs(q->type) 604 ); 605#endif 606 break; 607 } 608 count--; 609 } 610 fflush(stdout); 611 return ((u_char *)q); 612} 613 614int AliasHandleUdpNbtNS( 615 struct ip *pip, /* IP packet to examine/patch */ 616 struct alias_link *link, 617 struct in_addr *alias_address, 618 u_short *alias_port, 619 struct in_addr *original_address, 620 u_short *original_port ) 621{ 622 struct udphdr * uh; 623 NbtNSHeader * nsh; 624 u_char * p; 625 char *pmax; 626 NBTArguments nbtarg; 627 628 /* Set up Common Parameter */ 629 nbtarg.oldaddr = *alias_address; 630 nbtarg.oldport = *alias_port; 631 nbtarg.newaddr = *original_address; 632 nbtarg.newport = *original_port; 633 634 /* Calculate data length of UDP packet */ 635 uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 636 nbtarg.uh_sum = &(uh->uh_sum); 637 nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr))); 638 p = (u_char *)(nsh + 1); 639 pmax = (char *)uh + ntohs( uh->uh_ulen ); 640 641 if ((char *)(nsh + 1) > pmax) 642 return(-1); 643 644#ifdef DEBUG 645 printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x" 646 ", an=%04x, ns=%04x, ar=%04x, [%d]-->", 647 nsh->dir ? "Response": "Request", 648 nsh->nametrid, 649 nsh->opcode, 650 nsh->nmflags, 651 nsh->rcode, 652 ntohs(nsh->qdcount), 653 ntohs(nsh->ancount), 654 ntohs(nsh->nscount), 655 ntohs(nsh->arcount), 656 (u_char *)p -(u_char *)nsh 657 ); 658#endif 659 660 /* Question Entries */ 661 if (ntohs(nsh->qdcount) !=0 ) { 662 p = AliasHandleQuestion( 663 ntohs(nsh->qdcount), 664 (NBTNsQuestion *)p, 665 pmax, 666 &nbtarg 667 ); 668 } 669 670 /* Answer Resource Records */ 671 if (ntohs(nsh->ancount) !=0 ) { 672 p = AliasHandleResource( 673 ntohs(nsh->ancount), 674 (NBTNsResource *)p, 675 pmax, 676 &nbtarg 677 ); 678 } 679 680 /* Authority Resource Recodrs */ 681 if (ntohs(nsh->nscount) !=0 ) { 682 p = AliasHandleResource( 683 ntohs(nsh->nscount), 684 (NBTNsResource *)p, 685 pmax, 686 &nbtarg 687 ); 688 } 689 690 /* Additional Resource Recodrs */ 691 if (ntohs(nsh->arcount) !=0 ) { 692 p = AliasHandleResource( 693 ntohs(nsh->arcount), 694 (NBTNsResource *)p, 695 pmax, 696 &nbtarg 697 ); 698 } 699 700#ifdef DEBUG 701 PrintRcode(nsh->rcode); 702#endif 703 return ((p == NULL) ? -1 : 0); 704} 705