alias_nbt.c revision 187304
1/*- 2 * Written by Atsushi Murai <amurai@spec.co.jp> 3 * Copyright (c) 1998, System Planning and Engineering Co. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * TODO: 27 * oClean up. 28 * oConsidering for word alignment for other platform. 29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias_nbt.c 187304 2009-01-15 19:35:23Z piso $"); 33 34/* 35 alias_nbt.c performs special processing for NetBios over TCP/IP 36 sessions by UDP. 37 38 Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>) 39 40 See HISTORY file for record of revisions. 41*/ 42 43/* Includes */ 44#ifdef _KERNEL 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/kernel.h> 48#include <sys/module.h> 49#else 50#include <errno.h> 51#include <sys/types.h> 52#include <stdio.h> 53#include <strings.h> 54#endif 55 56#include <netinet/in_systm.h> 57#include <netinet/in.h> 58#include <netinet/ip.h> 59#include <netinet/udp.h> 60 61#ifdef _KERNEL 62#include <netinet/libalias/alias_local.h> 63#include <netinet/libalias/alias_mod.h> 64#else 65#include "alias_local.h" 66#include "alias_mod.h" 67#endif 68 69#define NETBIOS_NS_PORT_NUMBER 137 70#define NETBIOS_DGM_PORT_NUMBER 138 71 72static int 73AliasHandleUdpNbt(struct libalias *, struct ip *, struct alias_link *, 74 struct in_addr *, u_short); 75 76static int 77AliasHandleUdpNbtNS(struct libalias *, struct ip *, struct alias_link *, 78 struct in_addr *, u_short *, struct in_addr *, u_short *); 79static int 80fingerprint1(struct libalias *la, struct ip *pip, struct alias_data *ah) 81{ 82 83 if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL || 84 ah->aaddr == NULL || ah->aport == NULL) 85 return (-1); 86 if (ntohs(*ah->dport) == NETBIOS_DGM_PORT_NUMBER 87 || ntohs(*ah->sport) == NETBIOS_DGM_PORT_NUMBER) 88 return (0); 89 return (-1); 90} 91 92static int 93protohandler1(struct libalias *la, struct ip *pip, struct alias_data *ah) 94{ 95 96 AliasHandleUdpNbt(la, pip, ah->lnk, ah->aaddr, *ah->aport); 97 return (0); 98} 99 100static int 101fingerprint2(struct libalias *la, struct ip *pip, struct alias_data *ah) 102{ 103 104 if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL || 105 ah->aaddr == NULL || ah->aport == NULL) 106 return (-1); 107 if (ntohs(*ah->dport) == NETBIOS_NS_PORT_NUMBER 108 || ntohs(*ah->sport) == NETBIOS_NS_PORT_NUMBER) 109 return (0); 110 return (-1); 111} 112 113static int 114protohandler2in(struct libalias *la, struct ip *pip, struct alias_data *ah) 115{ 116 117 AliasHandleUdpNbtNS(la, pip, ah->lnk, ah->aaddr, ah->aport, 118 ah->oaddr, ah->dport); 119 return (0); 120} 121 122static int 123protohandler2out(struct libalias *la, struct ip *pip, struct alias_data *ah) 124{ 125 126 AliasHandleUdpNbtNS(la, pip, ah->lnk, &pip->ip_src, ah->sport, 127 ah->aaddr, ah->aport); 128 return (0); 129} 130 131/* Kernel module definition. */ 132struct proto_handler handlers[] = { 133 { 134 .pri = 130, 135 .dir = IN|OUT, 136 .proto = UDP, 137 .fingerprint = &fingerprint1, 138 .protohandler = &protohandler1 139 }, 140 { 141 .pri = 140, 142 .dir = IN, 143 .proto = UDP, 144 .fingerprint = &fingerprint2, 145 .protohandler = &protohandler2in 146 }, 147 { 148 .pri = 140, 149 .dir = OUT, 150 .proto = UDP, 151 .fingerprint = &fingerprint2, 152 .protohandler = &protohandler2out 153 }, 154 { EOH } 155}; 156 157static int 158mod_handler(module_t mod, int type, void *data) 159{ 160 int error; 161 162 switch (type) { 163 case MOD_LOAD: 164 error = 0; 165 LibAliasAttachHandlers(handlers); 166 break; 167 case MOD_UNLOAD: 168 error = 0; 169 LibAliasDetachHandlers(handlers); 170 break; 171 default: 172 error = EINVAL; 173 } 174 return (error); 175} 176 177#ifdef _KERNEL 178static 179#endif 180moduledata_t alias_mod = { 181 "alias_nbt", mod_handler, NULL 182}; 183 184#ifdef _KERNEL 185DECLARE_MODULE(alias_nbt, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND); 186MODULE_VERSION(alias_nbt, 1); 187MODULE_DEPEND(alias_nbt, libalias, 1, 1, 1); 188#endif 189 190typedef struct { 191 struct in_addr oldaddr; 192 u_short oldport; 193 struct in_addr newaddr; 194 u_short newport; 195 u_short *uh_sum; 196} NBTArguments; 197 198typedef struct { 199 unsigned char type; 200 unsigned char flags; 201 u_short id; 202 struct in_addr source_ip; 203 u_short source_port; 204 u_short len; 205 u_short offset; 206} NbtDataHeader; 207 208#define OpQuery 0 209#define OpUnknown 4 210#define OpRegist 5 211#define OpRelease 6 212#define OpWACK 7 213#define OpRefresh 8 214typedef struct { 215 u_short nametrid; 216 u_short dir: 1, opcode:4, nmflags:7, rcode:4; 217 u_short qdcount; 218 u_short ancount; 219 u_short nscount; 220 u_short arcount; 221} NbtNSHeader; 222 223#define FMT_ERR 0x1 224#define SRV_ERR 0x2 225#define IMP_ERR 0x4 226#define RFS_ERR 0x5 227#define ACT_ERR 0x6 228#define CFT_ERR 0x7 229 230 231#ifdef LIBALIAS_DEBUG 232static void 233PrintRcode(u_char rcode) 234{ 235 236 switch (rcode) { 237 case FMT_ERR: 238 printf("\nFormat Error."); 239 case SRV_ERR: 240 printf("\nSever failure."); 241 case IMP_ERR: 242 printf("\nUnsupported request error.\n"); 243 case RFS_ERR: 244 printf("\nRefused error.\n"); 245 case ACT_ERR: 246 printf("\nActive error.\n"); 247 case CFT_ERR: 248 printf("\nName in conflict error.\n"); 249 default: 250 printf("\n?%c?=%0x\n", '?', rcode); 251 252 } 253} 254 255#endif 256 257 258/* Handling Name field */ 259static u_char * 260AliasHandleName(u_char * p, char *pmax) 261{ 262 263 u_char *s; 264 u_char c; 265 int compress; 266 267 /* Following length field */ 268 269 if (p == NULL || (char *)p >= pmax) 270 return (NULL); 271 272 if (*p & 0xc0) { 273 p = p + 2; 274 if ((char *)p > pmax) 275 return (NULL); 276 return ((u_char *) p); 277 } 278 while ((*p & 0x3f) != 0x00) { 279 s = p + 1; 280 if (*p == 0x20) 281 compress = 1; 282 else 283 compress = 0; 284 285 /* Get next length field */ 286 p = (u_char *) (p + (*p & 0x3f) + 1); 287 if ((char *)p > pmax) { 288 p = NULL; 289 break; 290 } 291#ifdef LIBALIAS_DEBUG 292 printf(":"); 293#endif 294 while (s < p) { 295 if (compress == 1) { 296 c = (u_char) (((((*s & 0x0f) << 4) | (*(s + 1) & 0x0f)) - 0x11)); 297#ifdef LIBALIAS_DEBUG 298 if (isprint(c)) 299 printf("%c", c); 300 else 301 printf("<0x%02x>", c); 302#endif 303 s += 2; 304 } else { 305#ifdef LIBALIAS_DEBUG 306 printf("%c", *s); 307#endif 308 s++; 309 } 310 } 311#ifdef LIBALIAS_DEBUG 312 printf(":"); 313 fflush(stdout); 314#endif 315 } 316 317 /* Set up to out of Name field */ 318 if (p == NULL || (char *)p >= pmax) 319 p = NULL; 320 else 321 p++; 322 return ((u_char *) p); 323} 324 325/* 326 * NetBios Datagram Handler (IP/UDP) 327 */ 328#define DGM_DIRECT_UNIQ 0x10 329#define DGM_DIRECT_GROUP 0x11 330#define DGM_BROADCAST 0x12 331#define DGM_ERROR 0x13 332#define DGM_QUERY 0x14 333#define DGM_POSITIVE_RES 0x15 334#define DGM_NEGATIVE_RES 0x16 335 336static int 337AliasHandleUdpNbt( 338 struct libalias *la, 339 struct ip *pip, /* IP packet to examine/patch */ 340 struct alias_link *lnk, 341 struct in_addr *alias_address, 342 u_short alias_port 343) 344{ 345 struct udphdr *uh; 346 NbtDataHeader *ndh; 347 u_char *p = NULL; 348 char *pmax; 349 350 (void)la; 351 (void)lnk; 352 353 /* Calculate data length of UDP packet */ 354 uh = (struct udphdr *)ip_next(pip); 355 pmax = (char *)uh + ntohs(uh->uh_ulen); 356 357 ndh = (NbtDataHeader *)udp_next(uh); 358 if ((char *)(ndh + 1) > pmax) 359 return (-1); 360#ifdef LIBALIAS_DEBUG 361 printf("\nType=%02x,", ndh->type); 362#endif 363 switch (ndh->type) { 364 case DGM_DIRECT_UNIQ: 365 case DGM_DIRECT_GROUP: 366 case DGM_BROADCAST: 367 p = (u_char *) ndh + 14; 368 p = AliasHandleName(p, pmax); /* Source Name */ 369 p = AliasHandleName(p, pmax); /* Destination Name */ 370 break; 371 case DGM_ERROR: 372 p = (u_char *) ndh + 11; 373 break; 374 case DGM_QUERY: 375 case DGM_POSITIVE_RES: 376 case DGM_NEGATIVE_RES: 377 p = (u_char *) ndh + 10; 378 p = AliasHandleName(p, pmax); /* Destination Name */ 379 break; 380 } 381 if (p == NULL || (char *)p > pmax) 382 p = NULL; 383#ifdef LIBALIAS_DEBUG 384 printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port)); 385#endif 386 /* Doing an IP address and Port number Translation */ 387 if (uh->uh_sum != 0) { 388 int acc; 389 u_short *sptr; 390 391 acc = ndh->source_port; 392 acc -= alias_port; 393 sptr = (u_short *) & (ndh->source_ip); 394 acc += *sptr++; 395 acc += *sptr; 396 sptr = (u_short *) alias_address; 397 acc -= *sptr++; 398 acc -= *sptr; 399 ADJUST_CHECKSUM(acc, uh->uh_sum); 400 } 401 ndh->source_ip = *alias_address; 402 ndh->source_port = alias_port; 403#ifdef LIBALIAS_DEBUG 404 printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port)); 405 fflush(stdout); 406#endif 407 return ((p == NULL) ? -1 : 0); 408} 409 410/* Question Section */ 411#define QS_TYPE_NB 0x0020 412#define QS_TYPE_NBSTAT 0x0021 413#define QS_CLAS_IN 0x0001 414typedef struct { 415 u_short type; /* The type of Request */ 416 u_short class; /* The class of Request */ 417} NBTNsQuestion; 418 419static u_char * 420AliasHandleQuestion( 421 u_short count, 422 NBTNsQuestion * q, 423 char *pmax, 424 NBTArguments * nbtarg) 425{ 426 427 (void)nbtarg; 428 429 while (count != 0) { 430 /* Name Filed */ 431 q = (NBTNsQuestion *) AliasHandleName((u_char *) q, pmax); 432 433 if (q == NULL || (char *)(q + 1) > pmax) { 434 q = NULL; 435 break; 436 } 437 /* Type and Class filed */ 438 switch (ntohs(q->type)) { 439 case QS_TYPE_NB: 440 case QS_TYPE_NBSTAT: 441 q = q + 1; 442 break; 443 default: 444#ifdef LIBALIAS_DEBUG 445 printf("\nUnknown Type on Question %0x\n", ntohs(q->type)); 446#endif 447 break; 448 } 449 count--; 450 } 451 452 /* Set up to out of Question Section */ 453 return ((u_char *) q); 454} 455 456/* Resource Record */ 457#define RR_TYPE_A 0x0001 458#define RR_TYPE_NS 0x0002 459#define RR_TYPE_NULL 0x000a 460#define RR_TYPE_NB 0x0020 461#define RR_TYPE_NBSTAT 0x0021 462#define RR_CLAS_IN 0x0001 463#define SizeOfNsResource 8 464typedef struct { 465 u_short type; 466 u_short class; 467 unsigned int ttl; 468 u_short rdlen; 469} NBTNsResource; 470 471#define SizeOfNsRNB 6 472typedef struct { 473 u_short g: 1 , ont:2, resv:13; 474 struct in_addr addr; 475} NBTNsRNB; 476 477static u_char * 478AliasHandleResourceNB( 479 NBTNsResource * q, 480 char *pmax, 481 NBTArguments * nbtarg) 482{ 483 NBTNsRNB *nb; 484 u_short bcount; 485 486 if (q == NULL || (char *)(q + 1) > pmax) 487 return (NULL); 488 /* Check out a length */ 489 bcount = ntohs(q->rdlen); 490 491 /* Forward to Resource NB position */ 492 nb = (NBTNsRNB *) ((u_char *) q + SizeOfNsResource); 493 494 /* Processing all in_addr array */ 495#ifdef LIBALIAS_DEBUG 496 printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr)); 497 printf("->%s, %dbytes] ", inet_ntoa(nbtarg->newaddr), bcount); 498#endif 499 while (nb != NULL && bcount != 0) { 500 if ((char *)(nb + 1) > pmax) { 501 nb = NULL; 502 break; 503 } 504#ifdef LIBALIAS_DEBUG 505 printf("<%s>", inet_ntoa(nb->addr)); 506#endif 507 if (!bcmp(&nbtarg->oldaddr, &nb->addr, sizeof(struct in_addr))) { 508 if (*nbtarg->uh_sum != 0) { 509 int acc; 510 u_short *sptr; 511 512 sptr = (u_short *) & (nb->addr); 513 acc = *sptr++; 514 acc += *sptr; 515 sptr = (u_short *) & (nbtarg->newaddr); 516 acc -= *sptr++; 517 acc -= *sptr; 518 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum); 519 } 520 nb->addr = nbtarg->newaddr; 521#ifdef LIBALIAS_DEBUG 522 printf("O"); 523#endif 524 } 525#ifdef LIBALIAS_DEBUG 526 else { 527 printf("."); 528 } 529#endif 530 nb = (NBTNsRNB *) ((u_char *) nb + SizeOfNsRNB); 531 bcount -= SizeOfNsRNB; 532 } 533 if (nb == NULL || (char *)(nb + 1) > pmax) { 534 nb = NULL; 535 } 536 return ((u_char *) nb); 537} 538 539#define SizeOfResourceA 6 540typedef struct { 541 struct in_addr addr; 542} NBTNsResourceA; 543 544static u_char * 545AliasHandleResourceA( 546 NBTNsResource * q, 547 char *pmax, 548 NBTArguments * nbtarg) 549{ 550 NBTNsResourceA *a; 551 u_short bcount; 552 553 if (q == NULL || (char *)(q + 1) > pmax) 554 return (NULL); 555 556 /* Forward to Resource A position */ 557 a = (NBTNsResourceA *) ((u_char *) q + sizeof(NBTNsResource)); 558 559 /* Check out of length */ 560 bcount = ntohs(q->rdlen); 561 562 /* Processing all in_addr array */ 563#ifdef LIBALIAS_DEBUG 564 printf("Arec [%s", inet_ntoa(nbtarg->oldaddr)); 565 printf("->%s]", inet_ntoa(nbtarg->newaddr)); 566#endif 567 while (bcount != 0) { 568 if (a == NULL || (char *)(a + 1) > pmax) 569 return (NULL); 570#ifdef LIBALIAS_DEBUG 571 printf("..%s", inet_ntoa(a->addr)); 572#endif 573 if (!bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr))) { 574 if (*nbtarg->uh_sum != 0) { 575 int acc; 576 u_short *sptr; 577 578 sptr = (u_short *) & (a->addr); /* Old */ 579 acc = *sptr++; 580 acc += *sptr; 581 sptr = (u_short *) & nbtarg->newaddr; /* New */ 582 acc -= *sptr++; 583 acc -= *sptr; 584 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum); 585 } 586 a->addr = nbtarg->newaddr; 587 } 588 a++; /* XXXX */ 589 bcount -= SizeOfResourceA; 590 } 591 if (a == NULL || (char *)(a + 1) > pmax) 592 a = NULL; 593 return ((u_char *) a); 594} 595 596typedef struct { 597 u_short opcode:4, flags:8, resv:4; 598} NBTNsResourceNULL; 599 600static u_char * 601AliasHandleResourceNULL( 602 NBTNsResource * q, 603 char *pmax, 604 NBTArguments * nbtarg) 605{ 606 NBTNsResourceNULL *n; 607 u_short bcount; 608 609 (void)nbtarg; 610 611 if (q == NULL || (char *)(q + 1) > pmax) 612 return (NULL); 613 614 /* Forward to Resource NULL position */ 615 n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource)); 616 617 /* Check out of length */ 618 bcount = ntohs(q->rdlen); 619 620 /* Processing all in_addr array */ 621 while (bcount != 0) { 622 if ((char *)(n + 1) > pmax) { 623 n = NULL; 624 break; 625 } 626 n++; 627 bcount -= sizeof(NBTNsResourceNULL); 628 } 629 if ((char *)(n + 1) > pmax) 630 n = NULL; 631 632 return ((u_char *) n); 633} 634 635static u_char * 636AliasHandleResourceNS( 637 NBTNsResource * q, 638 char *pmax, 639 NBTArguments * nbtarg) 640{ 641 NBTNsResourceNULL *n; 642 u_short bcount; 643 644 (void)nbtarg; 645 646 if (q == NULL || (char *)(q + 1) > pmax) 647 return (NULL); 648 649 /* Forward to Resource NULL position */ 650 n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource)); 651 652 /* Check out of length */ 653 bcount = ntohs(q->rdlen); 654 655 /* Resource Record Name Filed */ 656 q = (NBTNsResource *) AliasHandleName((u_char *) n, pmax); /* XXX */ 657 658 if (q == NULL || (char *)((u_char *) n + bcount) > pmax) 659 return (NULL); 660 else 661 return ((u_char *) n + bcount); 662} 663 664typedef struct { 665 u_short numnames; 666} NBTNsResourceNBSTAT; 667 668static u_char * 669AliasHandleResourceNBSTAT( 670 NBTNsResource * q, 671 char *pmax, 672 NBTArguments * nbtarg) 673{ 674 NBTNsResourceNBSTAT *n; 675 u_short bcount; 676 677 (void)nbtarg; 678 679 if (q == NULL || (char *)(q + 1) > pmax) 680 return (NULL); 681 682 /* Forward to Resource NBSTAT position */ 683 n = (NBTNsResourceNBSTAT *) ((u_char *) q + sizeof(NBTNsResource)); 684 685 /* Check out of length */ 686 bcount = ntohs(q->rdlen); 687 688 if (q == NULL || (char *)((u_char *) n + bcount) > pmax) 689 return (NULL); 690 else 691 return ((u_char *) n + bcount); 692} 693 694static u_char * 695AliasHandleResource( 696 u_short count, 697 NBTNsResource * q, 698 char *pmax, 699 NBTArguments 700 * nbtarg) 701{ 702 while (count != 0) { 703 /* Resource Record Name Filed */ 704 q = (NBTNsResource *) AliasHandleName((u_char *) q, pmax); 705 706 if (q == NULL || (char *)(q + 1) > pmax) 707 break; 708#ifdef LIBALIAS_DEBUG 709 printf("type=%02x, count=%d\n", ntohs(q->type), count); 710#endif 711 712 /* Type and Class filed */ 713 switch (ntohs(q->type)) { 714 case RR_TYPE_NB: 715 q = (NBTNsResource *) AliasHandleResourceNB( 716 q, 717 pmax, 718 nbtarg 719 ); 720 break; 721 case RR_TYPE_A: 722 q = (NBTNsResource *) AliasHandleResourceA( 723 q, 724 pmax, 725 nbtarg 726 ); 727 break; 728 case RR_TYPE_NS: 729 q = (NBTNsResource *) AliasHandleResourceNS( 730 q, 731 pmax, 732 nbtarg 733 ); 734 break; 735 case RR_TYPE_NULL: 736 q = (NBTNsResource *) AliasHandleResourceNULL( 737 q, 738 pmax, 739 nbtarg 740 ); 741 break; 742 case RR_TYPE_NBSTAT: 743 q = (NBTNsResource *) AliasHandleResourceNBSTAT( 744 q, 745 pmax, 746 nbtarg 747 ); 748 break; 749 default: 750#ifdef LIBALIAS_DEBUG 751 printf( 752 "\nUnknown Type of Resource %0x\n", 753 ntohs(q->type) 754 ); 755 fflush(stdout); 756#endif 757 break; 758 } 759 count--; 760 } 761 return ((u_char *) q); 762} 763 764static int 765AliasHandleUdpNbtNS( 766 struct libalias *la, 767 struct ip *pip, /* IP packet to examine/patch */ 768 struct alias_link *lnk, 769 struct in_addr *alias_address, 770 u_short * alias_port, 771 struct in_addr *original_address, 772 u_short * original_port) 773{ 774 struct udphdr *uh; 775 NbtNSHeader *nsh; 776 u_char *p; 777 char *pmax; 778 NBTArguments nbtarg; 779 780 (void)la; 781 (void)lnk; 782 783 /* Set up Common Parameter */ 784 nbtarg.oldaddr = *alias_address; 785 nbtarg.oldport = *alias_port; 786 nbtarg.newaddr = *original_address; 787 nbtarg.newport = *original_port; 788 789 /* Calculate data length of UDP packet */ 790 uh = (struct udphdr *)ip_next(pip); 791 nbtarg.uh_sum = &(uh->uh_sum); 792 nsh = (NbtNSHeader *)udp_next(uh); 793 p = (u_char *) (nsh + 1); 794 pmax = (char *)uh + ntohs(uh->uh_ulen); 795 796 if ((char *)(nsh + 1) > pmax) 797 return (-1); 798 799#ifdef LIBALIAS_DEBUG 800 printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x" 801 ", an=%04x, ns=%04x, ar=%04x, [%d]-->", 802 nsh->dir ? "Response" : "Request", 803 nsh->nametrid, 804 nsh->opcode, 805 nsh->nmflags, 806 nsh->rcode, 807 ntohs(nsh->qdcount), 808 ntohs(nsh->ancount), 809 ntohs(nsh->nscount), 810 ntohs(nsh->arcount), 811 (u_char *) p - (u_char *) nsh 812 ); 813#endif 814 815 /* Question Entries */ 816 if (ntohs(nsh->qdcount) != 0) { 817 p = AliasHandleQuestion( 818 ntohs(nsh->qdcount), 819 (NBTNsQuestion *) p, 820 pmax, 821 &nbtarg 822 ); 823 } 824 /* Answer Resource Records */ 825 if (ntohs(nsh->ancount) != 0) { 826 p = AliasHandleResource( 827 ntohs(nsh->ancount), 828 (NBTNsResource *) p, 829 pmax, 830 &nbtarg 831 ); 832 } 833 /* Authority Resource Recodrs */ 834 if (ntohs(nsh->nscount) != 0) { 835 p = AliasHandleResource( 836 ntohs(nsh->nscount), 837 (NBTNsResource *) p, 838 pmax, 839 &nbtarg 840 ); 841 } 842 /* Additional Resource Recodrs */ 843 if (ntohs(nsh->arcount) != 0) { 844 p = AliasHandleResource( 845 ntohs(nsh->arcount), 846 (NBTNsResource *) p, 847 pmax, 848 &nbtarg 849 ); 850 } 851#ifdef LIBALIAS_DEBUG 852 PrintRcode(nsh->rcode); 853#endif 854 return ((p == NULL) ? -1 : 0); 855} 856