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