]>
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("\nFormat Error.");
126 printf("\nSever failure.");
128 printf("\nUnsupported request error.\n");
130 printf("\nRefused error.\n");
132 printf("\nActive error.\n");
134 printf("\nName in conflict error.\n");
136 printf("\n???=%0x\n", rcode
);
143 /* Handling Name field */
144 static u_char
*AliasHandleName ( u_char
*p
, char *pmax
) {
150 /* Following length field */
152 if (p
== NULL
|| (char *)p
>= pmax
)
157 if ((char *)p
> pmax
)
159 return ((u_char
*)p
);
161 while ( ( *p
& 0x3f) != 0x00 ) {
168 /* Get next length field */
169 p
= (u_char
*)(p
+ (*p
& 0x3f) + 1);
170 if ((char *)p
> pmax
) {
178 if ( compress
== 1 ) {
179 c
= (u_char
)(((((*s
& 0x0f) << 4) | (*(s
+1) & 0x0f)) - 0x11));
184 printf("<0x%02x>", c
);
200 /* Set up to out of Name field */
201 if (p
== NULL
|| (char *)p
>= pmax
)
205 return ((u_char
*)p
);
209 * NetBios Datagram Handler (IP/UDP)
211 #define DGM_DIRECT_UNIQ 0x10
212 #define DGM_DIRECT_GROUP 0x11
213 #define DGM_BROADCAST 0x12
214 #define DGM_ERROR 0x13
215 #define DGM_QUERY 0x14
216 #define DGM_POSITIVE_RES 0x15
217 #define DGM_NEGATIVE_RES 0x16
219 int AliasHandleUdpNbt(
220 struct ip
*pip
, /* IP packet to examine/patch */
221 struct alias_link
*link
,
222 struct in_addr
*alias_address
,
230 /* Calculate data length of UDP packet */
231 uh
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
232 pmax
= (char *)uh
+ ntohs( uh
->uh_ulen
);
234 ndh
= (NbtDataHeader
*)((char *)uh
+ (sizeof (struct udphdr
)));
235 if ((char *)(ndh
+ 1) > pmax
)
238 printf("\nType=%02x,", ndh
->type
);
240 switch ( ndh
->type
) {
241 case DGM_DIRECT_UNIQ
:
242 case DGM_DIRECT_GROUP
:
244 p
= (u_char
*)ndh
+ 14;
245 p
= AliasHandleName ( p
, pmax
); /* Source Name */
246 p
= AliasHandleName ( p
, pmax
); /* Destination Name */
249 p
= (u_char
*)ndh
+ 11;
252 case DGM_POSITIVE_RES
:
253 case DGM_NEGATIVE_RES
:
254 p
= (u_char
*)ndh
+ 10;
255 p
= AliasHandleName ( p
, pmax
); /* Destination Name */
258 if (p
== NULL
|| (char *)p
> pmax
)
261 printf("%s:%d-->", inet_ntoa(ndh
->source_ip
), ntohs(ndh
->source_port
) );
263 /* Doing a IP address and Port number Translation */
264 if ( uh
->uh_sum
!= 0 ) {
267 acc
= ndh
->source_port
;
269 sptr
= (u_short
*) &(ndh
->source_ip
);
272 sptr
= (u_short
*) alias_address
;
275 ADJUST_CHECKSUM(acc
, uh
->uh_sum
);
277 ndh
->source_ip
= *alias_address
;
278 ndh
->source_port
= alias_port
;
280 printf("%s:%d\n", inet_ntoa(ndh
->source_ip
), ntohs(ndh
->source_port
) );
283 return((p
== NULL
) ? -1 : 0);
285 /* Question Section */
286 #define QS_TYPE_NB 0x0020
287 #define QS_TYPE_NBSTAT 0x0021
288 #define QS_CLAS_IN 0x0001
290 u_short type
; /* The type of Request */
291 u_short
class; /* The class of Request */
299 NBTArguments
*nbtarg
)
302 while ( count
!= 0 ) {
304 q
= (NBTNsQuestion
*)AliasHandleName((u_char
*)q
, pmax
);
306 if (q
== NULL
|| (char *)(q
+ 1) > pmax
) {
311 /* Type and Class filed */
312 switch ( ntohs(q
->type
) ) {
319 printf("\nUnknown Type on Question %0x\n", ntohs(q
->type
) );
326 /* Set up to out of Question Section */
327 return ((u_char
*)q
);
330 /* Resource Record */
331 #define RR_TYPE_A 0x0001
332 #define RR_TYPE_NS 0x0002
333 #define RR_TYPE_NULL 0x000a
334 #define RR_TYPE_NB 0x0020
335 #define RR_TYPE_NBSTAT 0x0021
336 #define RR_CLAS_IN 0x0001
337 #define SizeOfNsResource 8
345 #define SizeOfNsRNB 6
347 u_short g
:1, ont
:2, resv
:13;
352 AliasHandleResourceNB(
355 NBTArguments
*nbtarg
)
360 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
362 /* Check out a length */
363 bcount
= ntohs(q
->rdlen
);
365 /* Forward to Resource NB position */
366 nb
= (NBTNsRNB
*)((u_char
*)q
+ SizeOfNsResource
);
368 /* Processing all in_addr array */
370 printf("NB rec[%s", inet_ntoa(nbtarg
->oldaddr
));
371 printf("->%s, %dbytes] ",inet_ntoa(nbtarg
->newaddr
), bcount
);
373 while ( nb
!= NULL
&& bcount
!= 0 ) {
374 if ((char *)(nb
+ 1) > pmax
) {
379 printf("<%s>", inet_ntoa(nb
->addr
) );
381 if (!bcmp(&nbtarg
->oldaddr
,&nb
->addr
, sizeof(struct in_addr
) ) ) {
382 if ( *nbtarg
->uh_sum
!= 0 ) {
386 sptr
= (u_short
*) &(nb
->addr
);
389 sptr
= (u_short
*) &(nbtarg
->newaddr
);
392 ADJUST_CHECKSUM(acc
, *nbtarg
->uh_sum
);
395 nb
->addr
= nbtarg
->newaddr
;
405 nb
=(NBTNsRNB
*)((u_char
*)nb
+ SizeOfNsRNB
);
406 bcount
-= SizeOfNsRNB
;
408 if (nb
== NULL
|| (char *)(nb
+ 1) > pmax
) {
412 return ((u_char
*)nb
);
415 #define SizeOfResourceA 6
421 AliasHandleResourceA(
424 NBTArguments
*nbtarg
)
429 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
432 /* Forward to Resource A position */
433 a
= (NBTNsResourceA
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
435 /* Check out of length */
436 bcount
= ntohs(q
->rdlen
);
438 /* Processing all in_addr array */
440 printf("Arec [%s", inet_ntoa(nbtarg
->oldaddr
));
441 printf("->%s]",inet_ntoa(nbtarg
->newaddr
));
443 while ( bcount
!= 0 ) {
444 if (a
== NULL
|| (char *)(a
+ 1) > pmax
)
447 printf("..%s", inet_ntoa(a
->addr
) );
449 if ( !bcmp(&nbtarg
->oldaddr
, &a
->addr
, sizeof(struct in_addr
) ) ) {
450 if ( *nbtarg
->uh_sum
!= 0 ) {
454 sptr
= (u_short
*) &(a
->addr
); /* Old */
457 sptr
= (u_short
*) &nbtarg
->newaddr
; /* New */
460 ADJUST_CHECKSUM(acc
, *nbtarg
->uh_sum
);
463 a
->addr
= nbtarg
->newaddr
;
466 bcount
-= SizeOfResourceA
;
468 if (a
== NULL
|| (char *)(a
+ 1) > pmax
)
470 return ((u_char
*)a
);
474 u_short opcode
:4, flags
:8, resv
:4;
478 AliasHandleResourceNULL(
481 NBTArguments
*nbtarg
)
483 NBTNsResourceNULL
*n
;
486 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
489 /* Forward to Resource NULL position */
490 n
= (NBTNsResourceNULL
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
492 /* Check out of length */
493 bcount
= ntohs(q
->rdlen
);
495 /* Processing all in_addr array */
496 while ( bcount
!= 0 ) {
497 if ((char *)(n
+ 1) > pmax
) {
502 bcount
-= sizeof(NBTNsResourceNULL
);
504 if ((char *)(n
+ 1) > pmax
)
507 return ((u_char
*)n
);
511 AliasHandleResourceNS(
514 NBTArguments
*nbtarg
)
516 NBTNsResourceNULL
*n
;
519 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
522 /* Forward to Resource NULL position */
523 n
= (NBTNsResourceNULL
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
525 /* Check out of length */
526 bcount
= ntohs(q
->rdlen
);
528 /* Resource Record Name Filed */
529 q
= (NBTNsResource
*)AliasHandleName( (u_char
*)n
, pmax
); /* XXX */
531 if (q
== NULL
|| (char *)((u_char
*)n
+ bcount
) > pmax
)
534 return ((u_char
*)n
+ bcount
);
539 } NBTNsResourceNBSTAT
;
542 AliasHandleResourceNBSTAT(
545 NBTArguments
*nbtarg
)
547 NBTNsResourceNBSTAT
*n
;
550 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
553 /* Forward to Resource NBSTAT position */
554 n
= (NBTNsResourceNBSTAT
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
556 /* Check out of length */
557 bcount
= ntohs(q
->rdlen
);
559 if (q
== NULL
|| (char *)((u_char
*)n
+ bcount
) > pmax
)
562 return ((u_char
*)n
+ bcount
);
573 while ( count
!= 0 ) {
574 /* Resource Record Name Filed */
575 q
= (NBTNsResource
*)AliasHandleName( (u_char
*)q
, pmax
);
577 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
580 printf("type=%02x, count=%d\n", ntohs(q
->type
), count
);
583 /* Type and Class filed */
584 switch ( ntohs(q
->type
) ) {
586 q
= (NBTNsResource
*)AliasHandleResourceNB(
593 q
= (NBTNsResource
*)AliasHandleResourceA(
600 q
= (NBTNsResource
*)AliasHandleResourceNS(
607 q
= (NBTNsResource
*)AliasHandleResourceNULL(
614 q
= (NBTNsResource
*)AliasHandleResourceNBSTAT(
623 "\nUnknown Type of Resource %0x\n",
632 return ((u_char
*)q
);
635 int AliasHandleUdpNbtNS(
636 struct ip
*pip
, /* IP packet to examine/patch */
637 struct alias_link
*link
,
638 struct in_addr
*alias_address
,
640 struct in_addr
*original_address
,
641 u_short
*original_port
)
649 /* Set up Common Parameter */
650 nbtarg
.oldaddr
= *alias_address
;
651 nbtarg
.oldport
= *alias_port
;
652 nbtarg
.newaddr
= *original_address
;
653 nbtarg
.newport
= *original_port
;
655 /* Calculate data length of UDP packet */
656 uh
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
657 nbtarg
.uh_sum
= &(uh
->uh_sum
);
658 nsh
= (NbtNSHeader
*)((char *)uh
+ (sizeof(struct udphdr
)));
659 p
= (u_char
*)(nsh
+ 1);
660 pmax
= (char *)uh
+ ntohs( uh
->uh_ulen
);
662 if ((char *)(nsh
+ 1) > pmax
)
666 printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
667 ", an=%04x, ns=%04x, ar=%04x, [%d]-->",
668 nsh
->dir
? "Response": "Request",
677 (u_char
*)p
-(u_char
*)nsh
681 /* Question Entries */
682 if (ntohs(nsh
->qdcount
) !=0 ) {
683 p
= AliasHandleQuestion(
691 /* Answer Resource Records */
692 if (ntohs(nsh
->ancount
) !=0 ) {
693 p
= AliasHandleResource(
701 /* Authority Resource Recodrs */
702 if (ntohs(nsh
->nscount
) !=0 ) {
703 p
= AliasHandleResource(
711 /* Additional Resource Recodrs */
712 if (ntohs(nsh
->arcount
) !=0 ) {
713 p
= AliasHandleResource(
722 PrintRcode(nsh
->rcode
);
724 return ((p
== NULL
) ? -1 : 0);