alias_nbt.c revision 44616
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 * 1844616Sbrian * $Id: alias_nbt.c,v 1.2 1998/12/14 02:25:32 dillon Exp $ 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 10544616Sbrian#ifdef DEBUG 10644616Sbrianstatic void PrintRcode( u_char rcode ) { 10736321Samurai 10836321Samurai switch (rcode) { 10936321Samurai case FMT_ERR: 11036321Samurai printf("\nFormat Error."); 11136321Samurai case SRV_ERR: 11236321Samurai printf("\nSever failure."); 11336321Samurai case IMP_ERR: 11436321Samurai printf("\nUnsupported request error.\n"); 11536321Samurai case RFS_ERR: 11636321Samurai printf("\nRefused error.\n"); 11736321Samurai case ACT_ERR: 11836321Samurai printf("\nActive error.\n"); 11936321Samurai case CFT_ERR: 12036321Samurai printf("\nName in conflict error.\n"); 12136321Samurai default: 12236321Samurai printf("\n???=%0x\n", rcode ); 12336321Samurai 12436321Samurai } 12536321Samurai} 12644616Sbrian#endif 12736321Samurai 12836321Samurai 12936321Samurai/* Handling Name field */ 13044616Sbrianstatic u_char *AliasHandleName ( u_char *p, char *pmax ) { 13136321Samurai 13236321Samurai u_char *s; 13336321Samurai u_char c; 13436321Samurai int compress; 13536321Samurai 13636321Samurai /* Following length field */ 13741759Sdillon 13841759Sdillon if (p == NULL || (char *)p >= pmax) 13941759Sdillon return(NULL); 14041759Sdillon 14136321Samurai if (*p & 0xc0 ) { 14236321Samurai p = p + 2; 14341759Sdillon if ((char *)p > pmax) 14441759Sdillon return(NULL); 14536321Samurai return ((u_char *)p); 14636321Samurai } 14736321Samurai while ( ( *p & 0x3f) != 0x00 ) { 14836321Samurai s = p + 1; 14936321Samurai if ( *p == 0x20 ) 15036321Samurai compress = 1; 15136321Samurai else 15236321Samurai compress = 0; 15336321Samurai 15436321Samurai /* Get next length field */ 15536321Samurai p = (u_char *)(p + (*p & 0x3f) + 1); 15641759Sdillon if ((char *)p > pmax) { 15741759Sdillon p = NULL; 15841759Sdillon break; 15941759Sdillon } 16036321Samurai#ifdef DEBUG 16136321Samurai printf(":"); 16236321Samurai#endif 16336321Samurai while (s < p) { 16436321Samurai if ( compress == 1 ) { 16536321Samurai c = (u_char )(((((*s & 0x0f) << 4) | (*(s+1) & 0x0f)) - 0x11)); 16636321Samurai#ifdef DEBUG 16736321Samurai if (isprint( c ) ) 16836321Samurai printf("%c", c ); 16936321Samurai else 17036321Samurai printf("<0x%02x>", c ); 17136321Samurai#endif 17236321Samurai s +=2; 17336321Samurai } else { 17436321Samurai#ifdef DEBUG 17536321Samurai printf("%c", *s); 17636321Samurai#endif 17736321Samurai s++; 17836321Samurai } 17936321Samurai } 18036321Samurai#ifdef DEBUG 18136321Samurai printf(":"); 18236321Samurai#endif 18336321Samurai fflush(stdout); 18436321Samurai } 18536321Samurai 18636321Samurai /* Set up to out of Name field */ 18741759Sdillon if (p == NULL || (char *)p >= pmax) 18841759Sdillon p = NULL; 18941759Sdillon else 19041759Sdillon p++; 19136321Samurai return ((u_char *)p); 19236321Samurai} 19336321Samurai 19436321Samurai/* 19536321Samurai * NetBios Datagram Handler (IP/UDP) 19636321Samurai */ 19736321Samurai#define DGM_DIRECT_UNIQ 0x10 19836321Samurai#define DGM_DIRECT_GROUP 0x11 19936321Samurai#define DGM_BROADCAST 0x12 20036321Samurai#define DGM_ERROR 0x13 20136321Samurai#define DGM_QUERY 0x14 20236321Samurai#define DGM_POSITIVE_RES 0x15 20336321Samurai#define DGM_NEGATIVE_RES 0x16 20436321Samurai 20541759Sdillonint AliasHandleUdpNbt( 20636321Samurai struct ip *pip, /* IP packet to examine/patch */ 20736321Samurai struct alias_link *link, 20836321Samurai struct in_addr *alias_address, 20941759Sdillon u_short alias_port 21041759Sdillon) { 21136321Samurai struct udphdr * uh; 21236321Samurai NbtDataHeader *ndh; 21341759Sdillon u_char *p = NULL; 21441759Sdillon char *pmax; 21536321Samurai 21636321Samurai /* Calculate data length of UDP packet */ 21736321Samurai uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 21841759Sdillon pmax = (char *)uh + ntohs( uh->uh_ulen ); 21941759Sdillon 22036321Samurai ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr))); 22141759Sdillon if ((char *)(ndh + 1) > pmax) 22241759Sdillon return(-1); 22336321Samurai#ifdef DEBUG 22436321Samurai printf("\nType=%02x,", ndh->type ); 22536321Samurai#endif 22636321Samurai switch ( ndh->type ) { 22736321Samurai case DGM_DIRECT_UNIQ: 22836321Samurai case DGM_DIRECT_GROUP: 22936321Samurai case DGM_BROADCAST: 23036321Samurai p = (u_char *)ndh + 14; 23141759Sdillon p = AliasHandleName ( p, pmax ); /* Source Name */ 23241759Sdillon p = AliasHandleName ( p, pmax ); /* Destination Name */ 23336321Samurai break; 23436321Samurai case DGM_ERROR: 23536321Samurai p = (u_char *)ndh + 11; 23636321Samurai break; 23736321Samurai case DGM_QUERY: 23836321Samurai case DGM_POSITIVE_RES: 23936321Samurai case DGM_NEGATIVE_RES: 24036321Samurai p = (u_char *)ndh + 10; 24141759Sdillon p = AliasHandleName ( p, pmax ); /* Destination Name */ 24236321Samurai break; 24336321Samurai } 24441759Sdillon if (p == NULL || (char *)p > pmax) 24541759Sdillon p = NULL; 24636321Samurai#ifdef DEBUG 24736321Samurai printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); 24836321Samurai#endif 24936321Samurai /* Doing a IP address and Port number Translation */ 25036321Samurai if ( uh->uh_sum != 0 ) { 25136321Samurai int acc; 25236321Samurai u_short *sptr; 25336321Samurai acc = ndh->source_port; 25436321Samurai acc -= alias_port; 25536321Samurai sptr = (u_short *) &(ndh->source_ip); 25636321Samurai acc += *sptr++; 25736321Samurai acc += *sptr; 25836321Samurai sptr = (u_short *) alias_address; 25936321Samurai acc -= *sptr++; 26036321Samurai acc -= *sptr; 26136321Samurai ADJUST_CHECKSUM(acc, uh->uh_sum) 26236321Samurai } 26336321Samurai ndh->source_ip = *alias_address; 26436321Samurai ndh->source_port = alias_port; 26536321Samurai#ifdef DEBUG 26636321Samurai printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); 26736321Samurai fflush(stdout); 26836321Samurai#endif 26941759Sdillon return((p == NULL) ? -1 : 0); 27036321Samurai} 27136321Samurai/* Question Section */ 27236321Samurai#define QS_TYPE_NB 0x0020 27336321Samurai#define QS_TYPE_NBSTAT 0x0021 27436321Samurai#define QS_CLAS_IN 0x0001 27536321Samuraitypedef struct { 27636321Samurai u_short type; /* The type of Request */ 27736321Samurai u_short class; /* The class of Request */ 27836321Samurai} NBTNsQuestion; 27936321Samurai 28044616Sbrianstatic u_char * 28141759SdillonAliasHandleQuestion( 28241759Sdillon u_short count, 28336321Samurai NBTNsQuestion *q, 28441759Sdillon char *pmax, 28536321Samurai NBTArguments *nbtarg) 28636321Samurai{ 28736321Samurai 28836321Samurai while ( count != 0 ) { 28936321Samurai /* Name Filed */ 29041759Sdillon q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax); 29136321Samurai 29241759Sdillon if (q == NULL || (char *)(q + 1) > pmax) { 29341759Sdillon q = NULL; 29441759Sdillon break; 29541759Sdillon } 29641759Sdillon 29736321Samurai /* Type and Class filed */ 29836321Samurai switch ( ntohs(q->type) ) { 29936321Samurai case QS_TYPE_NB: 30036321Samurai case QS_TYPE_NBSTAT: 30136321Samurai q= q+1; 30236321Samurai break; 30336321Samurai default: 30444616Sbrian#ifdef DEBUG 30536321Samurai printf("\nUnknown Type on Question %0x\n", ntohs(q->type) ); 30644616Sbrian#endif 30736321Samurai break; 30836321Samurai } 30936321Samurai count--; 31036321Samurai } 31136321Samurai 31236321Samurai /* Set up to out of Question Section */ 31336321Samurai return ((u_char *)q); 31436321Samurai} 31536321Samurai 31636321Samurai/* Resource Record */ 31736321Samurai#define RR_TYPE_A 0x0001 31836321Samurai#define RR_TYPE_NS 0x0002 31936321Samurai#define RR_TYPE_NULL 0x000a 32036321Samurai#define RR_TYPE_NB 0x0020 32136321Samurai#define RR_TYPE_NBSTAT 0x0021 32236321Samurai#define RR_CLAS_IN 0x0001 32336321Samurai#define SizeOfNsResource 8 32436321Samuraitypedef struct { 32536321Samurai u_short type; 32636321Samurai u_short class; 32736321Samurai unsigned int ttl; 32836321Samurai u_short rdlen; 32936321Samurai} NBTNsResource; 33036321Samurai 33136321Samurai#define SizeOfNsRNB 6 33236321Samuraitypedef struct { 33336321Samurai u_short g:1, ont:2, resv:13; 33436321Samurai struct in_addr addr; 33536321Samurai} NBTNsRNB; 33636321Samurai 33744616Sbrianstatic u_char * 33841759SdillonAliasHandleResourceNB( 33941759Sdillon NBTNsResource *q, 34041759Sdillon char *pmax, 34136321Samurai NBTArguments *nbtarg) 34236321Samurai{ 34336321Samurai NBTNsRNB *nb; 34436321Samurai u_short bcount; 34536321Samurai 34641759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 34741759Sdillon return(NULL); 34836321Samurai /* Check out a length */ 34936321Samurai bcount = ntohs(q->rdlen); 35036321Samurai 35136321Samurai /* Forward to Resource NB position */ 35236321Samurai nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource); 35336321Samurai 35436321Samurai /* Processing all in_addr array */ 35536321Samurai#ifdef DEBUG 35636321Samurai printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr)); 35736321Samurai printf("->%s, %dbytes] ",inet_ntoa(nbtarg->newaddr ), bcount); 35836321Samurai#endif 35941759Sdillon while ( nb != NULL && bcount != 0 ) { 36041759Sdillon if ((char *)(nb + 1) > pmax) { 36141759Sdillon nb = NULL; 36241759Sdillon break; 36341759Sdillon } 36436321Samurai#ifdef DEBUG 36536321Samurai printf("<%s>", inet_ntoa(nb->addr) ); 36636321Samurai#endif 36736321Samurai if (!bcmp(&nbtarg->oldaddr,&nb->addr, sizeof(struct in_addr) ) ) { 36836321Samurai if ( *nbtarg->uh_sum != 0 ) { 36936321Samurai int acc; 37036321Samurai u_short *sptr; 37136321Samurai 37236321Samurai sptr = (u_short *) &(nb->addr); 37336321Samurai acc = *sptr++; 37436321Samurai acc += *sptr; 37536321Samurai sptr = (u_short *) &(nbtarg->newaddr); 37636321Samurai acc -= *sptr++; 37736321Samurai acc -= *sptr; 37836321Samurai ADJUST_CHECKSUM(acc, *nbtarg->uh_sum) 37936321Samurai } 38036321Samurai 38136321Samurai nb->addr = nbtarg->newaddr; 38236321Samurai#ifdef DEBUG 38336321Samurai printf("O"); 38436321Samurai#endif 38536321Samurai } 38636321Samurai#ifdef DEBUG 38736321Samurai else { 38836321Samurai printf("."); 38936321Samurai } 39036321Samurai#endif 39136321Samurai nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB); 39236321Samurai bcount -= SizeOfNsRNB; 39336321Samurai } 39441759Sdillon if (nb == NULL || (char *)(nb + 1) > pmax) { 39541759Sdillon nb = NULL; 39641759Sdillon } 39736321Samurai 39836321Samurai return ((u_char *)nb); 39936321Samurai} 40036321Samurai 40136321Samurai#define SizeOfResourceA 6 40236321Samuraitypedef struct { 40336321Samurai struct in_addr addr; 40436321Samurai} NBTNsResourceA; 40536321Samurai 40644616Sbrianstatic u_char * 40741759SdillonAliasHandleResourceA( 40841759Sdillon NBTNsResource *q, 40941759Sdillon char *pmax, 41036321Samurai NBTArguments *nbtarg) 41136321Samurai{ 41236321Samurai NBTNsResourceA *a; 41336321Samurai u_short bcount; 41436321Samurai 41541759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 41641759Sdillon return(NULL); 41741759Sdillon 41836321Samurai /* Forward to Resource A position */ 41936321Samurai a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) ); 42036321Samurai 42136321Samurai /* Check out of length */ 42236321Samurai bcount = ntohs(q->rdlen); 42336321Samurai 42436321Samurai /* Processing all in_addr array */ 42536321Samurai#ifdef DEBUG 42636321Samurai printf("Arec [%s", inet_ntoa(nbtarg->oldaddr)); 42736321Samurai printf("->%s]",inet_ntoa(nbtarg->newaddr )); 42836321Samurai#endif 42936321Samurai while ( bcount != 0 ) { 43041759Sdillon if (a == NULL || (char *)(a + 1) > pmax) 43141759Sdillon return(NULL); 43236321Samurai#ifdef DEBUG 43336321Samurai printf("..%s", inet_ntoa(a->addr) ); 43436321Samurai#endif 43536321Samurai if ( !bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr) ) ) { 43636321Samurai if ( *nbtarg->uh_sum != 0 ) { 43736321Samurai int acc; 43836321Samurai u_short *sptr; 43936321Samurai 44036321Samurai sptr = (u_short *) &(a->addr); /* Old */ 44136321Samurai acc = *sptr++; 44236321Samurai acc += *sptr; 44336321Samurai sptr = (u_short *) &nbtarg->newaddr; /* New */ 44436321Samurai acc -= *sptr++; 44536321Samurai acc -= *sptr; 44636321Samurai ADJUST_CHECKSUM(acc, *nbtarg->uh_sum) 44736321Samurai } 44836321Samurai 44936321Samurai a->addr = nbtarg->newaddr; 45036321Samurai } 45136321Samurai a++; /*XXXX*/ 45236321Samurai bcount -= SizeOfResourceA; 45336321Samurai } 45441759Sdillon if (a == NULL || (char *)(a + 1) > pmax) 45541759Sdillon a = NULL; 45636321Samurai return ((u_char *)a); 45736321Samurai} 45836321Samurai 45936321Samuraitypedef struct { 46036321Samurai u_short opcode:4, flags:8, resv:4; 46136321Samurai} NBTNsResourceNULL; 46236321Samurai 46344616Sbrianstatic u_char * 46441759SdillonAliasHandleResourceNULL( 46541759Sdillon NBTNsResource *q, 46641759Sdillon char *pmax, 46736321Samurai NBTArguments *nbtarg) 46836321Samurai{ 46936321Samurai NBTNsResourceNULL *n; 47036321Samurai u_short bcount; 47136321Samurai 47241759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 47341759Sdillon return(NULL); 47441759Sdillon 47536321Samurai /* Forward to Resource NULL position */ 47636321Samurai n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); 47736321Samurai 47836321Samurai /* Check out of length */ 47936321Samurai bcount = ntohs(q->rdlen); 48036321Samurai 48136321Samurai /* Processing all in_addr array */ 48236321Samurai while ( bcount != 0 ) { 48341759Sdillon if ((char *)(n + 1) > pmax) { 48441759Sdillon n = NULL; 48541759Sdillon break; 48641759Sdillon } 48736321Samurai n++; 48836321Samurai bcount -= sizeof(NBTNsResourceNULL); 48936321Samurai } 49041759Sdillon if ((char *)(n + 1) > pmax) 49141759Sdillon n = NULL; 49236321Samurai 49336321Samurai return ((u_char *)n); 49436321Samurai} 49536321Samurai 49644616Sbrianstatic u_char * 49741759SdillonAliasHandleResourceNS( 49841759Sdillon NBTNsResource *q, 49941759Sdillon char *pmax, 50036321Samurai NBTArguments *nbtarg) 50136321Samurai{ 50236321Samurai NBTNsResourceNULL *n; 50336321Samurai u_short bcount; 50436321Samurai 50541759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 50641759Sdillon return(NULL); 50741759Sdillon 50836321Samurai /* Forward to Resource NULL position */ 50936321Samurai n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); 51036321Samurai 51136321Samurai /* Check out of length */ 51236321Samurai bcount = ntohs(q->rdlen); 51336321Samurai 51436321Samurai /* Resource Record Name Filed */ 51541759Sdillon q = (NBTNsResource *)AliasHandleName( (u_char *)n, pmax ); /* XXX */ 51636321Samurai 51741759Sdillon if (q == NULL || (char *)((u_char *)n + bcount) > pmax) 51841759Sdillon return(NULL); 51941759Sdillon else 52036321Samurai return ((u_char *)n + bcount); 52136321Samurai} 52236321Samurai 52336321Samuraitypedef struct { 52436321Samurai u_short numnames; 52536321Samurai} NBTNsResourceNBSTAT; 52636321Samurai 52744616Sbrianstatic u_char * 52841759SdillonAliasHandleResourceNBSTAT( 52941759Sdillon NBTNsResource *q, 53041759Sdillon char *pmax, 53136321Samurai NBTArguments *nbtarg) 53236321Samurai{ 53336321Samurai NBTNsResourceNBSTAT *n; 53436321Samurai u_short bcount; 53536321Samurai 53641759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 53741759Sdillon return(NULL); 53841759Sdillon 53936321Samurai /* Forward to Resource NBSTAT position */ 54036321Samurai n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) ); 54136321Samurai 54236321Samurai /* Check out of length */ 54336321Samurai bcount = ntohs(q->rdlen); 54436321Samurai 54541759Sdillon if (q == NULL || (char *)((u_char *)n + bcount) > pmax) 54641759Sdillon return(NULL); 54741759Sdillon else 54836321Samurai return ((u_char *)n + bcount); 54936321Samurai} 55036321Samurai 55144616Sbrianstatic u_char * 55241759SdillonAliasHandleResource( 55341759Sdillon u_short count, 55436321Samurai NBTNsResource *q, 55541759Sdillon char *pmax, 55641759Sdillon NBTArguments 55741759Sdillon *nbtarg) 55836321Samurai{ 55936321Samurai while ( count != 0 ) { 56036321Samurai /* Resource Record Name Filed */ 56141759Sdillon q = (NBTNsResource *)AliasHandleName( (u_char *)q, pmax ); 56241759Sdillon 56341759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 56441759Sdillon break; 56536321Samurai#ifdef DEBUG 56636321Samurai printf("type=%02x, count=%d\n", ntohs(q->type), count ); 56736321Samurai#endif 56836321Samurai 56936321Samurai /* Type and Class filed */ 57036321Samurai switch ( ntohs(q->type) ) { 57136321Samurai case RR_TYPE_NB: 57241759Sdillon q = (NBTNsResource *)AliasHandleResourceNB( 57341759Sdillon q, 57441759Sdillon pmax, 57541759Sdillon nbtarg 57641759Sdillon ); 57736321Samurai break; 57836321Samurai case RR_TYPE_A: 57941759Sdillon q = (NBTNsResource *)AliasHandleResourceA( 58041759Sdillon q, 58141759Sdillon pmax, 58241759Sdillon nbtarg 58341759Sdillon ); 58436321Samurai break; 58536321Samurai case RR_TYPE_NS: 58641759Sdillon q = (NBTNsResource *)AliasHandleResourceNS( 58741759Sdillon q, 58841759Sdillon pmax, 58941759Sdillon nbtarg 59041759Sdillon ); 59136321Samurai break; 59236321Samurai case RR_TYPE_NULL: 59341759Sdillon q = (NBTNsResource *)AliasHandleResourceNULL( 59441759Sdillon q, 59541759Sdillon pmax, 59641759Sdillon nbtarg 59741759Sdillon ); 59836321Samurai break; 59936321Samurai case RR_TYPE_NBSTAT: 60041759Sdillon q = (NBTNsResource *)AliasHandleResourceNBSTAT( 60141759Sdillon q, 60241759Sdillon pmax, 60341759Sdillon nbtarg 60441759Sdillon ); 60536321Samurai break; 60641759Sdillon default: 60744616Sbrian#ifdef DEBUG 60841759Sdillon printf( 60941759Sdillon "\nUnknown Type of Resource %0x\n", 61041759Sdillon ntohs(q->type) 61141759Sdillon ); 61244616Sbrian#endif 61336321Samurai break; 61436321Samurai } 61536321Samurai count--; 61636321Samurai } 61736321Samurai fflush(stdout); 61836321Samurai return ((u_char *)q); 61936321Samurai} 62036321Samurai 62141759Sdillonint AliasHandleUdpNbtNS( 62236321Samurai struct ip *pip, /* IP packet to examine/patch */ 62336321Samurai struct alias_link *link, 62436321Samurai struct in_addr *alias_address, 62536321Samurai u_short *alias_port, 62636321Samurai struct in_addr *original_address, 62736321Samurai u_short *original_port ) 62836321Samurai{ 62936321Samurai struct udphdr * uh; 63036321Samurai NbtNSHeader * nsh; 63136321Samurai u_char * p; 63241759Sdillon char *pmax; 63336321Samurai NBTArguments nbtarg; 63436321Samurai 63536321Samurai /* Set up Common Parameter */ 63636321Samurai nbtarg.oldaddr = *alias_address; 63736321Samurai nbtarg.oldport = *alias_port; 63836321Samurai nbtarg.newaddr = *original_address; 63936321Samurai nbtarg.newport = *original_port; 64036321Samurai 64136321Samurai /* Calculate data length of UDP packet */ 64236321Samurai uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 64336321Samurai nbtarg.uh_sum = &(uh->uh_sum); 64436321Samurai nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr))); 64536321Samurai p = (u_char *)(nsh + 1); 64641759Sdillon pmax = (char *)uh + ntohs( uh->uh_ulen ); 64736321Samurai 64841759Sdillon if ((char *)(nsh + 1) > pmax) 64941759Sdillon return(-1); 65041759Sdillon 65136321Samurai#ifdef DEBUG 65241759Sdillon printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x" 65341759Sdillon ", an=%04x, ns=%04x, ar=%04x, [%d]-->", 65436321Samurai nsh->dir ? "Response": "Request", 65536321Samurai nsh->nametrid, 65636321Samurai nsh->opcode, 65736321Samurai nsh->nmflags, 65836321Samurai nsh->rcode, 65936321Samurai ntohs(nsh->qdcount), 66036321Samurai ntohs(nsh->ancount), 66136321Samurai ntohs(nsh->nscount), 66236321Samurai ntohs(nsh->arcount), 66341759Sdillon (u_char *)p -(u_char *)nsh 66441759Sdillon ); 66536321Samurai#endif 66636321Samurai 66736321Samurai /* Question Entries */ 66836321Samurai if (ntohs(nsh->qdcount) !=0 ) { 66941759Sdillon p = AliasHandleQuestion( 67041759Sdillon ntohs(nsh->qdcount), 67141759Sdillon (NBTNsQuestion *)p, 67241759Sdillon pmax, 67341759Sdillon &nbtarg 67441759Sdillon ); 67536321Samurai } 67636321Samurai 67736321Samurai /* Answer Resource Records */ 67836321Samurai if (ntohs(nsh->ancount) !=0 ) { 67941759Sdillon p = AliasHandleResource( 68041759Sdillon ntohs(nsh->ancount), 68141759Sdillon (NBTNsResource *)p, 68241759Sdillon pmax, 68341759Sdillon &nbtarg 68441759Sdillon ); 68536321Samurai } 68636321Samurai 68736321Samurai /* Authority Resource Recodrs */ 68836321Samurai if (ntohs(nsh->nscount) !=0 ) { 68941759Sdillon p = AliasHandleResource( 69041759Sdillon ntohs(nsh->nscount), 69141759Sdillon (NBTNsResource *)p, 69241759Sdillon pmax, 69341759Sdillon &nbtarg 69441759Sdillon ); 69536321Samurai } 69636321Samurai 69736321Samurai /* Additional Resource Recodrs */ 69836321Samurai if (ntohs(nsh->arcount) !=0 ) { 69941759Sdillon p = AliasHandleResource( 70041759Sdillon ntohs(nsh->arcount), 70141759Sdillon (NBTNsResource *)p, 70241759Sdillon pmax, 70341759Sdillon &nbtarg 70441759Sdillon ); 70536321Samurai } 70636321Samurai 70736321Samurai#ifdef DEBUG 70836321Samurai PrintRcode(nsh->rcode); 70936321Samurai#endif 71041759Sdillon return ((p == NULL) ? -1 : 0); 71136321Samurai} 712