VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/slirp/libalias/alias_nbt.c@ 25992

Last change on this file since 25992 was 25992, checked in by vboxsync, 15 years ago

alias_nbt.c: isprint -> RT_C_IS_PRINT; fixes missing prototype warning on darwin.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.4 KB
Line 
1/*-
2 * Written by Atsushi Murai <[email protected]>
3 * Copyright (c) 1998, System Planning and Engineering Co.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 * TODO:
27 * oClean up.
28 * oConsidering for word alignment for other platform.
29 */
30
31#ifndef VBOX
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: src/sys/netinet/libalias/alias_nbt.c,v 1.20.8.1 2009/04/15 03:14:26 kensmith Exp $");
34
35/*
36 alias_nbt.c performs special processing for NetBios over TCP/IP
37 sessions by UDP.
38
39 Initial version: May, 1998 (Atsushi Murai <[email protected]>)
40
41 See HISTORY file for record of revisions.
42*/
43
44/* Includes */
45#ifdef _KERNEL
46#include <sys/param.h>
47#include <sys/systm.h>
48#include <sys/kernel.h>
49#include <sys/module.h>
50#else
51#include <errno.h>
52#include <sys/types.h>
53#include <stdio.h>
54#endif
55
56#include <netinet/in_systm.h>
57#include <netinet/in.h>
58#include <netinet/ip.h>
59#include <netinet/udp.h>
60
61#ifdef _KERNEL
62#include <netinet/libalias/alias_local.h>
63#include <netinet/libalias/alias_mod.h>
64#else
65#include "alias_local.h"
66#include "alias_mod.h"
67#endif
68#else /*VBOX*/
69# include <iprt/ctype.h>
70# include <slirp.h>
71# include "alias_local.h"
72# include "alias_mod.h"
73# define isprint RT_C_IS_PRINT
74#endif /*VBOX*/
75
76#define NETBIOS_NS_PORT_NUMBER 137
77#define NETBIOS_DGM_PORT_NUMBER 138
78
79static int
80AliasHandleUdpNbt(struct libalias *, struct ip *, struct alias_link *,
81 struct in_addr *, u_short);
82
83static int
84AliasHandleUdpNbtNS(struct libalias *, struct ip *, struct alias_link *,
85 struct in_addr *, u_short *, struct in_addr *, u_short *);
86static int
87fingerprint1(struct libalias *la, struct ip *pip, struct alias_data *ah)
88{
89
90 if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
91 ah->aaddr == NULL || ah->aport == NULL)
92 return (-1);
93 if (ntohs(*ah->dport) == NETBIOS_DGM_PORT_NUMBER
94 || ntohs(*ah->sport) == NETBIOS_DGM_PORT_NUMBER)
95 return (0);
96 return (-1);
97}
98
99static int
100protohandler1(struct libalias *la, struct ip *pip, struct alias_data *ah)
101{
102
103 AliasHandleUdpNbt(la, pip, ah->lnk, ah->aaddr, *ah->aport);
104 return (0);
105}
106
107static int
108fingerprint2(struct libalias *la, struct ip *pip, struct alias_data *ah)
109{
110
111 if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
112 ah->aaddr == NULL || ah->aport == NULL)
113 return (-1);
114 if (ntohs(*ah->dport) == NETBIOS_NS_PORT_NUMBER
115 || ntohs(*ah->sport) == NETBIOS_NS_PORT_NUMBER)
116 return (0);
117 return (-1);
118}
119
120static int
121protohandler2in(struct libalias *la, struct ip *pip, struct alias_data *ah)
122{
123
124 AliasHandleUdpNbtNS(la, pip, ah->lnk, ah->aaddr, ah->aport,
125 ah->oaddr, ah->dport);
126 return (0);
127}
128
129static int
130protohandler2out(struct libalias *la, struct ip *pip, struct alias_data *ah)
131{
132
133 AliasHandleUdpNbtNS(la, pip, ah->lnk, &pip->ip_src, ah->sport,
134 ah->aaddr, ah->aport);
135 return (0);
136}
137
138/* Kernel module definition. */
139#ifndef VBOX
140struct proto_handler handlers[] = {
141 {
142 .pri = 130,
143 .dir = IN|OUT,
144 .proto = UDP,
145 .fingerprint = &fingerprint1,
146 .protohandler = &protohandler1
147 },
148 {
149 .pri = 140,
150 .dir = IN,
151 .proto = UDP,
152 .fingerprint = &fingerprint2,
153 .protohandler = &protohandler2in
154 },
155 {
156 .pri = 140,
157 .dir = OUT,
158 .proto = UDP,
159 .fingerprint = &fingerprint2,
160 .protohandler = &protohandler2out
161 },
162 { EOH }
163};
164#else /* !VBOX */
165#define handlers pData->nbt_module
166#endif /*VBOX*/
167
168#ifndef VBOX
169static int
170mod_handler(module_t mod, int type, void *data)
171#else /*!VBOX*/
172static int nbt_alias_handler(PNATState pData, int type);
173
174int
175nbt_alias_load(PNATState pData)
176{
177 return nbt_alias_handler(pData, MOD_LOAD);
178}
179
180int
181nbt_alias_unload(PNATState pData)
182{
183 return nbt_alias_handler(pData, MOD_UNLOAD);
184}
185static int
186nbt_alias_handler(PNATState pData, int type)
187#endif /*VBOX*/
188{
189 int error;
190#ifdef VBOX
191 if (handlers == NULL)
192 handlers = RTMemAllocZ(4 * sizeof(struct proto_handler));
193 handlers[0].pri = 130;
194 handlers[0].dir = IN|OUT;
195 handlers[0].proto = UDP;
196 handlers[0].fingerprint = &fingerprint1;
197 handlers[0].protohandler = &protohandler1;
198
199
200 handlers[1].pri = 140;
201 handlers[1].dir = IN;
202 handlers[1].proto = UDP;
203 handlers[1].fingerprint = &fingerprint2;
204 handlers[1].protohandler = &protohandler2in;
205
206
207 handlers[2].pri = 140;
208 handlers[2].dir = OUT;
209 handlers[2].proto = UDP;
210 handlers[2].fingerprint = &fingerprint2;
211 handlers[2].protohandler = &protohandler2out;
212
213 handlers[3].pri = EOH;
214#endif /*VBOX*/
215
216 switch (type) {
217 case MOD_LOAD:
218 error = 0;
219#ifdef VBOX
220 LibAliasAttachHandlers(pData, handlers);
221#else
222 LibAliasAttachHandlers(handlers);
223#endif
224 break;
225 case MOD_UNLOAD:
226 error = 0;
227#ifdef VBOX
228 LibAliasDetachHandlers(pData, handlers);
229 RTMemFree(handlers);
230 handlers = NULL;
231#else
232 LibAliasDetachHandlers(handlers);
233#endif
234 break;
235 default:
236 error = EINVAL;
237 }
238 return (error);
239}
240
241#ifndef VBOX
242#ifdef _KERNEL
243static
244#endif
245moduledata_t alias_mod = {
246 "alias_nbt", mod_handler, NULL
247};
248#endif /*!VBOX*/
249
250#ifdef _KERNEL
251DECLARE_MODULE(alias_nbt, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
252MODULE_VERSION(alias_nbt, 1);
253MODULE_DEPEND(alias_nbt, libalias, 1, 1, 1);
254#endif
255
256typedef struct {
257 struct in_addr oldaddr;
258 u_short oldport;
259 struct in_addr newaddr;
260 u_short newport;
261 u_short *uh_sum;
262} NBTArguments;
263
264typedef struct {
265 unsigned char type;
266 unsigned char flags;
267 u_short id;
268 struct in_addr source_ip;
269 u_short source_port;
270 u_short len;
271 u_short offset;
272} NbtDataHeader;
273
274#define OpQuery 0
275#define OpUnknown 4
276#define OpRegist 5
277#define OpRelease 6
278#define OpWACK 7
279#define OpRefresh 8
280typedef struct {
281#ifndef VBOX
282 u_short nametrid;
283 u_short dir: 1, opcode:4, nmflags:7, rcode:4;
284#else
285 unsigned nametrid:16;
286 unsigned dir: 1, opcode:4, nmflags:7, rcode:4;
287#endif
288 u_short qdcount;
289 u_short ancount;
290 u_short nscount;
291 u_short arcount;
292} NbtNSHeader;
293AssertCompileSize(NbtNSHeader, 12);
294
295#define FMT_ERR 0x1
296#define SRV_ERR 0x2
297#define IMP_ERR 0x4
298#define RFS_ERR 0x5
299#define ACT_ERR 0x6
300#define CFT_ERR 0x7
301
302
303#ifdef LIBALIAS_DEBUG
304static void
305PrintRcode(u_char rcode)
306{
307
308 switch (rcode) {
309 case FMT_ERR:
310 printf("\nFormat Error.");
311 case SRV_ERR:
312 printf("\nSever failure.");
313 case IMP_ERR:
314 printf("\nUnsupported request error.\n");
315 case RFS_ERR:
316 printf("\nRefused error.\n");
317 case ACT_ERR:
318 printf("\nActive error.\n");
319 case CFT_ERR:
320 printf("\nName in conflict error.\n");
321 default:
322 printf("\n?%c?=%0x\n", '?', rcode);
323
324 }
325}
326
327#endif
328
329
330/* Handling Name field */
331static u_char *
332AliasHandleName(u_char * p, char *pmax)
333{
334
335 u_char *s;
336 u_char c;
337 int compress;
338
339 /* Following length field */
340
341 if (p == NULL || (char *)p >= pmax)
342 return (NULL);
343
344 if (*p & 0xc0) {
345 p = p + 2;
346 if ((char *)p > pmax)
347 return (NULL);
348 return ((u_char *) p);
349 }
350 while ((*p & 0x3f) != 0x00) {
351 s = p + 1;
352 if (*p == 0x20)
353 compress = 1;
354 else
355 compress = 0;
356
357 /* Get next length field */
358 p = (u_char *) (p + (*p & 0x3f) + 1);
359 if ((char *)p > pmax) {
360 p = NULL;
361 break;
362 }
363#ifdef LIBALIAS_DEBUG
364 printf(":");
365#endif
366 while (s < p) {
367 if (compress == 1) {
368 c = (u_char) (((((*s & 0x0f) << 4) | (*(s + 1) & 0x0f)) - 0x11));
369#ifdef LIBALIAS_DEBUG
370 if (isprint(c))
371 printf("%c", c);
372 else
373 printf("<0x%02x>", c);
374#endif
375 s += 2;
376 } else {
377#ifdef LIBALIAS_DEBUG
378 printf("%c", *s);
379#endif
380 s++;
381 }
382 }
383#ifdef LIBALIAS_DEBUG
384 printf(":");
385 fflush(stdout);
386#endif
387 }
388
389 /* Set up to out of Name field */
390 if (p == NULL || (char *)p >= pmax)
391 p = NULL;
392 else
393 p++;
394 return ((u_char *) p);
395}
396
397/*
398 * NetBios Datagram Handler (IP/UDP)
399 */
400#define DGM_DIRECT_UNIQ 0x10
401#define DGM_DIRECT_GROUP 0x11
402#define DGM_BROADCAST 0x12
403#define DGM_ERROR 0x13
404#define DGM_QUERY 0x14
405#define DGM_POSITIVE_RES 0x15
406#define DGM_NEGATIVE_RES 0x16
407
408static int
409AliasHandleUdpNbt(
410 struct libalias *la,
411 struct ip *pip, /* IP packet to examine/patch */
412 struct alias_link *lnk,
413 struct in_addr *alias_address,
414 u_short alias_port
415)
416{
417 struct udphdr *uh;
418 NbtDataHeader *ndh;
419 u_char *p = NULL;
420 char *pmax;
421
422 (void)la;
423 (void)lnk;
424
425 /* Calculate data length of UDP packet */
426 uh = (struct udphdr *)ip_next(pip);
427 pmax = (char *)uh + ntohs(uh->uh_ulen);
428
429 ndh = (NbtDataHeader *)udp_next(uh);
430 if ((char *)(ndh + 1) > pmax)
431 return (-1);
432#ifdef LIBALIAS_DEBUG
433 printf("\nType=%02x,", ndh->type);
434#endif
435 switch (ndh->type) {
436 case DGM_DIRECT_UNIQ:
437 case DGM_DIRECT_GROUP:
438 case DGM_BROADCAST:
439 p = (u_char *) ndh + 14;
440 p = AliasHandleName(p, pmax); /* Source Name */
441 p = AliasHandleName(p, pmax); /* Destination Name */
442 break;
443 case DGM_ERROR:
444 p = (u_char *) ndh + 11;
445 break;
446 case DGM_QUERY:
447 case DGM_POSITIVE_RES:
448 case DGM_NEGATIVE_RES:
449 p = (u_char *) ndh + 10;
450 p = AliasHandleName(p, pmax); /* Destination Name */
451 break;
452 }
453 if (p == NULL || (char *)p > pmax)
454 p = NULL;
455#ifdef LIBALIAS_DEBUG
456 printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
457#endif
458 /* Doing an IP address and Port number Translation */
459 if (uh->uh_sum != 0) {
460 int acc;
461 u_short *sptr;
462
463 acc = ndh->source_port;
464 acc -= alias_port;
465 sptr = (u_short *) & (ndh->source_ip);
466 acc += *sptr++;
467 acc += *sptr;
468 sptr = (u_short *) alias_address;
469 acc -= *sptr++;
470 acc -= *sptr;
471 ADJUST_CHECKSUM(acc, uh->uh_sum);
472 }
473 ndh->source_ip = *alias_address;
474 ndh->source_port = alias_port;
475#ifdef LIBALIAS_DEBUG
476 printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
477 fflush(stdout);
478#endif
479 return ((p == NULL) ? -1 : 0);
480}
481
482/* Question Section */
483#define QS_TYPE_NB 0x0020
484#define QS_TYPE_NBSTAT 0x0021
485#define QS_CLAS_IN 0x0001
486typedef struct {
487 u_short type; /* The type of Request */
488 u_short class; /* The class of Request */
489} NBTNsQuestion;
490
491static u_char *
492AliasHandleQuestion(
493 u_short count,
494 NBTNsQuestion * q,
495 char *pmax,
496 NBTArguments * nbtarg)
497{
498
499 (void)nbtarg;
500
501 while (count != 0) {
502 /* Name Filed */
503 q = (NBTNsQuestion *) AliasHandleName((u_char *) q, pmax);
504
505 if (q == NULL || (char *)(q + 1) > pmax) {
506 q = NULL;
507 break;
508 }
509 /* Type and Class filed */
510 switch (ntohs(q->type)) {
511 case QS_TYPE_NB:
512 case QS_TYPE_NBSTAT:
513 q = q + 1;
514 break;
515 default:
516#ifdef LIBALIAS_DEBUG
517 printf("\nUnknown Type on Question %0x\n", ntohs(q->type));
518#endif
519 break;
520 }
521 count--;
522 }
523
524 /* Set up to out of Question Section */
525 return ((u_char *) q);
526}
527
528/* Resource Record */
529#define RR_TYPE_A 0x0001
530#define RR_TYPE_NS 0x0002
531#define RR_TYPE_NULL 0x000a
532#define RR_TYPE_NB 0x0020
533#define RR_TYPE_NBSTAT 0x0021
534#define RR_CLAS_IN 0x0001
535#define SizeOfNsResource 8
536typedef struct {
537 u_short type;
538 u_short class;
539 unsigned int ttl;
540 u_short rdlen;
541} NBTNsResource;
542
543#define SizeOfNsRNB 6
544typedef struct {
545#ifndef VBOX
546 u_short g: 1 , ont:2, resv:13;
547#else
548 unsigned g: 1 , ont:2, resv:13;
549#endif
550 struct in_addr addr;
551} NBTNsRNB;
552AssertCompileSize(NBTNsRNB, 8);
553
554static u_char *
555AliasHandleResourceNB(
556 NBTNsResource * q,
557 char *pmax,
558 NBTArguments * nbtarg)
559{
560 NBTNsRNB *nb;
561 u_short bcount;
562
563 if (q == NULL || (char *)(q + 1) > pmax)
564 return (NULL);
565 /* Check out a length */
566 bcount = ntohs(q->rdlen);
567
568 /* Forward to Resource NB position */
569 nb = (NBTNsRNB *) ((u_char *) q + SizeOfNsResource);
570
571 /* Processing all in_addr array */
572#ifdef LIBALIAS_DEBUG
573 printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr));
574 printf("->%s, %dbytes] ", inet_ntoa(nbtarg->newaddr), bcount);
575#endif
576 while (nb != NULL && bcount != 0) {
577 if ((char *)(nb + 1) > pmax) {
578 nb = NULL;
579 break;
580 }
581#ifdef LIBALIAS_DEBUG
582 printf("<%s>", inet_ntoa(nb->addr));
583#endif
584 if (!bcmp(&nbtarg->oldaddr, &nb->addr, sizeof(struct in_addr))) {
585 if (*nbtarg->uh_sum != 0) {
586 int acc;
587 u_short *sptr;
588
589 sptr = (u_short *) & (nb->addr);
590 acc = *sptr++;
591 acc += *sptr;
592 sptr = (u_short *) & (nbtarg->newaddr);
593 acc -= *sptr++;
594 acc -= *sptr;
595 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
596 }
597 nb->addr = nbtarg->newaddr;
598#ifdef LIBALIAS_DEBUG
599 printf("O");
600#endif
601 }
602#ifdef LIBALIAS_DEBUG
603 else {
604 printf(".");
605 }
606#endif
607 nb = (NBTNsRNB *) ((u_char *) nb + SizeOfNsRNB);
608 bcount -= SizeOfNsRNB;
609 }
610 if (nb == NULL || (char *)(nb + 1) > pmax) {
611 nb = NULL;
612 }
613 return ((u_char *) nb);
614}
615
616#define SizeOfResourceA 6
617typedef struct {
618 struct in_addr addr;
619} NBTNsResourceA;
620
621static u_char *
622AliasHandleResourceA(
623 NBTNsResource * q,
624 char *pmax,
625 NBTArguments * nbtarg)
626{
627 NBTNsResourceA *a;
628 u_short bcount;
629
630 if (q == NULL || (char *)(q + 1) > pmax)
631 return (NULL);
632
633 /* Forward to Resource A position */
634 a = (NBTNsResourceA *) ((u_char *) q + sizeof(NBTNsResource));
635
636 /* Check out of length */
637 bcount = ntohs(q->rdlen);
638
639 /* Processing all in_addr array */
640#ifdef LIBALIAS_DEBUG
641 printf("Arec [%s", inet_ntoa(nbtarg->oldaddr));
642 printf("->%s]", inet_ntoa(nbtarg->newaddr));
643#endif
644 while (bcount != 0) {
645 if (a == NULL || (char *)(a + 1) > pmax)
646 return (NULL);
647#ifdef LIBALIAS_DEBUG
648 printf("..%s", inet_ntoa(a->addr));
649#endif
650 if (!bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr))) {
651 if (*nbtarg->uh_sum != 0) {
652 int acc;
653 u_short *sptr;
654
655 sptr = (u_short *) & (a->addr); /* Old */
656 acc = *sptr++;
657 acc += *sptr;
658 sptr = (u_short *) & nbtarg->newaddr; /* New */
659 acc -= *sptr++;
660 acc -= *sptr;
661 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
662 }
663 a->addr = nbtarg->newaddr;
664 }
665 a++; /* XXXX */
666 bcount -= SizeOfResourceA;
667 }
668 if (a == NULL || (char *)(a + 1) > pmax)
669 a = NULL;
670 return ((u_char *) a);
671}
672
673typedef struct {
674#ifndef VBOX
675 u_short opcode:4, flags:8, resv:4;
676#else
677 u_short hidden; /* obviously not needed */
678#endif
679} NBTNsResourceNULL;
680AssertCompileSize(NBTNsResourceNULL, 2);
681
682static u_char *
683AliasHandleResourceNULL(
684 NBTNsResource * q,
685 char *pmax,
686 NBTArguments * nbtarg)
687{
688 NBTNsResourceNULL *n;
689 u_short bcount;
690
691 (void)nbtarg;
692
693 if (q == NULL || (char *)(q + 1) > pmax)
694 return (NULL);
695
696 /* Forward to Resource NULL position */
697 n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource));
698
699 /* Check out of length */
700 bcount = ntohs(q->rdlen);
701
702 /* Processing all in_addr array */
703 while (bcount != 0) {
704 if ((char *)(n + 1) > pmax) {
705 n = NULL;
706 break;
707 }
708 n++;
709 bcount -= sizeof(NBTNsResourceNULL);
710 }
711 if ((char *)(n + 1) > pmax)
712 n = NULL;
713
714 return ((u_char *) n);
715}
716
717static u_char *
718AliasHandleResourceNS(
719 NBTNsResource * q,
720 char *pmax,
721 NBTArguments * nbtarg)
722{
723 NBTNsResourceNULL *n;
724 u_short bcount;
725
726 (void)nbtarg;
727
728 if (q == NULL || (char *)(q + 1) > pmax)
729 return (NULL);
730
731 /* Forward to Resource NULL position */
732 n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource));
733
734 /* Check out of length */
735 bcount = ntohs(q->rdlen);
736
737 /* Resource Record Name Filed */
738 q = (NBTNsResource *) AliasHandleName((u_char *) n, pmax); /* XXX */
739
740 if (q == NULL || (char *)((u_char *) n + bcount) > pmax)
741 return (NULL);
742 else
743 return ((u_char *) n + bcount);
744}
745
746typedef struct {
747 u_short numnames;
748} NBTNsResourceNBSTAT;
749
750static u_char *
751AliasHandleResourceNBSTAT(
752 NBTNsResource * q,
753 char *pmax,
754 NBTArguments * nbtarg)
755{
756 NBTNsResourceNBSTAT *n;
757 u_short bcount;
758
759 (void)nbtarg;
760
761 if (q == NULL || (char *)(q + 1) > pmax)
762 return (NULL);
763
764 /* Forward to Resource NBSTAT position */
765 n = (NBTNsResourceNBSTAT *) ((u_char *) q + sizeof(NBTNsResource));
766
767 /* Check out of length */
768 bcount = ntohs(q->rdlen);
769
770 if (q == NULL || (char *)((u_char *) n + bcount) > pmax)
771 return (NULL);
772 else
773 return ((u_char *) n + bcount);
774}
775
776static u_char *
777AliasHandleResource(
778 u_short count,
779 NBTNsResource * q,
780 char *pmax,
781 NBTArguments
782 * nbtarg)
783{
784 while (count != 0) {
785 /* Resource Record Name Filed */
786 q = (NBTNsResource *) AliasHandleName((u_char *) q, pmax);
787
788 if (q == NULL || (char *)(q + 1) > pmax)
789 break;
790#ifdef LIBALIAS_DEBUG
791 printf("type=%02x, count=%d\n", ntohs(q->type), count);
792#endif
793
794 /* Type and Class filed */
795 switch (ntohs(q->type)) {
796 case RR_TYPE_NB:
797 q = (NBTNsResource *) AliasHandleResourceNB(
798 q,
799 pmax,
800 nbtarg
801 );
802 break;
803 case RR_TYPE_A:
804 q = (NBTNsResource *) AliasHandleResourceA(
805 q,
806 pmax,
807 nbtarg
808 );
809 break;
810 case RR_TYPE_NS:
811 q = (NBTNsResource *) AliasHandleResourceNS(
812 q,
813 pmax,
814 nbtarg
815 );
816 break;
817 case RR_TYPE_NULL:
818 q = (NBTNsResource *) AliasHandleResourceNULL(
819 q,
820 pmax,
821 nbtarg
822 );
823 break;
824 case RR_TYPE_NBSTAT:
825 q = (NBTNsResource *) AliasHandleResourceNBSTAT(
826 q,
827 pmax,
828 nbtarg
829 );
830 break;
831 default:
832#ifdef LIBALIAS_DEBUG
833 printf(
834 "\nUnknown Type of Resource %0x\n",
835 ntohs(q->type)
836 );
837 fflush(stdout);
838#endif
839 break;
840 }
841 count--;
842 }
843 return ((u_char *) q);
844}
845
846static int
847AliasHandleUdpNbtNS(
848 struct libalias *la,
849 struct ip *pip, /* IP packet to examine/patch */
850 struct alias_link *lnk,
851 struct in_addr *alias_address,
852 u_short * alias_port,
853 struct in_addr *original_address,
854 u_short * original_port)
855{
856 struct udphdr *uh;
857 NbtNSHeader *nsh;
858 u_char *p;
859 char *pmax;
860 NBTArguments nbtarg;
861
862 (void)la;
863 (void)lnk;
864
865 /* Set up Common Parameter */
866 nbtarg.oldaddr = *alias_address;
867 nbtarg.oldport = *alias_port;
868 nbtarg.newaddr = *original_address;
869 nbtarg.newport = *original_port;
870
871 /* Calculate data length of UDP packet */
872 uh = (struct udphdr *)ip_next(pip);
873 nbtarg.uh_sum = &(uh->uh_sum);
874 nsh = (NbtNSHeader *)udp_next(uh);
875 p = (u_char *) (nsh + 1);
876 pmax = (char *)uh + ntohs(uh->uh_ulen);
877
878 if ((char *)(nsh + 1) > pmax)
879 return (-1);
880
881#ifdef LIBALIAS_DEBUG
882 printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
883 ", an=%04x, ns=%04x, ar=%04x, [%d]-->",
884 nsh->dir ? "Response" : "Request",
885 nsh->nametrid,
886 nsh->opcode,
887 nsh->nmflags,
888 nsh->rcode,
889 ntohs(nsh->qdcount),
890 ntohs(nsh->ancount),
891 ntohs(nsh->nscount),
892 ntohs(nsh->arcount),
893 (u_char *) p - (u_char *) nsh
894 );
895#endif
896
897 /* Question Entries */
898 if (ntohs(nsh->qdcount) != 0) {
899 p = AliasHandleQuestion(
900 ntohs(nsh->qdcount),
901 (NBTNsQuestion *) p,
902 pmax,
903 &nbtarg
904 );
905 }
906 /* Answer Resource Records */
907 if (ntohs(nsh->ancount) != 0) {
908 p = AliasHandleResource(
909 ntohs(nsh->ancount),
910 (NBTNsResource *) p,
911 pmax,
912 &nbtarg
913 );
914 }
915 /* Authority Resource Recodrs */
916 if (ntohs(nsh->nscount) != 0) {
917 p = AliasHandleResource(
918 ntohs(nsh->nscount),
919 (NBTNsResource *) p,
920 pmax,
921 &nbtarg
922 );
923 }
924 /* Additional Resource Recodrs */
925 if (ntohs(nsh->arcount) != 0) {
926 p = AliasHandleResource(
927 ntohs(nsh->arcount),
928 (NBTNsResource *) p,
929 pmax,
930 &nbtarg
931 );
932 }
933#ifdef LIBALIAS_DEBUG
934 PrintRcode(nsh->rcode);
935#endif
936 return ((p == NULL) ? -1 : 0);
937}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette