alias_nbt.c revision 77696
177696Sbrian/*- 236321Samurai * Written by Atsushi Murai <amurai@spec.co.jp> 377696Sbrian * Copyright (c) 1998, System Planning and Engineering Co. 477696Sbrian * All rights reserved. 536321Samurai * 677696Sbrian * Redistribution and use in source and binary forms, with or without 777696Sbrian * modification, are permitted provided that the following conditions 877696Sbrian * are met: 977696Sbrian * 1. Redistributions of source code must retain the above copyright 1077696Sbrian * notice, this list of conditions and the following disclaimer. 1177696Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1277696Sbrian * notice, this list of conditions and the following disclaimer in the 1377696Sbrian * documentation and/or other materials provided with the distribution. 1436321Samurai * 1577696Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1677696Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1777696Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1877696Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1977696Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2077696Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2177696Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2277696Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2377696Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2477696Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2577696Sbrian * SUCH DAMAGE. 2636321Samurai * 2750476Speter * $FreeBSD: head/sys/netinet/libalias/alias_nbt.c 77696 2001-06-04 14:52:17Z brian $ 2836321Samurai * 2936321Samurai * TODO: 3036321Samurai * oClean up. 3136321Samurai * oConsidering for word alignment for other platform. 3236321Samurai */ 3336321Samurai/* 3436321Samurai alias_nbt.c performs special processing for NetBios over TCP/IP 3536321Samurai sessions by UDP. 3636321Samurai 3736321Samurai Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>) 3836321Samurai 3936321Samurai See HISTORY file for record of revisions. 4036321Samurai*/ 4136321Samurai 4236321Samurai/* Includes */ 4336321Samurai#include <ctype.h> 4436321Samurai#include <stdio.h> 4536321Samurai#include <string.h> 4636321Samurai#include <sys/types.h> 4736321Samurai#include <netinet/in_systm.h> 4836321Samurai#include <netinet/in.h> 4936321Samurai#include <arpa/inet.h> 5036321Samurai#include <netinet/ip.h> 5136321Samurai#include <netinet/udp.h> 5236321Samurai#include <netinet/tcp.h> 5336321Samurai 5436321Samurai#include "alias_local.h" 5536321Samurai 5636321Samuraitypedef struct { 5736321Samurai struct in_addr oldaddr; 5836321Samurai u_short oldport; 5936321Samurai struct in_addr newaddr; 6036321Samurai u_short newport; 6136321Samurai u_short *uh_sum; 6236321Samurai} NBTArguments; 6336321Samurai 6436321Samuraitypedef struct { 6536321Samurai unsigned char type; 6636321Samurai unsigned char flags; 6736321Samurai u_short id; 6836321Samurai struct in_addr source_ip; 6936321Samurai u_short source_port; 7036321Samurai u_short len; 7136321Samurai u_short offset; 7236321Samurai} NbtDataHeader; 7336321Samurai 7436321Samurai#define OpQuery 0 7536321Samurai#define OpUnknown 4 7636321Samurai#define OpRegist 5 7736321Samurai#define OpRelease 6 7836321Samurai#define OpWACK 7 7936321Samurai#define OpRefresh 8 8036321Samuraitypedef struct { 8136321Samurai u_short nametrid; 8236321Samurai u_short dir:1, opcode:4, nmflags:7, rcode:4; 8336321Samurai u_short qdcount; 8436321Samurai u_short ancount; 8536321Samurai u_short nscount; 8636321Samurai u_short arcount; 8736321Samurai} NbtNSHeader; 8836321Samurai 8936321Samurai#define FMT_ERR 0x1 9036321Samurai#define SRV_ERR 0x2 9136321Samurai#define IMP_ERR 0x4 9236321Samurai#define RFS_ERR 0x5 9336321Samurai#define ACT_ERR 0x6 9436321Samurai#define CFT_ERR 0x7 9536321Samurai 9636321Samurai 9744616Sbrian#ifdef DEBUG 9844616Sbrianstatic void PrintRcode( u_char rcode ) { 9936321Samurai 10036321Samurai switch (rcode) { 10136321Samurai case FMT_ERR: 10236321Samurai printf("\nFormat Error."); 10336321Samurai case SRV_ERR: 10436321Samurai printf("\nSever failure."); 10536321Samurai case IMP_ERR: 10636321Samurai printf("\nUnsupported request error.\n"); 10736321Samurai case RFS_ERR: 10836321Samurai printf("\nRefused error.\n"); 10936321Samurai case ACT_ERR: 11036321Samurai printf("\nActive error.\n"); 11136321Samurai case CFT_ERR: 11236321Samurai printf("\nName in conflict error.\n"); 11336321Samurai default: 11436321Samurai printf("\n???=%0x\n", rcode ); 11536321Samurai 11636321Samurai } 11736321Samurai} 11844616Sbrian#endif 11936321Samurai 12036321Samurai 12136321Samurai/* Handling Name field */ 12244616Sbrianstatic u_char *AliasHandleName ( u_char *p, char *pmax ) { 12336321Samurai 12436321Samurai u_char *s; 12536321Samurai u_char c; 12636321Samurai int compress; 12736321Samurai 12836321Samurai /* Following length field */ 12941759Sdillon 13041759Sdillon if (p == NULL || (char *)p >= pmax) 13141759Sdillon return(NULL); 13241759Sdillon 13336321Samurai if (*p & 0xc0 ) { 13436321Samurai p = p + 2; 13541759Sdillon if ((char *)p > pmax) 13641759Sdillon return(NULL); 13736321Samurai return ((u_char *)p); 13836321Samurai } 13936321Samurai while ( ( *p & 0x3f) != 0x00 ) { 14036321Samurai s = p + 1; 14136321Samurai if ( *p == 0x20 ) 14236321Samurai compress = 1; 14336321Samurai else 14436321Samurai compress = 0; 14536321Samurai 14636321Samurai /* Get next length field */ 14736321Samurai p = (u_char *)(p + (*p & 0x3f) + 1); 14841759Sdillon if ((char *)p > pmax) { 14941759Sdillon p = NULL; 15041759Sdillon break; 15141759Sdillon } 15236321Samurai#ifdef DEBUG 15336321Samurai printf(":"); 15436321Samurai#endif 15536321Samurai while (s < p) { 15636321Samurai if ( compress == 1 ) { 15736321Samurai c = (u_char )(((((*s & 0x0f) << 4) | (*(s+1) & 0x0f)) - 0x11)); 15836321Samurai#ifdef DEBUG 15936321Samurai if (isprint( c ) ) 16036321Samurai printf("%c", c ); 16136321Samurai else 16236321Samurai printf("<0x%02x>", c ); 16336321Samurai#endif 16436321Samurai s +=2; 16536321Samurai } else { 16636321Samurai#ifdef DEBUG 16736321Samurai printf("%c", *s); 16836321Samurai#endif 16936321Samurai s++; 17036321Samurai } 17136321Samurai } 17236321Samurai#ifdef DEBUG 17336321Samurai printf(":"); 17436321Samurai#endif 17536321Samurai fflush(stdout); 17636321Samurai } 17736321Samurai 17836321Samurai /* Set up to out of Name field */ 17941759Sdillon if (p == NULL || (char *)p >= pmax) 18041759Sdillon p = NULL; 18141759Sdillon else 18241759Sdillon 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 19741759Sdillonint AliasHandleUdpNbt( 19836321Samurai struct ip *pip, /* IP packet to examine/patch */ 19936321Samurai struct alias_link *link, 20036321Samurai struct in_addr *alias_address, 20141759Sdillon u_short alias_port 20241759Sdillon) { 20336321Samurai struct udphdr * uh; 20436321Samurai NbtDataHeader *ndh; 20541759Sdillon u_char *p = NULL; 20641759Sdillon char *pmax; 20736321Samurai 20836321Samurai /* Calculate data length of UDP packet */ 20936321Samurai uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 21041759Sdillon pmax = (char *)uh + ntohs( uh->uh_ulen ); 21141759Sdillon 21236321Samurai ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr))); 21341759Sdillon if ((char *)(ndh + 1) > pmax) 21441759Sdillon return(-1); 21536321Samurai#ifdef DEBUG 21636321Samurai printf("\nType=%02x,", ndh->type ); 21736321Samurai#endif 21836321Samurai switch ( ndh->type ) { 21936321Samurai case DGM_DIRECT_UNIQ: 22036321Samurai case DGM_DIRECT_GROUP: 22136321Samurai case DGM_BROADCAST: 22236321Samurai p = (u_char *)ndh + 14; 22341759Sdillon p = AliasHandleName ( p, pmax ); /* Source Name */ 22441759Sdillon p = AliasHandleName ( p, pmax ); /* Destination Name */ 22536321Samurai break; 22636321Samurai case DGM_ERROR: 22736321Samurai p = (u_char *)ndh + 11; 22836321Samurai break; 22936321Samurai case DGM_QUERY: 23036321Samurai case DGM_POSITIVE_RES: 23136321Samurai case DGM_NEGATIVE_RES: 23236321Samurai p = (u_char *)ndh + 10; 23341759Sdillon p = AliasHandleName ( p, pmax ); /* Destination Name */ 23436321Samurai break; 23536321Samurai } 23641759Sdillon if (p == NULL || (char *)p > pmax) 23741759Sdillon p = NULL; 23836321Samurai#ifdef DEBUG 23936321Samurai printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); 24036321Samurai#endif 24136321Samurai /* Doing a IP address and Port number Translation */ 24236321Samurai if ( uh->uh_sum != 0 ) { 24336321Samurai int acc; 24436321Samurai u_short *sptr; 24536321Samurai acc = ndh->source_port; 24636321Samurai acc -= alias_port; 24736321Samurai sptr = (u_short *) &(ndh->source_ip); 24836321Samurai acc += *sptr++; 24936321Samurai acc += *sptr; 25036321Samurai sptr = (u_short *) alias_address; 25136321Samurai acc -= *sptr++; 25236321Samurai acc -= *sptr; 25374778Sbrian ADJUST_CHECKSUM(acc, uh->uh_sum); 25436321Samurai } 25536321Samurai ndh->source_ip = *alias_address; 25636321Samurai ndh->source_port = alias_port; 25736321Samurai#ifdef DEBUG 25836321Samurai printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); 25936321Samurai fflush(stdout); 26036321Samurai#endif 26141759Sdillon return((p == NULL) ? -1 : 0); 26236321Samurai} 26336321Samurai/* Question Section */ 26436321Samurai#define QS_TYPE_NB 0x0020 26536321Samurai#define QS_TYPE_NBSTAT 0x0021 26636321Samurai#define QS_CLAS_IN 0x0001 26736321Samuraitypedef struct { 26836321Samurai u_short type; /* The type of Request */ 26936321Samurai u_short class; /* The class of Request */ 27036321Samurai} NBTNsQuestion; 27136321Samurai 27244616Sbrianstatic u_char * 27341759SdillonAliasHandleQuestion( 27441759Sdillon u_short count, 27536321Samurai NBTNsQuestion *q, 27641759Sdillon char *pmax, 27736321Samurai NBTArguments *nbtarg) 27836321Samurai{ 27936321Samurai 28036321Samurai while ( count != 0 ) { 28136321Samurai /* Name Filed */ 28241759Sdillon q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax); 28336321Samurai 28441759Sdillon if (q == NULL || (char *)(q + 1) > pmax) { 28541759Sdillon q = NULL; 28641759Sdillon break; 28741759Sdillon } 28841759Sdillon 28936321Samurai /* Type and Class filed */ 29036321Samurai switch ( ntohs(q->type) ) { 29136321Samurai case QS_TYPE_NB: 29236321Samurai case QS_TYPE_NBSTAT: 29336321Samurai q= q+1; 29436321Samurai break; 29536321Samurai default: 29644616Sbrian#ifdef DEBUG 29736321Samurai printf("\nUnknown Type on Question %0x\n", ntohs(q->type) ); 29844616Sbrian#endif 29936321Samurai break; 30036321Samurai } 30136321Samurai count--; 30236321Samurai } 30336321Samurai 30436321Samurai /* Set up to out of Question Section */ 30536321Samurai return ((u_char *)q); 30636321Samurai} 30736321Samurai 30836321Samurai/* Resource Record */ 30936321Samurai#define RR_TYPE_A 0x0001 31036321Samurai#define RR_TYPE_NS 0x0002 31136321Samurai#define RR_TYPE_NULL 0x000a 31236321Samurai#define RR_TYPE_NB 0x0020 31336321Samurai#define RR_TYPE_NBSTAT 0x0021 31436321Samurai#define RR_CLAS_IN 0x0001 31536321Samurai#define SizeOfNsResource 8 31636321Samuraitypedef struct { 31736321Samurai u_short type; 31836321Samurai u_short class; 31936321Samurai unsigned int ttl; 32036321Samurai u_short rdlen; 32136321Samurai} NBTNsResource; 32236321Samurai 32336321Samurai#define SizeOfNsRNB 6 32436321Samuraitypedef struct { 32536321Samurai u_short g:1, ont:2, resv:13; 32636321Samurai struct in_addr addr; 32736321Samurai} NBTNsRNB; 32836321Samurai 32944616Sbrianstatic u_char * 33041759SdillonAliasHandleResourceNB( 33141759Sdillon NBTNsResource *q, 33241759Sdillon char *pmax, 33336321Samurai NBTArguments *nbtarg) 33436321Samurai{ 33536321Samurai NBTNsRNB *nb; 33636321Samurai u_short bcount; 33736321Samurai 33841759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 33941759Sdillon return(NULL); 34036321Samurai /* Check out a length */ 34136321Samurai bcount = ntohs(q->rdlen); 34236321Samurai 34336321Samurai /* Forward to Resource NB position */ 34436321Samurai nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource); 34536321Samurai 34636321Samurai /* Processing all in_addr array */ 34736321Samurai#ifdef DEBUG 34836321Samurai printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr)); 34936321Samurai printf("->%s, %dbytes] ",inet_ntoa(nbtarg->newaddr ), bcount); 35036321Samurai#endif 35141759Sdillon while ( nb != NULL && bcount != 0 ) { 35241759Sdillon if ((char *)(nb + 1) > pmax) { 35341759Sdillon nb = NULL; 35441759Sdillon break; 35541759Sdillon } 35636321Samurai#ifdef DEBUG 35736321Samurai printf("<%s>", inet_ntoa(nb->addr) ); 35836321Samurai#endif 35936321Samurai if (!bcmp(&nbtarg->oldaddr,&nb->addr, sizeof(struct in_addr) ) ) { 36036321Samurai if ( *nbtarg->uh_sum != 0 ) { 36136321Samurai int acc; 36236321Samurai u_short *sptr; 36336321Samurai 36436321Samurai sptr = (u_short *) &(nb->addr); 36536321Samurai acc = *sptr++; 36636321Samurai acc += *sptr; 36736321Samurai sptr = (u_short *) &(nbtarg->newaddr); 36836321Samurai acc -= *sptr++; 36936321Samurai acc -= *sptr; 37074778Sbrian ADJUST_CHECKSUM(acc, *nbtarg->uh_sum); 37136321Samurai } 37236321Samurai 37336321Samurai nb->addr = nbtarg->newaddr; 37436321Samurai#ifdef DEBUG 37536321Samurai printf("O"); 37636321Samurai#endif 37736321Samurai } 37836321Samurai#ifdef DEBUG 37936321Samurai else { 38036321Samurai printf("."); 38136321Samurai } 38236321Samurai#endif 38336321Samurai nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB); 38436321Samurai bcount -= SizeOfNsRNB; 38536321Samurai } 38641759Sdillon if (nb == NULL || (char *)(nb + 1) > pmax) { 38741759Sdillon nb = NULL; 38841759Sdillon } 38936321Samurai 39036321Samurai return ((u_char *)nb); 39136321Samurai} 39236321Samurai 39336321Samurai#define SizeOfResourceA 6 39436321Samuraitypedef struct { 39536321Samurai struct in_addr addr; 39636321Samurai} NBTNsResourceA; 39736321Samurai 39844616Sbrianstatic u_char * 39941759SdillonAliasHandleResourceA( 40041759Sdillon NBTNsResource *q, 40141759Sdillon char *pmax, 40236321Samurai NBTArguments *nbtarg) 40336321Samurai{ 40436321Samurai NBTNsResourceA *a; 40536321Samurai u_short bcount; 40636321Samurai 40741759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 40841759Sdillon return(NULL); 40941759Sdillon 41036321Samurai /* Forward to Resource A position */ 41136321Samurai a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) ); 41236321Samurai 41336321Samurai /* Check out of length */ 41436321Samurai bcount = ntohs(q->rdlen); 41536321Samurai 41636321Samurai /* Processing all in_addr array */ 41736321Samurai#ifdef DEBUG 41836321Samurai printf("Arec [%s", inet_ntoa(nbtarg->oldaddr)); 41936321Samurai printf("->%s]",inet_ntoa(nbtarg->newaddr )); 42036321Samurai#endif 42136321Samurai while ( bcount != 0 ) { 42241759Sdillon if (a == NULL || (char *)(a + 1) > pmax) 42341759Sdillon return(NULL); 42436321Samurai#ifdef DEBUG 42536321Samurai printf("..%s", inet_ntoa(a->addr) ); 42636321Samurai#endif 42736321Samurai if ( !bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr) ) ) { 42836321Samurai if ( *nbtarg->uh_sum != 0 ) { 42936321Samurai int acc; 43036321Samurai u_short *sptr; 43136321Samurai 43236321Samurai sptr = (u_short *) &(a->addr); /* Old */ 43336321Samurai acc = *sptr++; 43436321Samurai acc += *sptr; 43536321Samurai sptr = (u_short *) &nbtarg->newaddr; /* New */ 43636321Samurai acc -= *sptr++; 43736321Samurai acc -= *sptr; 43874778Sbrian ADJUST_CHECKSUM(acc, *nbtarg->uh_sum); 43936321Samurai } 44036321Samurai 44136321Samurai a->addr = nbtarg->newaddr; 44236321Samurai } 44336321Samurai a++; /*XXXX*/ 44436321Samurai bcount -= SizeOfResourceA; 44536321Samurai } 44641759Sdillon if (a == NULL || (char *)(a + 1) > pmax) 44741759Sdillon a = NULL; 44836321Samurai return ((u_char *)a); 44936321Samurai} 45036321Samurai 45136321Samuraitypedef struct { 45236321Samurai u_short opcode:4, flags:8, resv:4; 45336321Samurai} NBTNsResourceNULL; 45436321Samurai 45544616Sbrianstatic u_char * 45641759SdillonAliasHandleResourceNULL( 45741759Sdillon NBTNsResource *q, 45841759Sdillon char *pmax, 45936321Samurai NBTArguments *nbtarg) 46036321Samurai{ 46136321Samurai NBTNsResourceNULL *n; 46236321Samurai u_short bcount; 46336321Samurai 46441759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 46541759Sdillon return(NULL); 46641759Sdillon 46736321Samurai /* Forward to Resource NULL position */ 46836321Samurai n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); 46936321Samurai 47036321Samurai /* Check out of length */ 47136321Samurai bcount = ntohs(q->rdlen); 47236321Samurai 47336321Samurai /* Processing all in_addr array */ 47436321Samurai while ( bcount != 0 ) { 47541759Sdillon if ((char *)(n + 1) > pmax) { 47641759Sdillon n = NULL; 47741759Sdillon break; 47841759Sdillon } 47936321Samurai n++; 48036321Samurai bcount -= sizeof(NBTNsResourceNULL); 48136321Samurai } 48241759Sdillon if ((char *)(n + 1) > pmax) 48341759Sdillon n = NULL; 48436321Samurai 48536321Samurai return ((u_char *)n); 48636321Samurai} 48736321Samurai 48844616Sbrianstatic u_char * 48941759SdillonAliasHandleResourceNS( 49041759Sdillon NBTNsResource *q, 49141759Sdillon char *pmax, 49236321Samurai NBTArguments *nbtarg) 49336321Samurai{ 49436321Samurai NBTNsResourceNULL *n; 49536321Samurai u_short bcount; 49636321Samurai 49741759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 49841759Sdillon return(NULL); 49941759Sdillon 50036321Samurai /* Forward to Resource NULL position */ 50136321Samurai n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); 50236321Samurai 50336321Samurai /* Check out of length */ 50436321Samurai bcount = ntohs(q->rdlen); 50536321Samurai 50636321Samurai /* Resource Record Name Filed */ 50741759Sdillon q = (NBTNsResource *)AliasHandleName( (u_char *)n, pmax ); /* XXX */ 50836321Samurai 50941759Sdillon if (q == NULL || (char *)((u_char *)n + bcount) > pmax) 51041759Sdillon return(NULL); 51141759Sdillon else 51236321Samurai return ((u_char *)n + bcount); 51336321Samurai} 51436321Samurai 51536321Samuraitypedef struct { 51636321Samurai u_short numnames; 51736321Samurai} NBTNsResourceNBSTAT; 51836321Samurai 51944616Sbrianstatic u_char * 52041759SdillonAliasHandleResourceNBSTAT( 52141759Sdillon NBTNsResource *q, 52241759Sdillon char *pmax, 52336321Samurai NBTArguments *nbtarg) 52436321Samurai{ 52536321Samurai NBTNsResourceNBSTAT *n; 52636321Samurai u_short bcount; 52736321Samurai 52841759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 52941759Sdillon return(NULL); 53041759Sdillon 53136321Samurai /* Forward to Resource NBSTAT position */ 53236321Samurai n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) ); 53336321Samurai 53436321Samurai /* Check out of length */ 53536321Samurai bcount = ntohs(q->rdlen); 53636321Samurai 53741759Sdillon if (q == NULL || (char *)((u_char *)n + bcount) > pmax) 53841759Sdillon return(NULL); 53941759Sdillon else 54036321Samurai return ((u_char *)n + bcount); 54136321Samurai} 54236321Samurai 54344616Sbrianstatic u_char * 54441759SdillonAliasHandleResource( 54541759Sdillon u_short count, 54636321Samurai NBTNsResource *q, 54741759Sdillon char *pmax, 54841759Sdillon NBTArguments 54941759Sdillon *nbtarg) 55036321Samurai{ 55136321Samurai while ( count != 0 ) { 55236321Samurai /* Resource Record Name Filed */ 55341759Sdillon q = (NBTNsResource *)AliasHandleName( (u_char *)q, pmax ); 55441759Sdillon 55541759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 55641759Sdillon break; 55736321Samurai#ifdef DEBUG 55836321Samurai printf("type=%02x, count=%d\n", ntohs(q->type), count ); 55936321Samurai#endif 56036321Samurai 56136321Samurai /* Type and Class filed */ 56236321Samurai switch ( ntohs(q->type) ) { 56336321Samurai case RR_TYPE_NB: 56441759Sdillon q = (NBTNsResource *)AliasHandleResourceNB( 56541759Sdillon q, 56641759Sdillon pmax, 56741759Sdillon nbtarg 56841759Sdillon ); 56936321Samurai break; 57036321Samurai case RR_TYPE_A: 57141759Sdillon q = (NBTNsResource *)AliasHandleResourceA( 57241759Sdillon q, 57341759Sdillon pmax, 57441759Sdillon nbtarg 57541759Sdillon ); 57636321Samurai break; 57736321Samurai case RR_TYPE_NS: 57841759Sdillon q = (NBTNsResource *)AliasHandleResourceNS( 57941759Sdillon q, 58041759Sdillon pmax, 58141759Sdillon nbtarg 58241759Sdillon ); 58336321Samurai break; 58436321Samurai case RR_TYPE_NULL: 58541759Sdillon q = (NBTNsResource *)AliasHandleResourceNULL( 58641759Sdillon q, 58741759Sdillon pmax, 58841759Sdillon nbtarg 58941759Sdillon ); 59036321Samurai break; 59136321Samurai case RR_TYPE_NBSTAT: 59241759Sdillon q = (NBTNsResource *)AliasHandleResourceNBSTAT( 59341759Sdillon q, 59441759Sdillon pmax, 59541759Sdillon nbtarg 59641759Sdillon ); 59736321Samurai break; 59841759Sdillon default: 59944616Sbrian#ifdef DEBUG 60041759Sdillon printf( 60141759Sdillon "\nUnknown Type of Resource %0x\n", 60241759Sdillon ntohs(q->type) 60341759Sdillon ); 60444616Sbrian#endif 60536321Samurai break; 60636321Samurai } 60736321Samurai count--; 60836321Samurai } 60936321Samurai fflush(stdout); 61036321Samurai return ((u_char *)q); 61136321Samurai} 61236321Samurai 61341759Sdillonint AliasHandleUdpNbtNS( 61436321Samurai struct ip *pip, /* IP packet to examine/patch */ 61536321Samurai struct alias_link *link, 61636321Samurai struct in_addr *alias_address, 61736321Samurai u_short *alias_port, 61836321Samurai struct in_addr *original_address, 61936321Samurai u_short *original_port ) 62036321Samurai{ 62136321Samurai struct udphdr * uh; 62236321Samurai NbtNSHeader * nsh; 62336321Samurai u_char * p; 62441759Sdillon char *pmax; 62536321Samurai NBTArguments nbtarg; 62636321Samurai 62736321Samurai /* Set up Common Parameter */ 62836321Samurai nbtarg.oldaddr = *alias_address; 62936321Samurai nbtarg.oldport = *alias_port; 63036321Samurai nbtarg.newaddr = *original_address; 63136321Samurai nbtarg.newport = *original_port; 63236321Samurai 63336321Samurai /* Calculate data length of UDP packet */ 63436321Samurai uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 63536321Samurai nbtarg.uh_sum = &(uh->uh_sum); 63636321Samurai nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr))); 63736321Samurai p = (u_char *)(nsh + 1); 63841759Sdillon pmax = (char *)uh + ntohs( uh->uh_ulen ); 63936321Samurai 64041759Sdillon if ((char *)(nsh + 1) > pmax) 64141759Sdillon return(-1); 64241759Sdillon 64336321Samurai#ifdef DEBUG 64441759Sdillon printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x" 64541759Sdillon ", an=%04x, ns=%04x, ar=%04x, [%d]-->", 64636321Samurai nsh->dir ? "Response": "Request", 64736321Samurai nsh->nametrid, 64836321Samurai nsh->opcode, 64936321Samurai nsh->nmflags, 65036321Samurai nsh->rcode, 65136321Samurai ntohs(nsh->qdcount), 65236321Samurai ntohs(nsh->ancount), 65336321Samurai ntohs(nsh->nscount), 65436321Samurai ntohs(nsh->arcount), 65541759Sdillon (u_char *)p -(u_char *)nsh 65641759Sdillon ); 65736321Samurai#endif 65836321Samurai 65936321Samurai /* Question Entries */ 66036321Samurai if (ntohs(nsh->qdcount) !=0 ) { 66141759Sdillon p = AliasHandleQuestion( 66241759Sdillon ntohs(nsh->qdcount), 66341759Sdillon (NBTNsQuestion *)p, 66441759Sdillon pmax, 66541759Sdillon &nbtarg 66641759Sdillon ); 66736321Samurai } 66836321Samurai 66936321Samurai /* Answer Resource Records */ 67036321Samurai if (ntohs(nsh->ancount) !=0 ) { 67141759Sdillon p = AliasHandleResource( 67241759Sdillon ntohs(nsh->ancount), 67341759Sdillon (NBTNsResource *)p, 67441759Sdillon pmax, 67541759Sdillon &nbtarg 67641759Sdillon ); 67736321Samurai } 67836321Samurai 67936321Samurai /* Authority Resource Recodrs */ 68036321Samurai if (ntohs(nsh->nscount) !=0 ) { 68141759Sdillon p = AliasHandleResource( 68241759Sdillon ntohs(nsh->nscount), 68341759Sdillon (NBTNsResource *)p, 68441759Sdillon pmax, 68541759Sdillon &nbtarg 68641759Sdillon ); 68736321Samurai } 68836321Samurai 68936321Samurai /* Additional Resource Recodrs */ 69036321Samurai if (ntohs(nsh->arcount) !=0 ) { 69141759Sdillon p = AliasHandleResource( 69241759Sdillon ntohs(nsh->arcount), 69341759Sdillon (NBTNsResource *)p, 69441759Sdillon pmax, 69541759Sdillon &nbtarg 69641759Sdillon ); 69736321Samurai } 69836321Samurai 69936321Samurai#ifdef DEBUG 70036321Samurai PrintRcode(nsh->rcode); 70136321Samurai#endif 70241759Sdillon return ((p == NULL) ? -1 : 0); 70336321Samurai} 704