diff options
Diffstat (limited to 'lib/libalias/alias_nbt.c')
-rw-r--r-- | lib/libalias/alias_nbt.c | 722 |
1 files changed, 0 insertions, 722 deletions
diff --git a/lib/libalias/alias_nbt.c b/lib/libalias/alias_nbt.c deleted file mode 100644 index b51abd1c5da5..000000000000 --- a/lib/libalias/alias_nbt.c +++ /dev/null @@ -1,722 +0,0 @@ -/*- - * Written by Atsushi Murai <amurai@spec.co.jp> - * Copyright (c) 1998, System Planning and Engineering Co. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * TODO: - * oClean up. - * oConsidering for word alignment for other platform. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - alias_nbt.c performs special processing for NetBios over TCP/IP - sessions by UDP. - - Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>) - - See HISTORY file for record of revisions. -*/ - -/* Includes */ -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <netinet/in_systm.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netinet/ip.h> -#include <netinet/udp.h> -#include <netinet/tcp.h> - -#include "alias_local.h" - -typedef struct { - struct in_addr oldaddr; - u_short oldport; - struct in_addr newaddr; - u_short newport; - u_short *uh_sum; -} NBTArguments; - -typedef struct { - unsigned char type; - unsigned char flags; - u_short id; - struct in_addr source_ip; - u_short source_port; - u_short len; - u_short offset; -} NbtDataHeader; - -#define OpQuery 0 -#define OpUnknown 4 -#define OpRegist 5 -#define OpRelease 6 -#define OpWACK 7 -#define OpRefresh 8 -typedef struct { - u_short nametrid; - u_short dir: 1, opcode:4, nmflags:7, rcode:4; - u_short qdcount; - u_short ancount; - u_short nscount; - u_short arcount; -} NbtNSHeader; - -#define FMT_ERR 0x1 -#define SRV_ERR 0x2 -#define IMP_ERR 0x4 -#define RFS_ERR 0x5 -#define ACT_ERR 0x6 -#define CFT_ERR 0x7 - - -#ifdef DEBUG -static void -PrintRcode(u_char rcode) -{ - - switch (rcode) { - case FMT_ERR: - printf("\nFormat Error."); - case SRV_ERR: - printf("\nSever failure."); - case IMP_ERR: - printf("\nUnsupported request error.\n"); - case RFS_ERR: - printf("\nRefused error.\n"); - case ACT_ERR: - printf("\nActive error.\n"); - case CFT_ERR: - printf("\nName in conflict error.\n"); - default: - printf("\n?%c?=%0x\n", '?', rcode); - - } -} - -#endif - - -/* Handling Name field */ -static u_char * -AliasHandleName(u_char * p, char *pmax) -{ - - u_char *s; - u_char c; - int compress; - - /* Following length field */ - - if (p == NULL || (char *)p >= pmax) - return (NULL); - - if (*p & 0xc0) { - p = p + 2; - if ((char *)p > pmax) - return (NULL); - return ((u_char *) p); - } - while ((*p & 0x3f) != 0x00) { - s = p + 1; - if (*p == 0x20) - compress = 1; - else - compress = 0; - - /* Get next length field */ - p = (u_char *) (p + (*p & 0x3f) + 1); - if ((char *)p > pmax) { - p = NULL; - break; - } -#ifdef DEBUG - printf(":"); -#endif - while (s < p) { - if (compress == 1) { - c = (u_char) (((((*s & 0x0f) << 4) | (*(s + 1) & 0x0f)) - 0x11)); -#ifdef DEBUG - if (isprint(c)) - printf("%c", c); - else - printf("<0x%02x>", c); -#endif - s += 2; - } else { -#ifdef DEBUG - printf("%c", *s); -#endif - s++; - } - } -#ifdef DEBUG - printf(":"); -#endif - fflush(stdout); - } - - /* Set up to out of Name field */ - if (p == NULL || (char *)p >= pmax) - p = NULL; - else - p++; - return ((u_char *) p); -} - -/* - * NetBios Datagram Handler (IP/UDP) - */ -#define DGM_DIRECT_UNIQ 0x10 -#define DGM_DIRECT_GROUP 0x11 -#define DGM_BROADCAST 0x12 -#define DGM_ERROR 0x13 -#define DGM_QUERY 0x14 -#define DGM_POSITIVE_RES 0x15 -#define DGM_NEGATIVE_RES 0x16 - -int -AliasHandleUdpNbt( - struct libalias *la, - struct ip *pip, /* IP packet to examine/patch */ - struct alias_link *lnk, - struct in_addr *alias_address, - u_short alias_port -) -{ - struct udphdr *uh; - NbtDataHeader *ndh; - u_char *p = NULL; - char *pmax; - - (void)la; - (void)lnk; - - /* Calculate data length of UDP packet */ - uh = (struct udphdr *)ip_next(pip); - pmax = (char *)uh + ntohs(uh->uh_ulen); - - ndh = (NbtDataHeader *)udp_next(uh); - if ((char *)(ndh + 1) > pmax) - return (-1); -#ifdef DEBUG - printf("\nType=%02x,", ndh->type); -#endif - switch (ndh->type) { - case DGM_DIRECT_UNIQ: - case DGM_DIRECT_GROUP: - case DGM_BROADCAST: - p = (u_char *) ndh + 14; - p = AliasHandleName(p, pmax); /* Source Name */ - p = AliasHandleName(p, pmax); /* Destination Name */ - break; - case DGM_ERROR: - p = (u_char *) ndh + 11; - break; - case DGM_QUERY: - case DGM_POSITIVE_RES: - case DGM_NEGATIVE_RES: - p = (u_char *) ndh + 10; - p = AliasHandleName(p, pmax); /* Destination Name */ - break; - } - if (p == NULL || (char *)p > pmax) - p = NULL; -#ifdef DEBUG - printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port)); -#endif - /* Doing an IP address and Port number Translation */ - if (uh->uh_sum != 0) { - int acc; - u_short *sptr; - - acc = ndh->source_port; - acc -= alias_port; - sptr = (u_short *) & (ndh->source_ip); - acc += *sptr++; - acc += *sptr; - sptr = (u_short *) alias_address; - acc -= *sptr++; - acc -= *sptr; - ADJUST_CHECKSUM(acc, uh->uh_sum); - } - ndh->source_ip = *alias_address; - ndh->source_port = alias_port; -#ifdef DEBUG - printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port)); - fflush(stdout); -#endif - return ((p == NULL) ? -1 : 0); -} - -/* Question Section */ -#define QS_TYPE_NB 0x0020 -#define QS_TYPE_NBSTAT 0x0021 -#define QS_CLAS_IN 0x0001 -typedef struct { - u_short type; /* The type of Request */ - u_short class; /* The class of Request */ -} NBTNsQuestion; - -static u_char * -AliasHandleQuestion( - u_short count, - NBTNsQuestion * q, - char *pmax, - NBTArguments * nbtarg) -{ - - (void)nbtarg; - - while (count != 0) { - /* Name Filed */ - q = (NBTNsQuestion *) AliasHandleName((u_char *) q, pmax); - - if (q == NULL || (char *)(q + 1) > pmax) { - q = NULL; - break; - } - /* Type and Class filed */ - switch (ntohs(q->type)) { - case QS_TYPE_NB: - case QS_TYPE_NBSTAT: - q = q + 1; - break; - default: -#ifdef DEBUG - printf("\nUnknown Type on Question %0x\n", ntohs(q->type)); -#endif - break; - } - count--; - } - - /* Set up to out of Question Section */ - return ((u_char *) q); -} - -/* Resource Record */ -#define RR_TYPE_A 0x0001 -#define RR_TYPE_NS 0x0002 -#define RR_TYPE_NULL 0x000a -#define RR_TYPE_NB 0x0020 -#define RR_TYPE_NBSTAT 0x0021 -#define RR_CLAS_IN 0x0001 -#define SizeOfNsResource 8 -typedef struct { - u_short type; - u_short class; - unsigned int ttl; - u_short rdlen; -} NBTNsResource; - -#define SizeOfNsRNB 6 -typedef struct { - u_short g: 1 , ont:2, resv:13; - struct in_addr addr; -} NBTNsRNB; - -static u_char * -AliasHandleResourceNB( - NBTNsResource * q, - char *pmax, - NBTArguments * nbtarg) -{ - NBTNsRNB *nb; - u_short bcount; - - if (q == NULL || (char *)(q + 1) > pmax) - return (NULL); - /* Check out a length */ - bcount = ntohs(q->rdlen); - - /* Forward to Resource NB position */ - nb = (NBTNsRNB *) ((u_char *) q + SizeOfNsResource); - - /* Processing all in_addr array */ -#ifdef DEBUG - printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr)); - printf("->%s, %dbytes] ", inet_ntoa(nbtarg->newaddr), bcount); -#endif - while (nb != NULL && bcount != 0) { - if ((char *)(nb + 1) > pmax) { - nb = NULL; - break; - } -#ifdef DEBUG - printf("<%s>", inet_ntoa(nb->addr)); -#endif - if (!bcmp(&nbtarg->oldaddr, &nb->addr, sizeof(struct in_addr))) { - if (*nbtarg->uh_sum != 0) { - int acc; - u_short *sptr; - - sptr = (u_short *) & (nb->addr); - acc = *sptr++; - acc += *sptr; - sptr = (u_short *) & (nbtarg->newaddr); - acc -= *sptr++; - acc -= *sptr; - ADJUST_CHECKSUM(acc, *nbtarg->uh_sum); - } - nb->addr = nbtarg->newaddr; -#ifdef DEBUG - printf("O"); -#endif - } -#ifdef DEBUG - else { - printf("."); - } -#endif - nb = (NBTNsRNB *) ((u_char *) nb + SizeOfNsRNB); - bcount -= SizeOfNsRNB; - } - if (nb == NULL || (char *)(nb + 1) > pmax) { - nb = NULL; - } - return ((u_char *) nb); -} - -#define SizeOfResourceA 6 -typedef struct { - struct in_addr addr; -} NBTNsResourceA; - -static u_char * -AliasHandleResourceA( - NBTNsResource * q, - char *pmax, - NBTArguments * nbtarg) -{ - NBTNsResourceA *a; - u_short bcount; - - if (q == NULL || (char *)(q + 1) > pmax) - return (NULL); - - /* Forward to Resource A position */ - a = (NBTNsResourceA *) ((u_char *) q + sizeof(NBTNsResource)); - - /* Check out of length */ - bcount = ntohs(q->rdlen); - - /* Processing all in_addr array */ -#ifdef DEBUG - printf("Arec [%s", inet_ntoa(nbtarg->oldaddr)); - printf("->%s]", inet_ntoa(nbtarg->newaddr)); -#endif - while (bcount != 0) { - if (a == NULL || (char *)(a + 1) > pmax) - return (NULL); -#ifdef DEBUG - printf("..%s", inet_ntoa(a->addr)); -#endif - if (!bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr))) { - if (*nbtarg->uh_sum != 0) { - int acc; - u_short *sptr; - - sptr = (u_short *) & (a->addr); /* Old */ - acc = *sptr++; - acc += *sptr; - sptr = (u_short *) & nbtarg->newaddr; /* New */ - acc -= *sptr++; - acc -= *sptr; - ADJUST_CHECKSUM(acc, *nbtarg->uh_sum); - } - a->addr = nbtarg->newaddr; - } - a++; /* XXXX */ - bcount -= SizeOfResourceA; - } - if (a == NULL || (char *)(a + 1) > pmax) - a = NULL; - return ((u_char *) a); -} - -typedef struct { - u_short opcode:4, flags:8, resv:4; -} NBTNsResourceNULL; - -static u_char * -AliasHandleResourceNULL( - NBTNsResource * q, - char *pmax, - NBTArguments * nbtarg) -{ - NBTNsResourceNULL *n; - u_short bcount; - - (void)nbtarg; - - if (q == NULL || (char *)(q + 1) > pmax) - return (NULL); - - /* Forward to Resource NULL position */ - n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource)); - - /* Check out of length */ - bcount = ntohs(q->rdlen); - - /* Processing all in_addr array */ - while (bcount != 0) { - if ((char *)(n + 1) > pmax) { - n = NULL; - break; - } - n++; - bcount -= sizeof(NBTNsResourceNULL); - } - if ((char *)(n + 1) > pmax) - n = NULL; - - return ((u_char *) n); -} - -static u_char * -AliasHandleResourceNS( - NBTNsResource * q, - char *pmax, - NBTArguments * nbtarg) -{ - NBTNsResourceNULL *n; - u_short bcount; - - (void)nbtarg; - - if (q == NULL || (char *)(q + 1) > pmax) - return (NULL); - - /* Forward to Resource NULL position */ - n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource)); - - /* Check out of length */ - bcount = ntohs(q->rdlen); - - /* Resource Record Name Filed */ - q = (NBTNsResource *) AliasHandleName((u_char *) n, pmax); /* XXX */ - - if (q == NULL || (char *)((u_char *) n + bcount) > pmax) - return (NULL); - else - return ((u_char *) n + bcount); -} - -typedef struct { - u_short numnames; -} NBTNsResourceNBSTAT; - -static u_char * -AliasHandleResourceNBSTAT( - NBTNsResource * q, - char *pmax, - NBTArguments * nbtarg) -{ - NBTNsResourceNBSTAT *n; - u_short bcount; - - (void)nbtarg; - - if (q == NULL || (char *)(q + 1) > pmax) - return (NULL); - - /* Forward to Resource NBSTAT position */ - n = (NBTNsResourceNBSTAT *) ((u_char *) q + sizeof(NBTNsResource)); - - /* Check out of length */ - bcount = ntohs(q->rdlen); - - if (q == NULL || (char *)((u_char *) n + bcount) > pmax) - return (NULL); - else - return ((u_char *) n + bcount); -} - -static u_char * -AliasHandleResource( - u_short count, - NBTNsResource * q, - char *pmax, - NBTArguments - * nbtarg) -{ - while (count != 0) { - /* Resource Record Name Filed */ - q = (NBTNsResource *) AliasHandleName((u_char *) q, pmax); - - if (q == NULL || (char *)(q + 1) > pmax) - break; -#ifdef DEBUG - printf("type=%02x, count=%d\n", ntohs(q->type), count); -#endif - - /* Type and Class filed */ - switch (ntohs(q->type)) { - case RR_TYPE_NB: - q = (NBTNsResource *) AliasHandleResourceNB( - q, - pmax, - nbtarg - ); - break; - case RR_TYPE_A: - q = (NBTNsResource *) AliasHandleResourceA( - q, - pmax, - nbtarg - ); - break; - case RR_TYPE_NS: - q = (NBTNsResource *) AliasHandleResourceNS( - q, - pmax, - nbtarg - ); - break; - case RR_TYPE_NULL: - q = (NBTNsResource *) AliasHandleResourceNULL( - q, - pmax, - nbtarg - ); - break; - case RR_TYPE_NBSTAT: - q = (NBTNsResource *) AliasHandleResourceNBSTAT( - q, - pmax, - nbtarg - ); - break; - default: -#ifdef DEBUG - printf( - "\nUnknown Type of Resource %0x\n", - ntohs(q->type) - ); -#endif - break; - } - count--; - } - fflush(stdout); - return ((u_char *) q); -} - -int -AliasHandleUdpNbtNS( - struct libalias *la, - struct ip *pip, /* IP packet to examine/patch */ - struct alias_link *lnk, - struct in_addr *alias_address, - u_short * alias_port, - struct in_addr *original_address, - u_short * original_port) -{ - struct udphdr *uh; - NbtNSHeader *nsh; - u_char *p; - char *pmax; - NBTArguments nbtarg; - - (void)la; - (void)lnk; - - /* Set up Common Parameter */ - nbtarg.oldaddr = *alias_address; - nbtarg.oldport = *alias_port; - nbtarg.newaddr = *original_address; - nbtarg.newport = *original_port; - - /* Calculate data length of UDP packet */ - uh = (struct udphdr *)ip_next(pip); - nbtarg.uh_sum = &(uh->uh_sum); - nsh = (NbtNSHeader *)udp_next(uh); - p = (u_char *) (nsh + 1); - pmax = (char *)uh + ntohs(uh->uh_ulen); - - if ((char *)(nsh + 1) > pmax) - return (-1); - -#ifdef DEBUG - printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x" - ", an=%04x, ns=%04x, ar=%04x, [%d]-->", - nsh->dir ? "Response" : "Request", - nsh->nametrid, - nsh->opcode, - nsh->nmflags, - nsh->rcode, - ntohs(nsh->qdcount), - ntohs(nsh->ancount), - ntohs(nsh->nscount), - ntohs(nsh->arcount), - (u_char *) p - (u_char *) nsh - ); -#endif - - /* Question Entries */ - if (ntohs(nsh->qdcount) != 0) { - p = AliasHandleQuestion( - ntohs(nsh->qdcount), - (NBTNsQuestion *) p, - pmax, - &nbtarg - ); - } - /* Answer Resource Records */ - if (ntohs(nsh->ancount) != 0) { - p = AliasHandleResource( - ntohs(nsh->ancount), - (NBTNsResource *) p, - pmax, - &nbtarg - ); - } - /* Authority Resource Recodrs */ - if (ntohs(nsh->nscount) != 0) { - p = AliasHandleResource( - ntohs(nsh->nscount), - (NBTNsResource *) p, - pmax, - &nbtarg - ); - } - /* Additional Resource Recodrs */ - if (ntohs(nsh->arcount) != 0) { - p = AliasHandleResource( - ntohs(nsh->arcount), - (NBTNsResource *) p, - pmax, - &nbtarg - ); - } -#ifdef DEBUG - PrintRcode(nsh->rcode); -#endif - return ((p == NULL) ? -1 : 0); -} |