]>
git.saurik.com Git - apple/network_cmds.git/blob - alias/alias_nbt.c
2 * Written by Atsushi Murai <amurai@spec.co.jp>
4 * Copyright (C) 1998, System Planning and Engineering Co. All rights reserverd.
6 * Redistribution and use in source and binary forms are permitted
7 * provided that the above copyright notice and this paragraph are
8 * duplicated in all such forms and that any documentation,
9 * advertising materials, and other materials related to such
10 * distribution and use acknowledge that the software was developed
11 * by the System Planning and Engineering Co. The name of the
12 * SPEC may not be used to endorse or promote products derived
13 * from this software without specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 * $Id: alias_nbt.c,v 1.1.1.1 2000/01/11 01:48:42 wsanchez Exp $
22 * oConsidering for word alignment for other platform.
25 alias_nbt.c performs special processing for NetBios over TCP/IP
28 Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>)
30 See HISTORY file for record of revisions.
37 #include <sys/types.h>
38 #include <netinet/in_systm.h>
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
41 #include <netinet/ip.h>
42 #include <netinet/udp.h>
43 #include <netinet/tcp.h>
45 #include "alias_local.h"
47 #define ADJUST_CHECKSUM(acc, cksum) { \
52 acc = (acc >> 16) + (acc & 0xffff); \
54 cksum = (u_short) ~acc; \
58 acc = (acc >> 16) + (acc & 0xffff); \
60 cksum = (u_short) acc; \
65 struct in_addr oldaddr
;
67 struct in_addr newaddr
;
76 struct in_addr source_ip
;
90 u_short dir
:1, opcode
:4, nmflags
:7, rcode
:4;
106 static void PrintRcode( u_char rcode
) {
110 printf("\nFormat Error.");
112 printf("\nSever failure.");
114 printf("\nUnsupported request error.\n");
116 printf("\nRefused error.\n");
118 printf("\nActive error.\n");
120 printf("\nName in conflict error.\n");
122 printf("\n???=%0x\n", rcode
);
129 /* Handling Name field */
130 static u_char
*AliasHandleName ( u_char
*p
, char *pmax
) {
136 /* Following length field */
138 if (p
== NULL
|| (char *)p
>= pmax
)
143 if ((char *)p
> pmax
)
145 return ((u_char
*)p
);
147 while ( ( *p
& 0x3f) != 0x00 ) {
154 /* Get next length field */
155 p
= (u_char
*)(p
+ (*p
& 0x3f) + 1);
156 if ((char *)p
> pmax
) {
164 if ( compress
== 1 ) {
165 c
= (u_char
)(((((*s
& 0x0f) << 4) | (*(s
+1) & 0x0f)) - 0x11));
170 printf("<0x%02x>", c
);
186 /* Set up to out of Name field */
187 if (p
== NULL
|| (char *)p
>= pmax
)
191 return ((u_char
*)p
);
195 * NetBios Datagram Handler (IP/UDP)
197 #define DGM_DIRECT_UNIQ 0x10
198 #define DGM_DIRECT_GROUP 0x11
199 #define DGM_BROADCAST 0x12
200 #define DGM_ERROR 0x13
201 #define DGM_QUERY 0x14
202 #define DGM_POSITIVE_RES 0x15
203 #define DGM_NEGATIVE_RES 0x16
205 int AliasHandleUdpNbt(
206 struct ip
*pip
, /* IP packet to examine/patch */
207 struct alias_link
*link
,
208 struct in_addr
*alias_address
,
216 /* Calculate data length of UDP packet */
217 uh
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
218 pmax
= (char *)uh
+ ntohs( uh
->uh_ulen
);
220 ndh
= (NbtDataHeader
*)((char *)uh
+ (sizeof (struct udphdr
)));
221 if ((char *)(ndh
+ 1) > pmax
)
224 printf("\nType=%02x,", ndh
->type
);
226 switch ( ndh
->type
) {
227 case DGM_DIRECT_UNIQ
:
228 case DGM_DIRECT_GROUP
:
230 p
= (u_char
*)ndh
+ 14;
231 p
= AliasHandleName ( p
, pmax
); /* Source Name */
232 p
= AliasHandleName ( p
, pmax
); /* Destination Name */
235 p
= (u_char
*)ndh
+ 11;
238 case DGM_POSITIVE_RES
:
239 case DGM_NEGATIVE_RES
:
240 p
= (u_char
*)ndh
+ 10;
241 p
= AliasHandleName ( p
, pmax
); /* Destination Name */
244 if (p
== NULL
|| (char *)p
> pmax
)
247 printf("%s:%d-->", inet_ntoa(ndh
->source_ip
), ntohs(ndh
->source_port
) );
249 /* Doing a IP address and Port number Translation */
250 if ( uh
->uh_sum
!= 0 ) {
253 acc
= ndh
->source_port
;
255 sptr
= (u_short
*) &(ndh
->source_ip
);
258 sptr
= (u_short
*) alias_address
;
261 ADJUST_CHECKSUM(acc
, uh
->uh_sum
)
263 ndh
->source_ip
= *alias_address
;
264 ndh
->source_port
= alias_port
;
266 printf("%s:%d\n", inet_ntoa(ndh
->source_ip
), ntohs(ndh
->source_port
) );
269 return((p
== NULL
) ? -1 : 0);
271 /* Question Section */
272 #define QS_TYPE_NB 0x0020
273 #define QS_TYPE_NBSTAT 0x0021
274 #define QS_CLAS_IN 0x0001
276 u_short type
; /* The type of Request */
277 u_short
class; /* The class of Request */
285 NBTArguments
*nbtarg
)
288 while ( count
!= 0 ) {
290 q
= (NBTNsQuestion
*)AliasHandleName((u_char
*)q
, pmax
);
292 if (q
== NULL
|| (char *)(q
+ 1) > pmax
) {
297 /* Type and Class filed */
298 switch ( ntohs(q
->type
) ) {
305 printf("\nUnknown Type on Question %0x\n", ntohs(q
->type
) );
312 /* Set up to out of Question Section */
313 return ((u_char
*)q
);
316 /* Resource Record */
317 #define RR_TYPE_A 0x0001
318 #define RR_TYPE_NS 0x0002
319 #define RR_TYPE_NULL 0x000a
320 #define RR_TYPE_NB 0x0020
321 #define RR_TYPE_NBSTAT 0x0021
322 #define RR_CLAS_IN 0x0001
323 #define SizeOfNsResource 8
331 #define SizeOfNsRNB 6
333 u_short g
:1, ont
:2, resv
:13;
338 AliasHandleResourceNB(
341 NBTArguments
*nbtarg
)
346 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
348 /* Check out a length */
349 bcount
= ntohs(q
->rdlen
);
351 /* Forward to Resource NB position */
352 nb
= (NBTNsRNB
*)((u_char
*)q
+ SizeOfNsResource
);
354 /* Processing all in_addr array */
356 printf("NB rec[%s", inet_ntoa(nbtarg
->oldaddr
));
357 printf("->%s, %dbytes] ",inet_ntoa(nbtarg
->newaddr
), bcount
);
359 while ( nb
!= NULL
&& bcount
!= 0 ) {
360 if ((char *)(nb
+ 1) > pmax
) {
365 printf("<%s>", inet_ntoa(nb
->addr
) );
367 if (!bcmp(&nbtarg
->oldaddr
,&nb
->addr
, sizeof(struct in_addr
) ) ) {
368 if ( *nbtarg
->uh_sum
!= 0 ) {
372 sptr
= (u_short
*) &(nb
->addr
);
375 sptr
= (u_short
*) &(nbtarg
->newaddr
);
378 ADJUST_CHECKSUM(acc
, *nbtarg
->uh_sum
)
381 nb
->addr
= nbtarg
->newaddr
;
391 nb
=(NBTNsRNB
*)((u_char
*)nb
+ SizeOfNsRNB
);
392 bcount
-= SizeOfNsRNB
;
394 if (nb
== NULL
|| (char *)(nb
+ 1) > pmax
) {
398 return ((u_char
*)nb
);
401 #define SizeOfResourceA 6
407 AliasHandleResourceA(
410 NBTArguments
*nbtarg
)
415 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
418 /* Forward to Resource A position */
419 a
= (NBTNsResourceA
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
421 /* Check out of length */
422 bcount
= ntohs(q
->rdlen
);
424 /* Processing all in_addr array */
426 printf("Arec [%s", inet_ntoa(nbtarg
->oldaddr
));
427 printf("->%s]",inet_ntoa(nbtarg
->newaddr
));
429 while ( bcount
!= 0 ) {
430 if (a
== NULL
|| (char *)(a
+ 1) > pmax
)
433 printf("..%s", inet_ntoa(a
->addr
) );
435 if ( !bcmp(&nbtarg
->oldaddr
, &a
->addr
, sizeof(struct in_addr
) ) ) {
436 if ( *nbtarg
->uh_sum
!= 0 ) {
440 sptr
= (u_short
*) &(a
->addr
); /* Old */
443 sptr
= (u_short
*) &nbtarg
->newaddr
; /* New */
446 ADJUST_CHECKSUM(acc
, *nbtarg
->uh_sum
)
449 a
->addr
= nbtarg
->newaddr
;
452 bcount
-= SizeOfResourceA
;
454 if (a
== NULL
|| (char *)(a
+ 1) > pmax
)
456 return ((u_char
*)a
);
460 u_short opcode
:4, flags
:8, resv
:4;
464 AliasHandleResourceNULL(
467 NBTArguments
*nbtarg
)
469 NBTNsResourceNULL
*n
;
472 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
475 /* Forward to Resource NULL position */
476 n
= (NBTNsResourceNULL
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
478 /* Check out of length */
479 bcount
= ntohs(q
->rdlen
);
481 /* Processing all in_addr array */
482 while ( bcount
!= 0 ) {
483 if ((char *)(n
+ 1) > pmax
) {
488 bcount
-= sizeof(NBTNsResourceNULL
);
490 if ((char *)(n
+ 1) > pmax
)
493 return ((u_char
*)n
);
497 AliasHandleResourceNS(
500 NBTArguments
*nbtarg
)
502 NBTNsResourceNULL
*n
;
505 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
508 /* Forward to Resource NULL position */
509 n
= (NBTNsResourceNULL
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
511 /* Check out of length */
512 bcount
= ntohs(q
->rdlen
);
514 /* Resource Record Name Filed */
515 q
= (NBTNsResource
*)AliasHandleName( (u_char
*)n
, pmax
); /* XXX */
517 if (q
== NULL
|| (char *)((u_char
*)n
+ bcount
) > pmax
)
520 return ((u_char
*)n
+ bcount
);
525 } NBTNsResourceNBSTAT
;
528 AliasHandleResourceNBSTAT(
531 NBTArguments
*nbtarg
)
533 NBTNsResourceNBSTAT
*n
;
536 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
539 /* Forward to Resource NBSTAT position */
540 n
= (NBTNsResourceNBSTAT
*)( (u_char
*)q
+ sizeof(NBTNsResource
) );
542 /* Check out of length */
543 bcount
= ntohs(q
->rdlen
);
545 if (q
== NULL
|| (char *)((u_char
*)n
+ bcount
) > pmax
)
548 return ((u_char
*)n
+ bcount
);
559 while ( count
!= 0 ) {
560 /* Resource Record Name Filed */
561 q
= (NBTNsResource
*)AliasHandleName( (u_char
*)q
, pmax
);
563 if (q
== NULL
|| (char *)(q
+ 1) > pmax
)
566 printf("type=%02x, count=%d\n", ntohs(q
->type
), count
);
569 /* Type and Class filed */
570 switch ( ntohs(q
->type
) ) {
572 q
= (NBTNsResource
*)AliasHandleResourceNB(
579 q
= (NBTNsResource
*)AliasHandleResourceA(
586 q
= (NBTNsResource
*)AliasHandleResourceNS(
593 q
= (NBTNsResource
*)AliasHandleResourceNULL(
600 q
= (NBTNsResource
*)AliasHandleResourceNBSTAT(
609 "\nUnknown Type of Resource %0x\n",
618 return ((u_char
*)q
);
621 int AliasHandleUdpNbtNS(
622 struct ip
*pip
, /* IP packet to examine/patch */
623 struct alias_link
*link
,
624 struct in_addr
*alias_address
,
626 struct in_addr
*original_address
,
627 u_short
*original_port
)
635 /* Set up Common Parameter */
636 nbtarg
.oldaddr
= *alias_address
;
637 nbtarg
.oldport
= *alias_port
;
638 nbtarg
.newaddr
= *original_address
;
639 nbtarg
.newport
= *original_port
;
641 /* Calculate data length of UDP packet */
642 uh
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
643 nbtarg
.uh_sum
= &(uh
->uh_sum
);
644 nsh
= (NbtNSHeader
*)((char *)uh
+ (sizeof(struct udphdr
)));
645 p
= (u_char
*)(nsh
+ 1);
646 pmax
= (char *)uh
+ ntohs( uh
->uh_ulen
);
648 if ((char *)(nsh
+ 1) > pmax
)
652 printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
653 ", an=%04x, ns=%04x, ar=%04x, [%d]-->",
654 nsh
->dir
? "Response": "Request",
663 (u_char
*)p
-(u_char
*)nsh
667 /* Question Entries */
668 if (ntohs(nsh
->qdcount
) !=0 ) {
669 p
= AliasHandleQuestion(
677 /* Answer Resource Records */
678 if (ntohs(nsh
->ancount
) !=0 ) {
679 p
= AliasHandleResource(
687 /* Authority Resource Recodrs */
688 if (ntohs(nsh
->nscount
) !=0 ) {
689 p
= AliasHandleResource(
697 /* Additional Resource Recodrs */
698 if (ntohs(nsh
->arcount
) !=0 ) {
699 p
= AliasHandleResource(
708 PrintRcode(nsh
->rcode
);
710 return ((p
== NULL
) ? -1 : 0);