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