VirtualBox

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

Last change on this file since 21664 was 20958, checked in by vboxsync, 16 years ago

NAT: export of libalias

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