alias_nbt.c revision 36321
136321Samurai/* 236321Samurai * Written by Atsushi Murai <amurai@spec.co.jp> 336321Samurai * 436321Samurai * Copyright (C) 1998, System Planning and Engineering Co. All rights reserverd. 536321Samurai * 636321Samurai * Redistribution and use in source and binary forms are permitted 736321Samurai * provided that the above copyright notice and this paragraph are 836321Samurai * duplicated in all such forms and that any documentation, 936321Samurai * advertising materials, and other materials related to such 1036321Samurai * distribution and use acknowledge that the software was developed 1136321Samurai * by the System Planning and Engineering Co. The name of the 1236321Samurai * SPEC may not be used to endorse or promote products derived 1336321Samurai * from this software without specific prior written permission. 1436321Samurai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1536321Samurai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1636321Samurai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1736321Samurai * 1836321Samurai * $Id:$ 1936321Samurai * 2036321Samurai * TODO: 2136321Samurai * oClean up. 2236321Samurai * oConsidering for word alignment for other platform. 2336321Samurai */ 2436321Samurai/* 2536321Samurai alias_nbt.c performs special processing for NetBios over TCP/IP 2636321Samurai sessions by UDP. 2736321Samurai 2836321Samurai Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>) 2936321Samurai 3036321Samurai See HISTORY file for record of revisions. 3136321Samurai*/ 3236321Samurai 3336321Samurai/* Includes */ 3436321Samurai#include <ctype.h> 3536321Samurai#include <stdio.h> 3636321Samurai#include <string.h> 3736321Samurai#include <sys/types.h> 3836321Samurai#include <netinet/in_systm.h> 3936321Samurai#include <netinet/in.h> 4036321Samurai#include <arpa/inet.h> 4136321Samurai#include <netinet/ip.h> 4236321Samurai#include <netinet/udp.h> 4336321Samurai#include <netinet/tcp.h> 4436321Samurai 4536321Samurai#include "alias_local.h" 4636321Samurai 4736321Samurai#define ADJUST_CHECKSUM(acc, cksum) { \ 4836321Samurai acc += cksum; \ 4936321Samurai if (acc < 0) \ 5036321Samurai { \ 5136321Samurai acc = -acc; \ 5236321Samurai acc = (acc >> 16) + (acc & 0xffff); \ 5336321Samurai acc += acc >> 16; \ 5436321Samurai cksum = (u_short) ~acc; \ 5536321Samurai } \ 5636321Samurai else \ 5736321Samurai { \ 5836321Samurai acc = (acc >> 16) + (acc & 0xffff); \ 5936321Samurai acc += acc >> 16; \ 6036321Samurai cksum = (u_short) acc; \ 6136321Samurai } \ 6236321Samurai} 6336321Samurai 6436321Samuraitypedef struct { 6536321Samurai struct in_addr oldaddr; 6636321Samurai u_short oldport; 6736321Samurai struct in_addr newaddr; 6836321Samurai u_short newport; 6936321Samurai u_short *uh_sum; 7036321Samurai} NBTArguments; 7136321Samurai 7236321Samuraitypedef struct { 7336321Samurai unsigned char type; 7436321Samurai unsigned char flags; 7536321Samurai u_short id; 7636321Samurai struct in_addr source_ip; 7736321Samurai u_short source_port; 7836321Samurai u_short len; 7936321Samurai u_short offset; 8036321Samurai} NbtDataHeader; 8136321Samurai 8236321Samurai#define OpQuery 0 8336321Samurai#define OpUnknown 4 8436321Samurai#define OpRegist 5 8536321Samurai#define OpRelease 6 8636321Samurai#define OpWACK 7 8736321Samurai#define OpRefresh 8 8836321Samuraitypedef struct { 8936321Samurai u_short nametrid; 9036321Samurai u_short dir:1, opcode:4, nmflags:7, rcode:4; 9136321Samurai u_short qdcount; 9236321Samurai u_short ancount; 9336321Samurai u_short nscount; 9436321Samurai u_short arcount; 9536321Samurai} NbtNSHeader; 9636321Samurai 9736321Samurai#define FMT_ERR 0x1 9836321Samurai#define SRV_ERR 0x2 9936321Samurai#define IMP_ERR 0x4 10036321Samurai#define RFS_ERR 0x5 10136321Samurai#define ACT_ERR 0x6 10236321Samurai#define CFT_ERR 0x7 10336321Samurai 10436321Samurai/******************************************************************* 10536321Samurai * copy an IP address from one buffer to another * 10636321Samurai *******************************************************************/ 10736321Samuraivoid putip(void *dest,void *src) 10836321Samurai{ 10936321Samurai memcpy(dest,src,4); 11036321Samurai} 11136321Samurai 11236321Samuraivoid PrintRcode( u_char rcode ) { 11336321Samurai 11436321Samurai switch (rcode) { 11536321Samurai case FMT_ERR: 11636321Samurai printf("\nFormat Error."); 11736321Samurai case SRV_ERR: 11836321Samurai printf("\nSever failure."); 11936321Samurai case IMP_ERR: 12036321Samurai printf("\nUnsupported request error.\n"); 12136321Samurai case RFS_ERR: 12236321Samurai printf("\nRefused error.\n"); 12336321Samurai case ACT_ERR: 12436321Samurai printf("\nActive error.\n"); 12536321Samurai case CFT_ERR: 12636321Samurai printf("\nName in conflict error.\n"); 12736321Samurai default: 12836321Samurai printf("\n???=%0x\n", rcode ); 12936321Samurai 13036321Samurai } 13136321Samurai} 13236321Samurai 13336321Samurai 13436321Samurai/* Handling Name field */ 13536321Samuraiu_char *AliasHandleName ( u_char *p ) { 13636321Samurai 13736321Samurai u_char *s; 13836321Samurai u_char c; 13936321Samurai int compress; 14036321Samurai 14136321Samurai /* Following length field */ 14236321Samurai if (*p & 0xc0 ) { 14336321Samurai p = p + 2; 14436321Samurai return ((u_char *)p); 14536321Samurai } 14636321Samurai while ( ( *p & 0x3f) != 0x00 ) { 14736321Samurai s = p + 1; 14836321Samurai if ( *p == 0x20 ) 14936321Samurai compress = 1; 15036321Samurai else 15136321Samurai compress = 0; 15236321Samurai 15336321Samurai /* Get next length field */ 15436321Samurai p = (u_char *)(p + (*p & 0x3f) + 1); 15536321Samurai#ifdef DEBUG 15636321Samurai printf(":"); 15736321Samurai#endif 15836321Samurai while (s < p) { 15936321Samurai if ( compress == 1 ) { 16036321Samurai c = (u_char )(((((*s & 0x0f) << 4) | (*(s+1) & 0x0f)) - 0x11)); 16136321Samurai#ifdef DEBUG 16236321Samurai if (isprint( c ) ) 16336321Samurai printf("%c", c ); 16436321Samurai else 16536321Samurai printf("<0x%02x>", c ); 16636321Samurai#endif 16736321Samurai s +=2; 16836321Samurai } else { 16936321Samurai#ifdef DEBUG 17036321Samurai printf("%c", *s); 17136321Samurai#endif 17236321Samurai s++; 17336321Samurai } 17436321Samurai } 17536321Samurai#ifdef DEBUG 17636321Samurai printf(":"); 17736321Samurai#endif 17836321Samurai fflush(stdout); 17936321Samurai } 18036321Samurai 18136321Samurai /* Set up to out of Name field */ 18236321Samurai p++; 18336321Samurai return ((u_char *)p); 18436321Samurai} 18536321Samurai 18636321Samurai/* 18736321Samurai * NetBios Datagram Handler (IP/UDP) 18836321Samurai */ 18936321Samurai#define DGM_DIRECT_UNIQ 0x10 19036321Samurai#define DGM_DIRECT_GROUP 0x11 19136321Samurai#define DGM_BROADCAST 0x12 19236321Samurai#define DGM_ERROR 0x13 19336321Samurai#define DGM_QUERY 0x14 19436321Samurai#define DGM_POSITIVE_RES 0x15 19536321Samurai#define DGM_NEGATIVE_RES 0x16 19636321Samurai 19736321Samuraivoid AliasHandleUdpNbt( 19836321Samurai struct ip *pip, /* IP packet to examine/patch */ 19936321Samurai struct alias_link *link, 20036321Samurai struct in_addr *alias_address, 20136321Samurai u_short alias_port ) 20236321Samurai{ 20336321Samurai struct udphdr * uh; 20436321Samurai NbtDataHeader *ndh; 20536321Samurai u_char *p; 20636321Samurai 20736321Samurai /* Calculate data length of UDP packet */ 20836321Samurai uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 20936321Samurai ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr))); 21036321Samurai#ifdef DEBUG 21136321Samurai printf("\nType=%02x,", ndh->type ); 21236321Samurai#endif 21336321Samurai switch ( ndh->type ) { 21436321Samurai case DGM_DIRECT_UNIQ: 21536321Samurai case DGM_DIRECT_GROUP: 21636321Samurai case DGM_BROADCAST: 21736321Samurai p = (u_char *)ndh + 14; 21836321Samurai p = AliasHandleName ( p ); /* Source Name */ 21936321Samurai p = AliasHandleName ( p ); /* Destination Name */ 22036321Samurai break; 22136321Samurai case DGM_ERROR: 22236321Samurai p = (u_char *)ndh + 11; 22336321Samurai break; 22436321Samurai case DGM_QUERY: 22536321Samurai case DGM_POSITIVE_RES: 22636321Samurai case DGM_NEGATIVE_RES: 22736321Samurai p = (u_char *)ndh + 10; 22836321Samurai p = AliasHandleName ( p ); /* Destination Name */ 22936321Samurai break; 23036321Samurai } 23136321Samurai#ifdef DEBUG 23236321Samurai printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); 23336321Samurai#endif 23436321Samurai /* Doing a IP address and Port number Translation */ 23536321Samurai if ( uh->uh_sum != 0 ) { 23636321Samurai int acc; 23736321Samurai u_short *sptr; 23836321Samurai acc = ndh->source_port; 23936321Samurai acc -= alias_port; 24036321Samurai sptr = (u_short *) &(ndh->source_ip); 24136321Samurai acc += *sptr++; 24236321Samurai acc += *sptr; 24336321Samurai sptr = (u_short *) alias_address; 24436321Samurai acc -= *sptr++; 24536321Samurai acc -= *sptr; 24636321Samurai ADJUST_CHECKSUM(acc, uh->uh_sum) 24736321Samurai } 24836321Samurai ndh->source_ip = *alias_address; 24936321Samurai ndh->source_port = alias_port; 25036321Samurai#ifdef DEBUG 25136321Samurai printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); 25236321Samurai fflush(stdout); 25336321Samurai#endif 25436321Samurai} 25536321Samurai/* Question Section */ 25636321Samurai#define QS_TYPE_NB 0x0020 25736321Samurai#define QS_TYPE_NBSTAT 0x0021 25836321Samurai#define QS_CLAS_IN 0x0001 25936321Samuraitypedef struct { 26036321Samurai u_short type; /* The type of Request */ 26136321Samurai u_short class; /* The class of Request */ 26236321Samurai} NBTNsQuestion; 26336321Samurai 26436321Samuraiu_char *AliasHandleQuestion(u_short count, 26536321Samurai NBTNsQuestion *q, 26636321Samurai NBTArguments *nbtarg) 26736321Samurai{ 26836321Samurai 26936321Samurai while ( count != 0 ) { 27036321Samurai /* Name Filed */ 27136321Samurai q = (NBTNsQuestion *)AliasHandleName((u_char *)q ); 27236321Samurai 27336321Samurai /* Type and Class filed */ 27436321Samurai switch ( ntohs(q->type) ) { 27536321Samurai case QS_TYPE_NB: 27636321Samurai case QS_TYPE_NBSTAT: 27736321Samurai q= q+1; 27836321Samurai break; 27936321Samurai default: 28036321Samurai printf("\nUnknown Type on Question %0x\n", ntohs(q->type) ); 28136321Samurai break; 28236321Samurai } 28336321Samurai count--; 28436321Samurai } 28536321Samurai 28636321Samurai /* Set up to out of Question Section */ 28736321Samurai return ((u_char *)q); 28836321Samurai} 28936321Samurai 29036321Samurai/* Resource Record */ 29136321Samurai#define RR_TYPE_A 0x0001 29236321Samurai#define RR_TYPE_NS 0x0002 29336321Samurai#define RR_TYPE_NULL 0x000a 29436321Samurai#define RR_TYPE_NB 0x0020 29536321Samurai#define RR_TYPE_NBSTAT 0x0021 29636321Samurai#define RR_CLAS_IN 0x0001 29736321Samurai#define SizeOfNsResource 8 29836321Samuraitypedef struct { 29936321Samurai u_short type; 30036321Samurai u_short class; 30136321Samurai unsigned int ttl; 30236321Samurai u_short rdlen; 30336321Samurai} NBTNsResource; 30436321Samurai 30536321Samurai#define SizeOfNsRNB 6 30636321Samuraitypedef struct { 30736321Samurai u_short g:1, ont:2, resv:13; 30836321Samurai struct in_addr addr; 30936321Samurai} NBTNsRNB; 31036321Samurai 31136321Samuraiu_char *AliasHandleResourceNB( NBTNsResource *q, 31236321Samurai NBTArguments *nbtarg) 31336321Samurai{ 31436321Samurai NBTNsRNB *nb; 31536321Samurai u_short bcount; 31636321Samurai 31736321Samurai /* Check out a length */ 31836321Samurai bcount = ntohs(q->rdlen); 31936321Samurai 32036321Samurai /* Forward to Resource NB position */ 32136321Samurai nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource); 32236321Samurai 32336321Samurai /* Processing all in_addr array */ 32436321Samurai#ifdef DEBUG 32536321Samurai printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr)); 32636321Samurai printf("->%s, %dbytes] ",inet_ntoa(nbtarg->newaddr ), bcount); 32736321Samurai#endif 32836321Samurai while ( bcount != 0 ) { 32936321Samurai#ifdef DEBUG 33036321Samurai printf("<%s>", inet_ntoa(nb->addr) ); 33136321Samurai#endif 33236321Samurai if (!bcmp(&nbtarg->oldaddr,&nb->addr, sizeof(struct in_addr) ) ) { 33336321Samurai if ( *nbtarg->uh_sum != 0 ) { 33436321Samurai int acc; 33536321Samurai u_short *sptr; 33636321Samurai 33736321Samurai sptr = (u_short *) &(nb->addr); 33836321Samurai acc = *sptr++; 33936321Samurai acc += *sptr; 34036321Samurai sptr = (u_short *) &(nbtarg->newaddr); 34136321Samurai acc -= *sptr++; 34236321Samurai acc -= *sptr; 34336321Samurai ADJUST_CHECKSUM(acc, *nbtarg->uh_sum) 34436321Samurai } 34536321Samurai 34636321Samurai nb->addr = nbtarg->newaddr; 34736321Samurai#ifdef DEBUG 34836321Samurai printf("O"); 34936321Samurai#endif 35036321Samurai } 35136321Samurai#ifdef DEBUG 35236321Samurai else { 35336321Samurai printf("."); 35436321Samurai } 35536321Samurai#endif 35636321Samurai nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB); 35736321Samurai bcount -= SizeOfNsRNB; 35836321Samurai } 35936321Samurai 36036321Samurai return ((u_char *)nb); 36136321Samurai} 36236321Samurai 36336321Samurai#define SizeOfResourceA 6 36436321Samuraitypedef struct { 36536321Samurai struct in_addr addr; 36636321Samurai} NBTNsResourceA; 36736321Samurai 36836321Samuraiu_char *AliasHandleResourceA( NBTNsResource *q, 36936321Samurai NBTArguments *nbtarg) 37036321Samurai{ 37136321Samurai NBTNsResourceA *a; 37236321Samurai u_short bcount; 37336321Samurai 37436321Samurai /* Forward to Resource A position */ 37536321Samurai a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) ); 37636321Samurai 37736321Samurai /* Check out of length */ 37836321Samurai bcount = ntohs(q->rdlen); 37936321Samurai 38036321Samurai /* Processing all in_addr array */ 38136321Samurai#ifdef DEBUG 38236321Samurai printf("Arec [%s", inet_ntoa(nbtarg->oldaddr)); 38336321Samurai printf("->%s]",inet_ntoa(nbtarg->newaddr )); 38436321Samurai#endif 38536321Samurai while ( bcount != 0 ) { 38636321Samurai#ifdef DEBUG 38736321Samurai printf("..%s", inet_ntoa(a->addr) ); 38836321Samurai#endif 38936321Samurai if ( !bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr) ) ) { 39036321Samurai if ( *nbtarg->uh_sum != 0 ) { 39136321Samurai int acc; 39236321Samurai u_short *sptr; 39336321Samurai 39436321Samurai sptr = (u_short *) &(a->addr); /* Old */ 39536321Samurai acc = *sptr++; 39636321Samurai acc += *sptr; 39736321Samurai sptr = (u_short *) &nbtarg->newaddr; /* New */ 39836321Samurai acc -= *sptr++; 39936321Samurai acc -= *sptr; 40036321Samurai ADJUST_CHECKSUM(acc, *nbtarg->uh_sum) 40136321Samurai } 40236321Samurai 40336321Samurai a->addr = nbtarg->newaddr; 40436321Samurai } 40536321Samurai a++; /*XXXX*/ 40636321Samurai bcount -= SizeOfResourceA; 40736321Samurai } 40836321Samurai return ((u_char *)a); 40936321Samurai} 41036321Samurai 41136321Samuraitypedef struct { 41236321Samurai u_short opcode:4, flags:8, resv:4; 41336321Samurai} NBTNsResourceNULL; 41436321Samurai 41536321Samuraiu_char *AliasHandleResourceNULL( NBTNsResource *q, 41636321Samurai NBTArguments *nbtarg) 41736321Samurai{ 41836321Samurai NBTNsResourceNULL *n; 41936321Samurai u_short bcount; 42036321Samurai 42136321Samurai /* Forward to Resource NULL position */ 42236321Samurai n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); 42336321Samurai 42436321Samurai /* Check out of length */ 42536321Samurai bcount = ntohs(q->rdlen); 42636321Samurai 42736321Samurai /* Processing all in_addr array */ 42836321Samurai while ( bcount != 0 ) { 42936321Samurai n++; 43036321Samurai bcount -= sizeof(NBTNsResourceNULL); 43136321Samurai } 43236321Samurai 43336321Samurai return ((u_char *)n); 43436321Samurai} 43536321Samurai 43636321Samuraiu_char *AliasHandleResourceNS( NBTNsResource *q, 43736321Samurai NBTArguments *nbtarg) 43836321Samurai{ 43936321Samurai NBTNsResourceNULL *n; 44036321Samurai u_short bcount; 44136321Samurai 44236321Samurai /* Forward to Resource NULL position */ 44336321Samurai n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); 44436321Samurai 44536321Samurai /* Check out of length */ 44636321Samurai bcount = ntohs(q->rdlen); 44736321Samurai 44836321Samurai /* Resource Record Name Filed */ 44936321Samurai q = (NBTNsResource *)AliasHandleName( (u_char *)n ); /* XXX */ 45036321Samurai 45136321Samurai return ((u_char *)n + bcount); 45236321Samurai} 45336321Samurai 45436321Samuraitypedef struct { 45536321Samurai u_short numnames; 45636321Samurai} NBTNsResourceNBSTAT; 45736321Samurai 45836321Samuraiu_char *AliasHandleResourceNBSTAT( NBTNsResource *q, 45936321Samurai NBTArguments *nbtarg) 46036321Samurai{ 46136321Samurai NBTNsResourceNBSTAT *n; 46236321Samurai u_short bcount; 46336321Samurai 46436321Samurai /* Forward to Resource NBSTAT position */ 46536321Samurai n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) ); 46636321Samurai 46736321Samurai /* Check out of length */ 46836321Samurai bcount = ntohs(q->rdlen); 46936321Samurai 47036321Samurai return ((u_char *)n + bcount); 47136321Samurai} 47236321Samurai 47336321Samuraiu_char *AliasHandleResource(u_short count, 47436321Samurai NBTNsResource *q, 47536321Samurai NBTArguments *nbtarg) 47636321Samurai{ 47736321Samurai while ( count != 0 ) { 47836321Samurai /* Resource Record Name Filed */ 47936321Samurai q = (NBTNsResource *)AliasHandleName( (u_char *)q ); 48036321Samurai#ifdef DEBUG 48136321Samurai printf("type=%02x, count=%d\n", ntohs(q->type), count ); 48236321Samurai#endif 48336321Samurai 48436321Samurai /* Type and Class filed */ 48536321Samurai switch ( ntohs(q->type) ) { 48636321Samurai case RR_TYPE_NB: 48736321Samurai q = (NBTNsResource *)AliasHandleResourceNB( q, nbtarg ); 48836321Samurai break; 48936321Samurai case RR_TYPE_A: 49036321Samurai q = (NBTNsResource *)AliasHandleResourceA( q, nbtarg ); 49136321Samurai break; 49236321Samurai case RR_TYPE_NS: 49336321Samurai q = (NBTNsResource *)AliasHandleResourceNS( q, nbtarg ); 49436321Samurai break; 49536321Samurai case RR_TYPE_NULL: 49636321Samurai q = (NBTNsResource *)AliasHandleResourceNULL( q, nbtarg ); 49736321Samurai break; 49836321Samurai case RR_TYPE_NBSTAT: 49936321Samurai q = (NBTNsResource *)AliasHandleResourceNBSTAT( q, nbtarg ); 50036321Samurai break; 50136321Samurai default: printf("\nUnknown Type of Resource %0x\n", 50236321Samurai ntohs(q->type) ); 50336321Samurai break; 50436321Samurai } 50536321Samurai count--; 50636321Samurai } 50736321Samurai fflush(stdout); 50836321Samurai return ((u_char *)q); 50936321Samurai} 51036321Samurai 51136321Samuraivoid AliasHandleUdpNbtNS( 51236321Samurai struct ip *pip, /* IP packet to examine/patch */ 51336321Samurai struct alias_link *link, 51436321Samurai struct in_addr *alias_address, 51536321Samurai u_short *alias_port, 51636321Samurai struct in_addr *original_address, 51736321Samurai u_short *original_port ) 51836321Samurai{ 51936321Samurai struct udphdr * uh; 52036321Samurai NbtNSHeader * nsh; 52136321Samurai u_short dlen; 52236321Samurai u_char * p; 52336321Samurai NBTArguments nbtarg; 52436321Samurai 52536321Samurai /* Set up Common Parameter */ 52636321Samurai nbtarg.oldaddr = *alias_address; 52736321Samurai nbtarg.oldport = *alias_port; 52836321Samurai nbtarg.newaddr = *original_address; 52936321Samurai nbtarg.newport = *original_port; 53036321Samurai 53136321Samurai /* Calculate data length of UDP packet */ 53236321Samurai uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 53336321Samurai nbtarg.uh_sum = &(uh->uh_sum); 53436321Samurai dlen = ntohs( uh->uh_ulen ); 53536321Samurai nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr))); 53636321Samurai p = (u_char *)(nsh + 1); 53736321Samurai 53836321Samurai#ifdef DEBUG 53936321Samurai printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x, an=%04x, ns=%04x, ar=%04x, [%d]-->", 54036321Samurai nsh->dir ? "Response": "Request", 54136321Samurai nsh->nametrid, 54236321Samurai nsh->opcode, 54336321Samurai nsh->nmflags, 54436321Samurai nsh->rcode, 54536321Samurai ntohs(nsh->qdcount), 54636321Samurai ntohs(nsh->ancount), 54736321Samurai ntohs(nsh->nscount), 54836321Samurai ntohs(nsh->arcount), 54936321Samurai (u_char *)p -(u_char *)nsh); 55036321Samurai#endif 55136321Samurai 55236321Samurai /* Question Entries */ 55336321Samurai if (ntohs(nsh->qdcount) !=0 ) { 55436321Samurai p = AliasHandleQuestion(ntohs(nsh->qdcount), (NBTNsQuestion *)p, &nbtarg ); 55536321Samurai } 55636321Samurai 55736321Samurai /* Answer Resource Records */ 55836321Samurai if (ntohs(nsh->ancount) !=0 ) { 55936321Samurai p = AliasHandleResource(ntohs(nsh->ancount), (NBTNsResource *)p, &nbtarg ); 56036321Samurai } 56136321Samurai 56236321Samurai /* Authority Resource Recodrs */ 56336321Samurai if (ntohs(nsh->nscount) !=0 ) { 56436321Samurai p = AliasHandleResource(ntohs(nsh->nscount), (NBTNsResource *)p, &nbtarg ); 56536321Samurai } 56636321Samurai 56736321Samurai /* Additional Resource Recodrs */ 56836321Samurai if (ntohs(nsh->arcount) !=0 ) { 56936321Samurai p = AliasHandleResource(ntohs(nsh->arcount), (NBTNsResource *)p, &nbtarg ); 57036321Samurai } 57136321Samurai 57236321Samurai#ifdef DEBUG 57336321Samurai PrintRcode(nsh->rcode); 57436321Samurai#endif 57536321Samurai return; 57636321Samurai} 577