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