alias_nbt.c revision 41759
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 * 1841759Sdillon * $Id: alias_nbt.c,v 1.1 1998/05/24 03:03:10 amurai 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/******************************************************************* 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 */ 13541759Sdillonu_char *AliasHandleName ( u_char *p, char *pmax ) { 13636321Samurai 13736321Samurai u_char *s; 13836321Samurai u_char c; 13936321Samurai int compress; 14036321Samurai 14136321Samurai /* Following length field */ 14241759Sdillon 14341759Sdillon if (p == NULL || (char *)p >= pmax) 14441759Sdillon return(NULL); 14541759Sdillon 14636321Samurai if (*p & 0xc0 ) { 14736321Samurai p = p + 2; 14841759Sdillon if ((char *)p > pmax) 14941759Sdillon return(NULL); 15036321Samurai return ((u_char *)p); 15136321Samurai } 15236321Samurai while ( ( *p & 0x3f) != 0x00 ) { 15336321Samurai s = p + 1; 15436321Samurai if ( *p == 0x20 ) 15536321Samurai compress = 1; 15636321Samurai else 15736321Samurai compress = 0; 15836321Samurai 15936321Samurai /* Get next length field */ 16036321Samurai p = (u_char *)(p + (*p & 0x3f) + 1); 16141759Sdillon if ((char *)p > pmax) { 16241759Sdillon p = NULL; 16341759Sdillon break; 16441759Sdillon } 16536321Samurai#ifdef DEBUG 16636321Samurai printf(":"); 16736321Samurai#endif 16836321Samurai while (s < p) { 16936321Samurai if ( compress == 1 ) { 17036321Samurai c = (u_char )(((((*s & 0x0f) << 4) | (*(s+1) & 0x0f)) - 0x11)); 17136321Samurai#ifdef DEBUG 17236321Samurai if (isprint( c ) ) 17336321Samurai printf("%c", c ); 17436321Samurai else 17536321Samurai printf("<0x%02x>", c ); 17636321Samurai#endif 17736321Samurai s +=2; 17836321Samurai } else { 17936321Samurai#ifdef DEBUG 18036321Samurai printf("%c", *s); 18136321Samurai#endif 18236321Samurai s++; 18336321Samurai } 18436321Samurai } 18536321Samurai#ifdef DEBUG 18636321Samurai printf(":"); 18736321Samurai#endif 18836321Samurai fflush(stdout); 18936321Samurai } 19036321Samurai 19136321Samurai /* Set up to out of Name field */ 19241759Sdillon if (p == NULL || (char *)p >= pmax) 19341759Sdillon p = NULL; 19441759Sdillon else 19541759Sdillon p++; 19636321Samurai return ((u_char *)p); 19736321Samurai} 19836321Samurai 19936321Samurai/* 20036321Samurai * NetBios Datagram Handler (IP/UDP) 20136321Samurai */ 20236321Samurai#define DGM_DIRECT_UNIQ 0x10 20336321Samurai#define DGM_DIRECT_GROUP 0x11 20436321Samurai#define DGM_BROADCAST 0x12 20536321Samurai#define DGM_ERROR 0x13 20636321Samurai#define DGM_QUERY 0x14 20736321Samurai#define DGM_POSITIVE_RES 0x15 20836321Samurai#define DGM_NEGATIVE_RES 0x16 20936321Samurai 21041759Sdillonint AliasHandleUdpNbt( 21136321Samurai struct ip *pip, /* IP packet to examine/patch */ 21236321Samurai struct alias_link *link, 21336321Samurai struct in_addr *alias_address, 21441759Sdillon u_short alias_port 21541759Sdillon) { 21636321Samurai struct udphdr * uh; 21736321Samurai NbtDataHeader *ndh; 21841759Sdillon u_char *p = NULL; 21941759Sdillon char *pmax; 22036321Samurai 22136321Samurai /* Calculate data length of UDP packet */ 22236321Samurai uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 22341759Sdillon pmax = (char *)uh + ntohs( uh->uh_ulen ); 22441759Sdillon 22536321Samurai ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr))); 22641759Sdillon if ((char *)(ndh + 1) > pmax) 22741759Sdillon return(-1); 22836321Samurai#ifdef DEBUG 22936321Samurai printf("\nType=%02x,", ndh->type ); 23036321Samurai#endif 23136321Samurai switch ( ndh->type ) { 23236321Samurai case DGM_DIRECT_UNIQ: 23336321Samurai case DGM_DIRECT_GROUP: 23436321Samurai case DGM_BROADCAST: 23536321Samurai p = (u_char *)ndh + 14; 23641759Sdillon p = AliasHandleName ( p, pmax ); /* Source Name */ 23741759Sdillon p = AliasHandleName ( p, pmax ); /* Destination Name */ 23836321Samurai break; 23936321Samurai case DGM_ERROR: 24036321Samurai p = (u_char *)ndh + 11; 24136321Samurai break; 24236321Samurai case DGM_QUERY: 24336321Samurai case DGM_POSITIVE_RES: 24436321Samurai case DGM_NEGATIVE_RES: 24536321Samurai p = (u_char *)ndh + 10; 24641759Sdillon p = AliasHandleName ( p, pmax ); /* Destination Name */ 24736321Samurai break; 24836321Samurai } 24941759Sdillon if (p == NULL || (char *)p > pmax) 25041759Sdillon p = NULL; 25136321Samurai#ifdef DEBUG 25236321Samurai printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); 25336321Samurai#endif 25436321Samurai /* Doing a IP address and Port number Translation */ 25536321Samurai if ( uh->uh_sum != 0 ) { 25636321Samurai int acc; 25736321Samurai u_short *sptr; 25836321Samurai acc = ndh->source_port; 25936321Samurai acc -= alias_port; 26036321Samurai sptr = (u_short *) &(ndh->source_ip); 26136321Samurai acc += *sptr++; 26236321Samurai acc += *sptr; 26336321Samurai sptr = (u_short *) alias_address; 26436321Samurai acc -= *sptr++; 26536321Samurai acc -= *sptr; 26636321Samurai ADJUST_CHECKSUM(acc, uh->uh_sum) 26736321Samurai } 26836321Samurai ndh->source_ip = *alias_address; 26936321Samurai ndh->source_port = alias_port; 27036321Samurai#ifdef DEBUG 27136321Samurai printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); 27236321Samurai fflush(stdout); 27336321Samurai#endif 27441759Sdillon return((p == NULL) ? -1 : 0); 27536321Samurai} 27636321Samurai/* Question Section */ 27736321Samurai#define QS_TYPE_NB 0x0020 27836321Samurai#define QS_TYPE_NBSTAT 0x0021 27936321Samurai#define QS_CLAS_IN 0x0001 28036321Samuraitypedef struct { 28136321Samurai u_short type; /* The type of Request */ 28236321Samurai u_short class; /* The class of Request */ 28336321Samurai} NBTNsQuestion; 28436321Samurai 28541759Sdillonu_char * 28641759SdillonAliasHandleQuestion( 28741759Sdillon u_short count, 28836321Samurai NBTNsQuestion *q, 28941759Sdillon char *pmax, 29036321Samurai NBTArguments *nbtarg) 29136321Samurai{ 29236321Samurai 29336321Samurai while ( count != 0 ) { 29436321Samurai /* Name Filed */ 29541759Sdillon q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax); 29636321Samurai 29741759Sdillon if (q == NULL || (char *)(q + 1) > pmax) { 29841759Sdillon q = NULL; 29941759Sdillon break; 30041759Sdillon } 30141759Sdillon 30236321Samurai /* Type and Class filed */ 30336321Samurai switch ( ntohs(q->type) ) { 30436321Samurai case QS_TYPE_NB: 30536321Samurai case QS_TYPE_NBSTAT: 30636321Samurai q= q+1; 30736321Samurai break; 30836321Samurai default: 30936321Samurai printf("\nUnknown Type on Question %0x\n", ntohs(q->type) ); 31036321Samurai break; 31136321Samurai } 31236321Samurai count--; 31336321Samurai } 31436321Samurai 31536321Samurai /* Set up to out of Question Section */ 31636321Samurai return ((u_char *)q); 31736321Samurai} 31836321Samurai 31936321Samurai/* Resource Record */ 32036321Samurai#define RR_TYPE_A 0x0001 32136321Samurai#define RR_TYPE_NS 0x0002 32236321Samurai#define RR_TYPE_NULL 0x000a 32336321Samurai#define RR_TYPE_NB 0x0020 32436321Samurai#define RR_TYPE_NBSTAT 0x0021 32536321Samurai#define RR_CLAS_IN 0x0001 32636321Samurai#define SizeOfNsResource 8 32736321Samuraitypedef struct { 32836321Samurai u_short type; 32936321Samurai u_short class; 33036321Samurai unsigned int ttl; 33136321Samurai u_short rdlen; 33236321Samurai} NBTNsResource; 33336321Samurai 33436321Samurai#define SizeOfNsRNB 6 33536321Samuraitypedef struct { 33636321Samurai u_short g:1, ont:2, resv:13; 33736321Samurai struct in_addr addr; 33836321Samurai} NBTNsRNB; 33936321Samurai 34041759Sdillonu_char * 34141759SdillonAliasHandleResourceNB( 34241759Sdillon NBTNsResource *q, 34341759Sdillon char *pmax, 34436321Samurai NBTArguments *nbtarg) 34536321Samurai{ 34636321Samurai NBTNsRNB *nb; 34736321Samurai u_short bcount; 34836321Samurai 34941759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 35041759Sdillon return(NULL); 35136321Samurai /* Check out a length */ 35236321Samurai bcount = ntohs(q->rdlen); 35336321Samurai 35436321Samurai /* Forward to Resource NB position */ 35536321Samurai nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource); 35636321Samurai 35736321Samurai /* Processing all in_addr array */ 35836321Samurai#ifdef DEBUG 35936321Samurai printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr)); 36036321Samurai printf("->%s, %dbytes] ",inet_ntoa(nbtarg->newaddr ), bcount); 36136321Samurai#endif 36241759Sdillon while ( nb != NULL && bcount != 0 ) { 36341759Sdillon if ((char *)(nb + 1) > pmax) { 36441759Sdillon nb = NULL; 36541759Sdillon break; 36641759Sdillon } 36736321Samurai#ifdef DEBUG 36836321Samurai printf("<%s>", inet_ntoa(nb->addr) ); 36936321Samurai#endif 37036321Samurai if (!bcmp(&nbtarg->oldaddr,&nb->addr, sizeof(struct in_addr) ) ) { 37136321Samurai if ( *nbtarg->uh_sum != 0 ) { 37236321Samurai int acc; 37336321Samurai u_short *sptr; 37436321Samurai 37536321Samurai sptr = (u_short *) &(nb->addr); 37636321Samurai acc = *sptr++; 37736321Samurai acc += *sptr; 37836321Samurai sptr = (u_short *) &(nbtarg->newaddr); 37936321Samurai acc -= *sptr++; 38036321Samurai acc -= *sptr; 38136321Samurai ADJUST_CHECKSUM(acc, *nbtarg->uh_sum) 38236321Samurai } 38336321Samurai 38436321Samurai nb->addr = nbtarg->newaddr; 38536321Samurai#ifdef DEBUG 38636321Samurai printf("O"); 38736321Samurai#endif 38836321Samurai } 38936321Samurai#ifdef DEBUG 39036321Samurai else { 39136321Samurai printf("."); 39236321Samurai } 39336321Samurai#endif 39436321Samurai nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB); 39536321Samurai bcount -= SizeOfNsRNB; 39636321Samurai } 39741759Sdillon if (nb == NULL || (char *)(nb + 1) > pmax) { 39841759Sdillon nb = NULL; 39941759Sdillon } 40036321Samurai 40136321Samurai return ((u_char *)nb); 40236321Samurai} 40336321Samurai 40436321Samurai#define SizeOfResourceA 6 40536321Samuraitypedef struct { 40636321Samurai struct in_addr addr; 40736321Samurai} NBTNsResourceA; 40836321Samurai 40941759Sdillonu_char * 41041759SdillonAliasHandleResourceA( 41141759Sdillon NBTNsResource *q, 41241759Sdillon char *pmax, 41336321Samurai NBTArguments *nbtarg) 41436321Samurai{ 41536321Samurai NBTNsResourceA *a; 41636321Samurai u_short bcount; 41736321Samurai 41841759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 41941759Sdillon return(NULL); 42041759Sdillon 42136321Samurai /* Forward to Resource A position */ 42236321Samurai a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) ); 42336321Samurai 42436321Samurai /* Check out of length */ 42536321Samurai bcount = ntohs(q->rdlen); 42636321Samurai 42736321Samurai /* Processing all in_addr array */ 42836321Samurai#ifdef DEBUG 42936321Samurai printf("Arec [%s", inet_ntoa(nbtarg->oldaddr)); 43036321Samurai printf("->%s]",inet_ntoa(nbtarg->newaddr )); 43136321Samurai#endif 43236321Samurai while ( bcount != 0 ) { 43341759Sdillon if (a == NULL || (char *)(a + 1) > pmax) 43441759Sdillon return(NULL); 43536321Samurai#ifdef DEBUG 43636321Samurai printf("..%s", inet_ntoa(a->addr) ); 43736321Samurai#endif 43836321Samurai if ( !bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr) ) ) { 43936321Samurai if ( *nbtarg->uh_sum != 0 ) { 44036321Samurai int acc; 44136321Samurai u_short *sptr; 44236321Samurai 44336321Samurai sptr = (u_short *) &(a->addr); /* Old */ 44436321Samurai acc = *sptr++; 44536321Samurai acc += *sptr; 44636321Samurai sptr = (u_short *) &nbtarg->newaddr; /* New */ 44736321Samurai acc -= *sptr++; 44836321Samurai acc -= *sptr; 44936321Samurai ADJUST_CHECKSUM(acc, *nbtarg->uh_sum) 45036321Samurai } 45136321Samurai 45236321Samurai a->addr = nbtarg->newaddr; 45336321Samurai } 45436321Samurai a++; /*XXXX*/ 45536321Samurai bcount -= SizeOfResourceA; 45636321Samurai } 45741759Sdillon if (a == NULL || (char *)(a + 1) > pmax) 45841759Sdillon a = NULL; 45936321Samurai return ((u_char *)a); 46036321Samurai} 46136321Samurai 46236321Samuraitypedef struct { 46336321Samurai u_short opcode:4, flags:8, resv:4; 46436321Samurai} NBTNsResourceNULL; 46536321Samurai 46641759Sdillonu_char * 46741759SdillonAliasHandleResourceNULL( 46841759Sdillon NBTNsResource *q, 46941759Sdillon char *pmax, 47036321Samurai NBTArguments *nbtarg) 47136321Samurai{ 47236321Samurai NBTNsResourceNULL *n; 47336321Samurai u_short bcount; 47436321Samurai 47541759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 47641759Sdillon return(NULL); 47741759Sdillon 47836321Samurai /* Forward to Resource NULL position */ 47936321Samurai n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); 48036321Samurai 48136321Samurai /* Check out of length */ 48236321Samurai bcount = ntohs(q->rdlen); 48336321Samurai 48436321Samurai /* Processing all in_addr array */ 48536321Samurai while ( bcount != 0 ) { 48641759Sdillon if ((char *)(n + 1) > pmax) { 48741759Sdillon n = NULL; 48841759Sdillon break; 48941759Sdillon } 49036321Samurai n++; 49136321Samurai bcount -= sizeof(NBTNsResourceNULL); 49236321Samurai } 49341759Sdillon if ((char *)(n + 1) > pmax) 49441759Sdillon n = NULL; 49536321Samurai 49636321Samurai return ((u_char *)n); 49736321Samurai} 49836321Samurai 49941759Sdillonu_char * 50041759SdillonAliasHandleResourceNS( 50141759Sdillon NBTNsResource *q, 50241759Sdillon char *pmax, 50336321Samurai NBTArguments *nbtarg) 50436321Samurai{ 50536321Samurai NBTNsResourceNULL *n; 50636321Samurai u_short bcount; 50736321Samurai 50841759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 50941759Sdillon return(NULL); 51041759Sdillon 51136321Samurai /* Forward to Resource NULL position */ 51236321Samurai n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); 51336321Samurai 51436321Samurai /* Check out of length */ 51536321Samurai bcount = ntohs(q->rdlen); 51636321Samurai 51736321Samurai /* Resource Record Name Filed */ 51841759Sdillon q = (NBTNsResource *)AliasHandleName( (u_char *)n, pmax ); /* XXX */ 51936321Samurai 52041759Sdillon if (q == NULL || (char *)((u_char *)n + bcount) > pmax) 52141759Sdillon return(NULL); 52241759Sdillon else 52336321Samurai return ((u_char *)n + bcount); 52436321Samurai} 52536321Samurai 52636321Samuraitypedef struct { 52736321Samurai u_short numnames; 52836321Samurai} NBTNsResourceNBSTAT; 52936321Samurai 53041759Sdillonu_char * 53141759SdillonAliasHandleResourceNBSTAT( 53241759Sdillon NBTNsResource *q, 53341759Sdillon char *pmax, 53436321Samurai NBTArguments *nbtarg) 53536321Samurai{ 53636321Samurai NBTNsResourceNBSTAT *n; 53736321Samurai u_short bcount; 53836321Samurai 53941759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 54041759Sdillon return(NULL); 54141759Sdillon 54236321Samurai /* Forward to Resource NBSTAT position */ 54336321Samurai n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) ); 54436321Samurai 54536321Samurai /* Check out of length */ 54636321Samurai bcount = ntohs(q->rdlen); 54736321Samurai 54841759Sdillon if (q == NULL || (char *)((u_char *)n + bcount) > pmax) 54941759Sdillon return(NULL); 55041759Sdillon else 55136321Samurai return ((u_char *)n + bcount); 55236321Samurai} 55336321Samurai 55441759Sdillonu_char * 55541759SdillonAliasHandleResource( 55641759Sdillon u_short count, 55736321Samurai NBTNsResource *q, 55841759Sdillon char *pmax, 55941759Sdillon NBTArguments 56041759Sdillon *nbtarg) 56136321Samurai{ 56236321Samurai while ( count != 0 ) { 56336321Samurai /* Resource Record Name Filed */ 56441759Sdillon q = (NBTNsResource *)AliasHandleName( (u_char *)q, pmax ); 56541759Sdillon 56641759Sdillon if (q == NULL || (char *)(q + 1) > pmax) 56741759Sdillon break; 56836321Samurai#ifdef DEBUG 56936321Samurai printf("type=%02x, count=%d\n", ntohs(q->type), count ); 57036321Samurai#endif 57136321Samurai 57236321Samurai /* Type and Class filed */ 57336321Samurai switch ( ntohs(q->type) ) { 57436321Samurai case RR_TYPE_NB: 57541759Sdillon q = (NBTNsResource *)AliasHandleResourceNB( 57641759Sdillon q, 57741759Sdillon pmax, 57841759Sdillon nbtarg 57941759Sdillon ); 58036321Samurai break; 58136321Samurai case RR_TYPE_A: 58241759Sdillon q = (NBTNsResource *)AliasHandleResourceA( 58341759Sdillon q, 58441759Sdillon pmax, 58541759Sdillon nbtarg 58641759Sdillon ); 58736321Samurai break; 58836321Samurai case RR_TYPE_NS: 58941759Sdillon q = (NBTNsResource *)AliasHandleResourceNS( 59041759Sdillon q, 59141759Sdillon pmax, 59241759Sdillon nbtarg 59341759Sdillon ); 59436321Samurai break; 59536321Samurai case RR_TYPE_NULL: 59641759Sdillon q = (NBTNsResource *)AliasHandleResourceNULL( 59741759Sdillon q, 59841759Sdillon pmax, 59941759Sdillon nbtarg 60041759Sdillon ); 60136321Samurai break; 60236321Samurai case RR_TYPE_NBSTAT: 60341759Sdillon q = (NBTNsResource *)AliasHandleResourceNBSTAT( 60441759Sdillon q, 60541759Sdillon pmax, 60641759Sdillon nbtarg 60741759Sdillon ); 60836321Samurai break; 60941759Sdillon default: 61041759Sdillon printf( 61141759Sdillon "\nUnknown Type of Resource %0x\n", 61241759Sdillon ntohs(q->type) 61341759Sdillon ); 61436321Samurai break; 61536321Samurai } 61636321Samurai count--; 61736321Samurai } 61836321Samurai fflush(stdout); 61936321Samurai return ((u_char *)q); 62036321Samurai} 62136321Samurai 62241759Sdillonint AliasHandleUdpNbtNS( 62336321Samurai struct ip *pip, /* IP packet to examine/patch */ 62436321Samurai struct alias_link *link, 62536321Samurai struct in_addr *alias_address, 62636321Samurai u_short *alias_port, 62736321Samurai struct in_addr *original_address, 62836321Samurai u_short *original_port ) 62936321Samurai{ 63036321Samurai struct udphdr * uh; 63136321Samurai NbtNSHeader * nsh; 63236321Samurai u_char * p; 63341759Sdillon char *pmax; 63436321Samurai NBTArguments nbtarg; 63536321Samurai 63636321Samurai /* Set up Common Parameter */ 63736321Samurai nbtarg.oldaddr = *alias_address; 63836321Samurai nbtarg.oldport = *alias_port; 63936321Samurai nbtarg.newaddr = *original_address; 64036321Samurai nbtarg.newport = *original_port; 64136321Samurai 64236321Samurai /* Calculate data length of UDP packet */ 64336321Samurai uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 64436321Samurai nbtarg.uh_sum = &(uh->uh_sum); 64536321Samurai nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr))); 64636321Samurai p = (u_char *)(nsh + 1); 64741759Sdillon pmax = (char *)uh + ntohs( uh->uh_ulen ); 64836321Samurai 64941759Sdillon if ((char *)(nsh + 1) > pmax) 65041759Sdillon return(-1); 65141759Sdillon 65236321Samurai#ifdef DEBUG 65341759Sdillon printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x" 65441759Sdillon ", an=%04x, ns=%04x, ar=%04x, [%d]-->", 65536321Samurai nsh->dir ? "Response": "Request", 65636321Samurai nsh->nametrid, 65736321Samurai nsh->opcode, 65836321Samurai nsh->nmflags, 65936321Samurai nsh->rcode, 66036321Samurai ntohs(nsh->qdcount), 66136321Samurai ntohs(nsh->ancount), 66236321Samurai ntohs(nsh->nscount), 66336321Samurai ntohs(nsh->arcount), 66441759Sdillon (u_char *)p -(u_char *)nsh 66541759Sdillon ); 66636321Samurai#endif 66736321Samurai 66836321Samurai /* Question Entries */ 66936321Samurai if (ntohs(nsh->qdcount) !=0 ) { 67041759Sdillon p = AliasHandleQuestion( 67141759Sdillon ntohs(nsh->qdcount), 67241759Sdillon (NBTNsQuestion *)p, 67341759Sdillon pmax, 67441759Sdillon &nbtarg 67541759Sdillon ); 67636321Samurai } 67736321Samurai 67836321Samurai /* Answer Resource Records */ 67936321Samurai if (ntohs(nsh->ancount) !=0 ) { 68041759Sdillon p = AliasHandleResource( 68141759Sdillon ntohs(nsh->ancount), 68241759Sdillon (NBTNsResource *)p, 68341759Sdillon pmax, 68441759Sdillon &nbtarg 68541759Sdillon ); 68636321Samurai } 68736321Samurai 68836321Samurai /* Authority Resource Recodrs */ 68936321Samurai if (ntohs(nsh->nscount) !=0 ) { 69041759Sdillon p = AliasHandleResource( 69141759Sdillon ntohs(nsh->nscount), 69241759Sdillon (NBTNsResource *)p, 69341759Sdillon pmax, 69441759Sdillon &nbtarg 69541759Sdillon ); 69636321Samurai } 69736321Samurai 69836321Samurai /* Additional Resource Recodrs */ 69936321Samurai if (ntohs(nsh->arcount) !=0 ) { 70041759Sdillon p = AliasHandleResource( 70141759Sdillon ntohs(nsh->arcount), 70241759Sdillon (NBTNsResource *)p, 70341759Sdillon pmax, 70441759Sdillon &nbtarg 70541759Sdillon ); 70636321Samurai } 70736321Samurai 70836321Samurai#ifdef DEBUG 70936321Samurai PrintRcode(nsh->rcode); 71036321Samurai#endif 71141759Sdillon return ((p == NULL) ? -1 : 0); 71236321Samurai} 71341759Sdillon 714