VirtualBox

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

Last change on this file since 65455 was 63015, checked in by vboxsync, 8 years ago

slirp: warnings

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