]>
git.saurik.com Git - apple/network_cmds.git/blob - alias/alias_nbt.c
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Written by Atsushi Murai <amurai@spec.co.jp>
24 * Copyright (c) 1998, System Planning and Engineering Co.
25 * All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
36 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
37 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
40 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
42 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 * $FreeBSD: src/lib/libalias/alias_nbt.c,v 1.4.2.3 2001/08/01 09:52:26 obrien Exp $
53 * oConsidering for word alignment for other platform.
56 alias_nbt.c performs special processing for NetBios over TCP/IP
59 Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>)
61 See HISTORY file for record of revisions.
68 #include <sys/types.h>
69 #include <netinet/in_systm.h>
70 #include <netinet/in.h>
71 #include <arpa/inet.h>
72 #include <netinet/ip.h>
73 #include <netinet/udp.h>
74 #include <netinet/tcp.h>
76 #include "alias_local.h"
79 struct in_addr oldaddr
;
81 struct in_addr newaddr
;
90 struct in_addr source_ip
;
104 u_short dir
:1, opcode
:4, nmflags
:7, rcode
:4;
120 static void PrintRcode( u_char rcode
) {
124 printf("\n Format Error.\n");
127 printf("\n Server failure.\n");
130 printf("\n Unsupported request error.\n");
133 printf("\n Refused error.\n");
136 printf("\n Active error.\n");
139 printf("\n Name in conflict error.\n");
142 printf("\n \?\?\?=%0x\n", rcode
);
149 /* Handling Name field */
150 static u_char
*AliasHandleName ( u_char
*p
, char *pmax
) {
156 /* Following length field */
158 if (p
== NULL
|| (char *)p
>= pmax
)
163 if ((char *)p
> pmax
)
165 return ((u_char
*)p
);
167 while ( ( *p
& 0x3f) != 0x00 ) {
174 /* Get next length field */
175 p
= (u_char
*)(p
+ (*p
& 0x3f) + 1);
176 if ((char *)p
> pmax
) {
184 if ( compress
== 1 ) {
185 c
= (u_char
)(((((*s
& 0x0f) << 4) | (*(s
+1) & 0x0f)) - 0x11));
190 printf("<0x%02x>", c
);
206 /* Set up to out of Name field */
207 if (p
== NULL
|| (char *)p
>= pmax
)
211 return ((u_char
*)p
);
215 * NetBios Datagram Handler (IP/UDP)
217 #define DGM_DIRECT_UNIQ 0x10
218 #define DGM_DIRECT_GROUP 0x11
219 #define DGM_BROADCAST 0x12
220 #define DGM_ERROR 0x13
221 #define DGM_QUERY 0x14
222 #define DGM_POSITIVE_RES 0x15
223 #define DGM_NEGATIVE_RES 0x16
225 int AliasHandleUdpNbt(
226 struct ip
*pip
, /* IP packet to examine/patch */
227 struct alias_link
*link
,
228 struct in_addr
*alias_address
,
236 /* Calculate data length of UDP packet */
237 uh
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
238 pmax
= (char *)uh
+ ntohs( uh
->uh_ulen
);
240 ndh
= (NbtDataHeader
*)((char *)uh
+ (sizeof (struct udphdr
)));
241 if ((char *)(ndh
+ 1) > pmax
)
244 printf("Type=%02x,", ndh
->type
);
246 switch ( ndh
->type
) {
247 case DGM_DIRECT_UNIQ
:
248 case DGM_DIRECT_GROUP
:
250 p
= (u_char
*)ndh
+ 14;
251 p
= AliasHandleName ( p
, pmax
); /* Source Name */
252 p
= AliasHandleName ( p
, pmax
); /* Destination Name */
255 p
= (u_char
*)ndh
+ 11;
258 case DGM_POSITIVE_RES
:
259 case DGM_NEGATIVE_RES
:
260 p
= (u_char
*)ndh
+ 10;
261 p
= AliasHandleName ( p
, pmax
); /* Destination Name */
264 if (p
== NULL
|| (char *)p
> pmax
)
267 printf("%s:%d-->", inet_ntoa(ndh
->source_ip
), ntohs(ndh
->source_port
) );
269 /* Doing a IP address and Port number Translation */
270 if ( uh
->uh_sum
!= 0 ) {
273 acc
= ndh
->source_port
;
275 sptr
= (u_short
*) &(ndh
->source_ip
);
278 sptr
= (u_short
*) alias_address
;
281 ADJUST_CHECKSUM(acc
, uh
->uh_sum
);
283 ndh
->source_ip
= *alias_address
;
284 ndh
->source_port
= alias_port
;
286 printf("%s:%d\n", inet_ntoa(ndh
->source_ip
), ntohs(ndh
->source_port
) );
289 return((p
== NULL
) ? -1 : 0);
291 /* Question Section */
292 #define QS_TYPE_NB 0x0020
293 #define QS_TYPE_NBSTAT 0x0021
294 #define QS_CLAS_IN 0x0001
296 u_short type
; /* The type of Request */
297 u_short
class; /* The class of Request */
305 NBTArguments
*nbtarg
)
308 while ( count
!= 0 ) {
310 q
= (NBTNsQuestion
*)AliasHandleName((u_char
*)q
, pmax
);
312 if (q
== NULL
|| (char *)(q
+ 1) > pmax
) {
317 /* Type and Class filed */
318 switch ( ntohs(q
->type
) ) {
325 printf("\nUnknown Type on Question %0x\n", ntohs(q
->type
) );
332 /* Set up to out of Question Section */
333 return ((u_char
*)q
);
336 /* Resource Record */
337 #define RR_TYPE_A 0x0001
338 #define RR_TYPE_NS 0x0002
339 #define RR_TYPE_NULL 0x000a
340 #define RR_TYPE_NB 0x0020
341 #define RR_TYPE_NBSTAT 0x0021
342 #define RR_CLAS_IN 0x0001
343 #define SizeOfNsResource 8
351 #define SizeOfNsRNB 6
353 u_short g
:1, ont
:2, resv
:13;
358 AliasHandleResourceNB(
361 NBTArguments
*nbtarg
)
366 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
368 /* Check out a length */
369 bcount
= ntohs(q
->rdlen
);
371 /* Forward to Resource NB position */
372 nb
= (NBTNsRNB
*)((u_char
*)q
+ SizeOfNsResource
);
374 /* Processing all in_addr array */
376 printf(" NB rec[%s", inet_ntoa(nbtarg
->oldaddr
));
377 printf("->%s, %d bytes] ",inet_ntoa(nbtarg
->newaddr
), bcount
);
379 while ( nb
!= NULL
&& bcount
!= 0 ) {
380 if ((char *)(nb
+ 1) > pmax
) {
385 printf("<%s>", inet_ntoa(nb
->addr
) );
387 if (!bcmp(&nbtarg
->oldaddr
,&nb
->addr
, sizeof(struct in_addr
) ) ) {
388 if ( *nbtarg
->uh_sum
!= 0 ) {
392 sptr
= (u_short
*) &(nb
->addr
);
395 sptr
= (u_short
*) &(nbtarg
->newaddr
);
398 ADJUST_CHECKSUM(acc
, *nbtarg
->uh_sum
);
401 nb
->addr
= nbtarg
->newaddr
;
411 nb
=(NBTNsRNB
*)((u_char
*)nb
+ SizeOfNsRNB
);
412 bcount
-= SizeOfNsRNB
;
414 if (nb
== NULL
|| (char *)(nb
+ 1) > pmax
) {
418 return ((u_char
*)nb
);
421 #define SizeOfResourceA 6
427 AliasHandleResourceA(
430 NBTArguments
*nbtarg
)
435 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
438 /* Forward to Resource A position */
439 a
= (NBTNsResourceA
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
441 /* Check out of length */
442 bcount
= ntohs(q
->rdlen
);
444 /* Processing all in_addr array */
446 printf("Arec [%s", inet_ntoa(nbtarg
->oldaddr
));
447 printf("->%s]",inet_ntoa(nbtarg
->newaddr
));
449 while ( bcount
!= 0 ) {
450 if (a
== NULL
|| (char *)(a
+ 1) > pmax
)
453 printf("..%s", inet_ntoa(a
->addr
) );
455 if ( !bcmp(&nbtarg
->oldaddr
, &a
->addr
, sizeof(struct in_addr
) ) ) {
456 if ( *nbtarg
->uh_sum
!= 0 ) {
460 sptr
= (u_short
*) &(a
->addr
); /* Old */
463 sptr
= (u_short
*) &nbtarg
->newaddr
; /* New */
466 ADJUST_CHECKSUM(acc
, *nbtarg
->uh_sum
);
469 a
->addr
= nbtarg
->newaddr
;
472 bcount
-= SizeOfResourceA
;
474 if (a
== NULL
|| (char *)(a
+ 1) > pmax
)
476 return ((u_char
*)a
);
480 u_short opcode
:4, flags
:8, resv
:4;
484 AliasHandleResourceNULL(
487 NBTArguments
*nbtarg
)
489 NBTNsResourceNULL
*n
;
492 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
495 /* Forward to Resource NULL position */
496 n
= (NBTNsResourceNULL
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
498 /* Check out of length */
499 bcount
= ntohs(q
->rdlen
);
501 /* Processing all in_addr array */
502 while ( bcount
!= 0 ) {
503 if ((char *)(n
+ 1) > pmax
) {
508 bcount
-= sizeof(NBTNsResourceNULL
);
510 if ((char *)(n
+ 1) > pmax
)
513 return ((u_char
*)n
);
517 AliasHandleResourceNS(
520 NBTArguments
*nbtarg
)
522 NBTNsResourceNULL
*n
;
525 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
528 /* Forward to Resource NULL position */
529 n
= (NBTNsResourceNULL
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
531 /* Check out of length */
532 bcount
= ntohs(q
->rdlen
);
534 /* Resource Record Name Filed */
535 q
= (NBTNsResource
*)AliasHandleName( (u_char
*)n
, pmax
); /* XXX */
537 if (q
== NULL
|| (char *)((u_char
*)n
+ bcount
) > pmax
)
540 return ((u_char
*)n
+ bcount
);
545 } NBTNsResourceNBSTAT
;
548 AliasHandleResourceNBSTAT(
551 NBTArguments
*nbtarg
)
553 NBTNsResourceNBSTAT
*n
;
556 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
559 /* Forward to Resource NBSTAT position */
560 n
= (NBTNsResourceNBSTAT
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
562 /* Check out of length */
563 bcount
= ntohs(q
->rdlen
);
565 if (q
== NULL
|| (char *)((u_char
*)n
+ bcount
) > pmax
)
568 return ((u_char
*)n
+ bcount
);
579 while ( count
!= 0 ) {
580 /* Resource Record Name Filed */
581 q
= (NBTNsResource
*)AliasHandleName( (u_char
*)q
, pmax
);
583 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
586 printf("\n type=%02x, count=%d\n", ntohs(q
->type
), count
);
589 /* Type and Class filed */
590 switch ( ntohs(q
->type
) ) {
592 q
= (NBTNsResource
*)AliasHandleResourceNB(
599 q
= (NBTNsResource
*)AliasHandleResourceA(
606 q
= (NBTNsResource
*)AliasHandleResourceNS(
613 q
= (NBTNsResource
*)AliasHandleResourceNULL(
620 q
= (NBTNsResource
*)AliasHandleResourceNBSTAT(
629 "\nUnknown Type of Resource %0x\n",
638 return ((u_char
*)q
);
641 int AliasHandleUdpNbtNS(
642 struct ip
*pip
, /* IP packet to examine/patch */
643 struct alias_link
*link
,
644 struct in_addr
*alias_address
,
646 struct in_addr
*original_address
,
647 u_short
*original_port
)
655 /* Set up Common Parameter */
656 nbtarg
.oldaddr
= *alias_address
;
657 nbtarg
.oldport
= *alias_port
;
658 nbtarg
.newaddr
= *original_address
;
659 nbtarg
.newport
= *original_port
;
661 /* Calculate data length of UDP packet */
662 uh
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
663 nbtarg
.uh_sum
= &(uh
->uh_sum
);
664 nsh
= (NbtNSHeader
*)((char *)uh
+ (sizeof(struct udphdr
)));
665 p
= (u_char
*)(nsh
+ 1);
666 pmax
= (char *)uh
+ ntohs( uh
->uh_ulen
);
668 if ((char *)(nsh
+ 1) > pmax
)
672 printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
673 ", an=%04x, ns=%04x, ar=%04x, [%d]-->",
674 nsh
->dir
? "Response": "Request",
683 (int)((u_char
*)p
-(u_char
*)nsh
)
687 /* Question Entries */
688 if (ntohs(nsh
->qdcount
) !=0 ) {
689 p
= AliasHandleQuestion(
697 /* Answer Resource Records */
698 if (ntohs(nsh
->ancount
) !=0 ) {
699 p
= AliasHandleResource(
707 /* Authority Resource Recodrs */
708 if (ntohs(nsh
->nscount
) !=0 ) {
709 p
= AliasHandleResource(
717 /* Additional Resource Recodrs */
718 if (ntohs(nsh
->arcount
) !=0 ) {
719 p
= AliasHandleResource(
729 PrintRcode(nsh
->rcode
);
731 return ((p
== NULL
) ? -1 : 0);