]>
git.saurik.com Git - apple/network_cmds.git/blob - alias/alias_nbt.c
d2199f68834de4a136bfd23767fcea599d8d72d5
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 * Written by Atsushi Murai <amurai@spec.co.jp>
25 * Copyright (c) 1998, System Planning and Engineering Co.
26 * All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
37 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
38 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * $FreeBSD: src/lib/libalias/alias_nbt.c,v 1.4.2.3 2001/08/01 09:52:26 obrien Exp $
54 * oConsidering for word alignment for other platform.
57 alias_nbt.c performs special processing for NetBios over TCP/IP
60 Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>)
62 See HISTORY file for record of revisions.
69 #include <sys/types.h>
70 #include <netinet/in_systm.h>
71 #include <netinet/in.h>
72 #include <arpa/inet.h>
73 #include <netinet/ip.h>
74 #include <netinet/udp.h>
75 #include <netinet/tcp.h>
77 #include "alias_local.h"
80 struct in_addr oldaddr
;
82 struct in_addr newaddr
;
91 struct in_addr source_ip
;
105 u_short dir
:1, opcode
:4, nmflags
:7, rcode
:4;
121 static void PrintRcode( u_char rcode
) {
125 printf("\nFormat Error.");
127 printf("\nSever failure.");
129 printf("\nUnsupported request error.\n");
131 printf("\nRefused error.\n");
133 printf("\nActive error.\n");
135 printf("\nName in conflict error.\n");
137 printf("\n???=%0x\n", rcode
);
144 /* Handling Name field */
145 static u_char
*AliasHandleName ( u_char
*p
, char *pmax
) {
151 /* Following length field */
153 if (p
== NULL
|| (char *)p
>= pmax
)
158 if ((char *)p
> pmax
)
160 return ((u_char
*)p
);
162 while ( ( *p
& 0x3f) != 0x00 ) {
169 /* Get next length field */
170 p
= (u_char
*)(p
+ (*p
& 0x3f) + 1);
171 if ((char *)p
> pmax
) {
179 if ( compress
== 1 ) {
180 c
= (u_char
)(((((*s
& 0x0f) << 4) | (*(s
+1) & 0x0f)) - 0x11));
185 printf("<0x%02x>", c
);
201 /* Set up to out of Name field */
202 if (p
== NULL
|| (char *)p
>= pmax
)
206 return ((u_char
*)p
);
210 * NetBios Datagram Handler (IP/UDP)
212 #define DGM_DIRECT_UNIQ 0x10
213 #define DGM_DIRECT_GROUP 0x11
214 #define DGM_BROADCAST 0x12
215 #define DGM_ERROR 0x13
216 #define DGM_QUERY 0x14
217 #define DGM_POSITIVE_RES 0x15
218 #define DGM_NEGATIVE_RES 0x16
220 int AliasHandleUdpNbt(
221 struct ip
*pip
, /* IP packet to examine/patch */
222 struct alias_link
*link
,
223 struct in_addr
*alias_address
,
231 /* Calculate data length of UDP packet */
232 uh
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
233 pmax
= (char *)uh
+ ntohs( uh
->uh_ulen
);
235 ndh
= (NbtDataHeader
*)((char *)uh
+ (sizeof (struct udphdr
)));
236 if ((char *)(ndh
+ 1) > pmax
)
239 printf("\nType=%02x,", ndh
->type
);
241 switch ( ndh
->type
) {
242 case DGM_DIRECT_UNIQ
:
243 case DGM_DIRECT_GROUP
:
245 p
= (u_char
*)ndh
+ 14;
246 p
= AliasHandleName ( p
, pmax
); /* Source Name */
247 p
= AliasHandleName ( p
, pmax
); /* Destination Name */
250 p
= (u_char
*)ndh
+ 11;
253 case DGM_POSITIVE_RES
:
254 case DGM_NEGATIVE_RES
:
255 p
= (u_char
*)ndh
+ 10;
256 p
= AliasHandleName ( p
, pmax
); /* Destination Name */
259 if (p
== NULL
|| (char *)p
> pmax
)
262 printf("%s:%d-->", inet_ntoa(ndh
->source_ip
), ntohs(ndh
->source_port
) );
264 /* Doing a IP address and Port number Translation */
265 if ( uh
->uh_sum
!= 0 ) {
268 acc
= ndh
->source_port
;
270 sptr
= (u_short
*) &(ndh
->source_ip
);
273 sptr
= (u_short
*) alias_address
;
276 ADJUST_CHECKSUM(acc
, uh
->uh_sum
);
278 ndh
->source_ip
= *alias_address
;
279 ndh
->source_port
= alias_port
;
281 printf("%s:%d\n", inet_ntoa(ndh
->source_ip
), ntohs(ndh
->source_port
) );
284 return((p
== NULL
) ? -1 : 0);
286 /* Question Section */
287 #define QS_TYPE_NB 0x0020
288 #define QS_TYPE_NBSTAT 0x0021
289 #define QS_CLAS_IN 0x0001
291 u_short type
; /* The type of Request */
292 u_short
class; /* The class of Request */
300 NBTArguments
*nbtarg
)
303 while ( count
!= 0 ) {
305 q
= (NBTNsQuestion
*)AliasHandleName((u_char
*)q
, pmax
);
307 if (q
== NULL
|| (char *)(q
+ 1) > pmax
) {
312 /* Type and Class filed */
313 switch ( ntohs(q
->type
) ) {
320 printf("\nUnknown Type on Question %0x\n", ntohs(q
->type
) );
327 /* Set up to out of Question Section */
328 return ((u_char
*)q
);
331 /* Resource Record */
332 #define RR_TYPE_A 0x0001
333 #define RR_TYPE_NS 0x0002
334 #define RR_TYPE_NULL 0x000a
335 #define RR_TYPE_NB 0x0020
336 #define RR_TYPE_NBSTAT 0x0021
337 #define RR_CLAS_IN 0x0001
338 #define SizeOfNsResource 8
346 #define SizeOfNsRNB 6
348 u_short g
:1, ont
:2, resv
:13;
353 AliasHandleResourceNB(
356 NBTArguments
*nbtarg
)
361 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
363 /* Check out a length */
364 bcount
= ntohs(q
->rdlen
);
366 /* Forward to Resource NB position */
367 nb
= (NBTNsRNB
*)((u_char
*)q
+ SizeOfNsResource
);
369 /* Processing all in_addr array */
371 printf("NB rec[%s", inet_ntoa(nbtarg
->oldaddr
));
372 printf("->%s, %dbytes] ",inet_ntoa(nbtarg
->newaddr
), bcount
);
374 while ( nb
!= NULL
&& bcount
!= 0 ) {
375 if ((char *)(nb
+ 1) > pmax
) {
380 printf("<%s>", inet_ntoa(nb
->addr
) );
382 if (!bcmp(&nbtarg
->oldaddr
,&nb
->addr
, sizeof(struct in_addr
) ) ) {
383 if ( *nbtarg
->uh_sum
!= 0 ) {
387 sptr
= (u_short
*) &(nb
->addr
);
390 sptr
= (u_short
*) &(nbtarg
->newaddr
);
393 ADJUST_CHECKSUM(acc
, *nbtarg
->uh_sum
);
396 nb
->addr
= nbtarg
->newaddr
;
406 nb
=(NBTNsRNB
*)((u_char
*)nb
+ SizeOfNsRNB
);
407 bcount
-= SizeOfNsRNB
;
409 if (nb
== NULL
|| (char *)(nb
+ 1) > pmax
) {
413 return ((u_char
*)nb
);
416 #define SizeOfResourceA 6
422 AliasHandleResourceA(
425 NBTArguments
*nbtarg
)
430 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
433 /* Forward to Resource A position */
434 a
= (NBTNsResourceA
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
436 /* Check out of length */
437 bcount
= ntohs(q
->rdlen
);
439 /* Processing all in_addr array */
441 printf("Arec [%s", inet_ntoa(nbtarg
->oldaddr
));
442 printf("->%s]",inet_ntoa(nbtarg
->newaddr
));
444 while ( bcount
!= 0 ) {
445 if (a
== NULL
|| (char *)(a
+ 1) > pmax
)
448 printf("..%s", inet_ntoa(a
->addr
) );
450 if ( !bcmp(&nbtarg
->oldaddr
, &a
->addr
, sizeof(struct in_addr
) ) ) {
451 if ( *nbtarg
->uh_sum
!= 0 ) {
455 sptr
= (u_short
*) &(a
->addr
); /* Old */
458 sptr
= (u_short
*) &nbtarg
->newaddr
; /* New */
461 ADJUST_CHECKSUM(acc
, *nbtarg
->uh_sum
);
464 a
->addr
= nbtarg
->newaddr
;
467 bcount
-= SizeOfResourceA
;
469 if (a
== NULL
|| (char *)(a
+ 1) > pmax
)
471 return ((u_char
*)a
);
475 u_short opcode
:4, flags
:8, resv
:4;
479 AliasHandleResourceNULL(
482 NBTArguments
*nbtarg
)
484 NBTNsResourceNULL
*n
;
487 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
490 /* Forward to Resource NULL position */
491 n
= (NBTNsResourceNULL
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
493 /* Check out of length */
494 bcount
= ntohs(q
->rdlen
);
496 /* Processing all in_addr array */
497 while ( bcount
!= 0 ) {
498 if ((char *)(n
+ 1) > pmax
) {
503 bcount
-= sizeof(NBTNsResourceNULL
);
505 if ((char *)(n
+ 1) > pmax
)
508 return ((u_char
*)n
);
512 AliasHandleResourceNS(
515 NBTArguments
*nbtarg
)
517 NBTNsResourceNULL
*n
;
520 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
523 /* Forward to Resource NULL position */
524 n
= (NBTNsResourceNULL
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
526 /* Check out of length */
527 bcount
= ntohs(q
->rdlen
);
529 /* Resource Record Name Filed */
530 q
= (NBTNsResource
*)AliasHandleName( (u_char
*)n
, pmax
); /* XXX */
532 if (q
== NULL
|| (char *)((u_char
*)n
+ bcount
) > pmax
)
535 return ((u_char
*)n
+ bcount
);
540 } NBTNsResourceNBSTAT
;
543 AliasHandleResourceNBSTAT(
546 NBTArguments
*nbtarg
)
548 NBTNsResourceNBSTAT
*n
;
551 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
554 /* Forward to Resource NBSTAT position */
555 n
= (NBTNsResourceNBSTAT
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
557 /* Check out of length */
558 bcount
= ntohs(q
->rdlen
);
560 if (q
== NULL
|| (char *)((u_char
*)n
+ bcount
) > pmax
)
563 return ((u_char
*)n
+ bcount
);
574 while ( count
!= 0 ) {
575 /* Resource Record Name Filed */
576 q
= (NBTNsResource
*)AliasHandleName( (u_char
*)q
, pmax
);
578 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
581 printf("type=%02x, count=%d\n", ntohs(q
->type
), count
);
584 /* Type and Class filed */
585 switch ( ntohs(q
->type
) ) {
587 q
= (NBTNsResource
*)AliasHandleResourceNB(
594 q
= (NBTNsResource
*)AliasHandleResourceA(
601 q
= (NBTNsResource
*)AliasHandleResourceNS(
608 q
= (NBTNsResource
*)AliasHandleResourceNULL(
615 q
= (NBTNsResource
*)AliasHandleResourceNBSTAT(
624 "\nUnknown Type of Resource %0x\n",
633 return ((u_char
*)q
);
636 int AliasHandleUdpNbtNS(
637 struct ip
*pip
, /* IP packet to examine/patch */
638 struct alias_link
*link
,
639 struct in_addr
*alias_address
,
641 struct in_addr
*original_address
,
642 u_short
*original_port
)
650 /* Set up Common Parameter */
651 nbtarg
.oldaddr
= *alias_address
;
652 nbtarg
.oldport
= *alias_port
;
653 nbtarg
.newaddr
= *original_address
;
654 nbtarg
.newport
= *original_port
;
656 /* Calculate data length of UDP packet */
657 uh
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
658 nbtarg
.uh_sum
= &(uh
->uh_sum
);
659 nsh
= (NbtNSHeader
*)((char *)uh
+ (sizeof(struct udphdr
)));
660 p
= (u_char
*)(nsh
+ 1);
661 pmax
= (char *)uh
+ ntohs( uh
->uh_ulen
);
663 if ((char *)(nsh
+ 1) > pmax
)
667 printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
668 ", an=%04x, ns=%04x, ar=%04x, [%d]-->",
669 nsh
->dir
? "Response": "Request",
678 (u_char
*)p
-(u_char
*)nsh
682 /* Question Entries */
683 if (ntohs(nsh
->qdcount
) !=0 ) {
684 p
= AliasHandleQuestion(
692 /* Answer Resource Records */
693 if (ntohs(nsh
->ancount
) !=0 ) {
694 p
= AliasHandleResource(
702 /* Authority Resource Recodrs */
703 if (ntohs(nsh
->nscount
) !=0 ) {
704 p
= AliasHandleResource(
712 /* Additional Resource Recodrs */
713 if (ntohs(nsh
->arcount
) !=0 ) {
714 p
= AliasHandleResource(
723 PrintRcode(nsh
->rcode
);
725 return ((p
== NULL
) ? -1 : 0);