1888b1a7aSBrian Somers /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3fe267a55SPedro F. Giffuni *
4fb9cd36dSAtsushi Murai * Written by Atsushi Murai <amurai@spec.co.jp>
5888b1a7aSBrian Somers * Copyright (c) 1998, System Planning and Engineering Co.
6888b1a7aSBrian Somers * All rights reserved.
7fb9cd36dSAtsushi Murai *
8888b1a7aSBrian Somers * Redistribution and use in source and binary forms, with or without
9888b1a7aSBrian Somers * modification, are permitted provided that the following conditions
10888b1a7aSBrian Somers * are met:
11888b1a7aSBrian Somers * 1. Redistributions of source code must retain the above copyright
12888b1a7aSBrian Somers * notice, this list of conditions and the following disclaimer.
13888b1a7aSBrian Somers * 2. Redistributions in binary form must reproduce the above copyright
14888b1a7aSBrian Somers * notice, this list of conditions and the following disclaimer in the
15888b1a7aSBrian Somers * documentation and/or other materials provided with the distribution.
16fb9cd36dSAtsushi Murai *
17888b1a7aSBrian Somers * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18888b1a7aSBrian Somers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19888b1a7aSBrian Somers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20888b1a7aSBrian Somers * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21888b1a7aSBrian Somers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22888b1a7aSBrian Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23888b1a7aSBrian Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24888b1a7aSBrian Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25888b1a7aSBrian Somers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26888b1a7aSBrian Somers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27888b1a7aSBrian Somers * SUCH DAMAGE.
28fb9cd36dSAtsushi Murai * TODO:
29fb9cd36dSAtsushi Murai * oClean up.
30fb9cd36dSAtsushi Murai * oConsidering for word alignment for other platform.
31fb9cd36dSAtsushi Murai */
32e2505aa6SMatthew Dillon
33e2505aa6SMatthew Dillon #include <sys/cdefs.h>
34fb9cd36dSAtsushi Murai /*
35fb9cd36dSAtsushi Murai alias_nbt.c performs special processing for NetBios over TCP/IP
36fb9cd36dSAtsushi Murai sessions by UDP.
37fb9cd36dSAtsushi Murai
38fb9cd36dSAtsushi Murai Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>)
39fb9cd36dSAtsushi Murai
40fb9cd36dSAtsushi Murai See HISTORY file for record of revisions.
41fb9cd36dSAtsushi Murai */
42fb9cd36dSAtsushi Murai
43fb9cd36dSAtsushi Murai /* Includes */
44c649a2e0SGleb Smirnoff #ifdef _KERNEL
45c649a2e0SGleb Smirnoff #include <sys/param.h>
46be4f3cd0SPaolo Pisati #include <sys/systm.h>
47be4f3cd0SPaolo Pisati #include <sys/kernel.h>
48be4f3cd0SPaolo Pisati #include <sys/module.h>
49c649a2e0SGleb Smirnoff #else
50be4f3cd0SPaolo Pisati #include <errno.h>
51c649a2e0SGleb Smirnoff #include <sys/types.h>
52fb9cd36dSAtsushi Murai #include <stdio.h>
53dd14bc5dSPaolo Pisati #include <strings.h>
54c649a2e0SGleb Smirnoff #endif
55c649a2e0SGleb Smirnoff
56fb9cd36dSAtsushi Murai #include <netinet/in_systm.h>
57fb9cd36dSAtsushi Murai #include <netinet/in.h>
58fb9cd36dSAtsushi Murai #include <netinet/ip.h>
59fb9cd36dSAtsushi Murai #include <netinet/udp.h>
60fb9cd36dSAtsushi Murai
61c649a2e0SGleb Smirnoff #ifdef _KERNEL
62c649a2e0SGleb Smirnoff #include <netinet/libalias/alias_local.h>
63be4f3cd0SPaolo Pisati #include <netinet/libalias/alias_mod.h>
64c649a2e0SGleb Smirnoff #else
65fb9cd36dSAtsushi Murai #include "alias_local.h"
66be4f3cd0SPaolo Pisati #include "alias_mod.h"
67be4f3cd0SPaolo Pisati #endif
68be4f3cd0SPaolo Pisati
69be4f3cd0SPaolo Pisati #define NETBIOS_NS_PORT_NUMBER 137
70be4f3cd0SPaolo Pisati #define NETBIOS_DGM_PORT_NUMBER 138
71be4f3cd0SPaolo Pisati
72be4f3cd0SPaolo Pisati static int
73be4f3cd0SPaolo Pisati AliasHandleUdpNbt(struct libalias *, struct ip *, struct alias_link *,
74be4f3cd0SPaolo Pisati struct in_addr *, u_short);
75be4f3cd0SPaolo Pisati static int
76be4f3cd0SPaolo Pisati AliasHandleUdpNbtNS(struct libalias *, struct ip *, struct alias_link *,
77be4f3cd0SPaolo Pisati struct in_addr *, u_short *, struct in_addr *, u_short *);
78effc8e57SLutz Donnerhacke
79be4f3cd0SPaolo Pisati static int
fingerprint1(struct libalias * la,struct alias_data * ah)8043197d29SPaolo Pisati fingerprint1(struct libalias *la, struct alias_data *ah)
81be4f3cd0SPaolo Pisati {
82be4f3cd0SPaolo Pisati if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
83be4f3cd0SPaolo Pisati ah->aaddr == NULL || ah->aport == NULL)
84be4f3cd0SPaolo Pisati return (-1);
85be4f3cd0SPaolo Pisati if (ntohs(*ah->dport) == NETBIOS_DGM_PORT_NUMBER
86be4f3cd0SPaolo Pisati || ntohs(*ah->sport) == NETBIOS_DGM_PORT_NUMBER)
87be4f3cd0SPaolo Pisati return (0);
88be4f3cd0SPaolo Pisati return (-1);
89be4f3cd0SPaolo Pisati }
90be4f3cd0SPaolo Pisati
91be4f3cd0SPaolo Pisati static int
protohandler1(struct libalias * la,struct ip * pip,struct alias_data * ah)92be4f3cd0SPaolo Pisati protohandler1(struct libalias *la, struct ip *pip, struct alias_data *ah)
93be4f3cd0SPaolo Pisati {
94ea80b0acSPaolo Pisati return (AliasHandleUdpNbt(la, pip, ah->lnk, ah->aaddr, *ah->aport));
95be4f3cd0SPaolo Pisati }
96be4f3cd0SPaolo Pisati
97be4f3cd0SPaolo Pisati static int
fingerprint2(struct libalias * la,struct alias_data * ah)9843197d29SPaolo Pisati fingerprint2(struct libalias *la, struct alias_data *ah)
99be4f3cd0SPaolo Pisati {
100be4f3cd0SPaolo Pisati if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
101be4f3cd0SPaolo Pisati ah->aaddr == NULL || ah->aport == NULL)
102be4f3cd0SPaolo Pisati return (-1);
103be4f3cd0SPaolo Pisati if (ntohs(*ah->dport) == NETBIOS_NS_PORT_NUMBER
104be4f3cd0SPaolo Pisati || ntohs(*ah->sport) == NETBIOS_NS_PORT_NUMBER)
105be4f3cd0SPaolo Pisati return (0);
106be4f3cd0SPaolo Pisati return (-1);
107be4f3cd0SPaolo Pisati }
108be4f3cd0SPaolo Pisati
109be4f3cd0SPaolo Pisati static int
protohandler2in(struct libalias * la,struct ip * pip,struct alias_data * ah)110be4f3cd0SPaolo Pisati protohandler2in(struct libalias *la, struct ip *pip, struct alias_data *ah)
111be4f3cd0SPaolo Pisati {
112be4f3cd0SPaolo Pisati AliasHandleUdpNbtNS(la, pip, ah->lnk, ah->aaddr, ah->aport,
113be4f3cd0SPaolo Pisati ah->oaddr, ah->dport);
114be4f3cd0SPaolo Pisati return (0);
115be4f3cd0SPaolo Pisati }
116be4f3cd0SPaolo Pisati
117be4f3cd0SPaolo Pisati static int
protohandler2out(struct libalias * la,struct ip * pip,struct alias_data * ah)118be4f3cd0SPaolo Pisati protohandler2out(struct libalias *la, struct ip *pip, struct alias_data *ah)
119be4f3cd0SPaolo Pisati {
120ea80b0acSPaolo Pisati return (AliasHandleUdpNbtNS(la, pip, ah->lnk, &pip->ip_src, ah->sport,
121ea80b0acSPaolo Pisati ah->aaddr, ah->aport));
122be4f3cd0SPaolo Pisati }
123be4f3cd0SPaolo Pisati
124be4f3cd0SPaolo Pisati /* Kernel module definition. */
125be4f3cd0SPaolo Pisati struct proto_handler handlers[] = {
126be4f3cd0SPaolo Pisati {
127be4f3cd0SPaolo Pisati .pri = 130,
128be4f3cd0SPaolo Pisati .dir = IN|OUT,
129be4f3cd0SPaolo Pisati .proto = UDP,
130be4f3cd0SPaolo Pisati .fingerprint = &fingerprint1,
131be4f3cd0SPaolo Pisati .protohandler = &protohandler1
132be4f3cd0SPaolo Pisati },
133be4f3cd0SPaolo Pisati {
134be4f3cd0SPaolo Pisati .pri = 140,
135be4f3cd0SPaolo Pisati .dir = IN,
136be4f3cd0SPaolo Pisati .proto = UDP,
137be4f3cd0SPaolo Pisati .fingerprint = &fingerprint2,
138be4f3cd0SPaolo Pisati .protohandler = &protohandler2in
139be4f3cd0SPaolo Pisati },
140be4f3cd0SPaolo Pisati {
141be4f3cd0SPaolo Pisati .pri = 140,
142be4f3cd0SPaolo Pisati .dir = OUT,
143be4f3cd0SPaolo Pisati .proto = UDP,
144be4f3cd0SPaolo Pisati .fingerprint = &fingerprint2,
145be4f3cd0SPaolo Pisati .protohandler = &protohandler2out
146be4f3cd0SPaolo Pisati },
147be4f3cd0SPaolo Pisati { EOH }
148be4f3cd0SPaolo Pisati };
149be4f3cd0SPaolo Pisati
150be4f3cd0SPaolo Pisati static int
mod_handler(module_t mod,int type,void * data)151be4f3cd0SPaolo Pisati mod_handler(module_t mod, int type, void *data)
152be4f3cd0SPaolo Pisati {
153be4f3cd0SPaolo Pisati int error;
154be4f3cd0SPaolo Pisati
155be4f3cd0SPaolo Pisati switch (type) {
156be4f3cd0SPaolo Pisati case MOD_LOAD:
157be4f3cd0SPaolo Pisati error = 0;
158be4f3cd0SPaolo Pisati LibAliasAttachHandlers(handlers);
159be4f3cd0SPaolo Pisati break;
160be4f3cd0SPaolo Pisati case MOD_UNLOAD:
161be4f3cd0SPaolo Pisati error = 0;
162be4f3cd0SPaolo Pisati LibAliasDetachHandlers(handlers);
163be4f3cd0SPaolo Pisati break;
164be4f3cd0SPaolo Pisati default:
165be4f3cd0SPaolo Pisati error = EINVAL;
166be4f3cd0SPaolo Pisati }
167be4f3cd0SPaolo Pisati return (error);
168be4f3cd0SPaolo Pisati }
169be4f3cd0SPaolo Pisati
170be4f3cd0SPaolo Pisati #ifdef _KERNEL
171be4f3cd0SPaolo Pisati static
172be4f3cd0SPaolo Pisati #endif
173be4f3cd0SPaolo Pisati moduledata_t alias_mod = {
174be4f3cd0SPaolo Pisati "alias_nbt", mod_handler, NULL
175be4f3cd0SPaolo Pisati };
176be4f3cd0SPaolo Pisati
177be4f3cd0SPaolo Pisati #ifdef _KERNEL
178be4f3cd0SPaolo Pisati DECLARE_MODULE(alias_nbt, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
179be4f3cd0SPaolo Pisati MODULE_VERSION(alias_nbt, 1);
180be4f3cd0SPaolo Pisati MODULE_DEPEND(alias_nbt, libalias, 1, 1, 1);
181c649a2e0SGleb Smirnoff #endif
182fb9cd36dSAtsushi Murai
183fb9cd36dSAtsushi Murai typedef struct {
184fb9cd36dSAtsushi Murai struct in_addr oldaddr;
185fb9cd36dSAtsushi Murai u_short oldport;
186fb9cd36dSAtsushi Murai struct in_addr newaddr;
187fb9cd36dSAtsushi Murai u_short newport;
188fb9cd36dSAtsushi Murai u_short *uh_sum;
189fb9cd36dSAtsushi Murai } NBTArguments;
190fb9cd36dSAtsushi Murai
191fb9cd36dSAtsushi Murai typedef struct {
192fb9cd36dSAtsushi Murai unsigned char type;
193fb9cd36dSAtsushi Murai unsigned char flags;
194fb9cd36dSAtsushi Murai u_short id;
195fb9cd36dSAtsushi Murai struct in_addr source_ip;
196fb9cd36dSAtsushi Murai u_short source_port;
197fb9cd36dSAtsushi Murai u_short len;
198fb9cd36dSAtsushi Murai u_short offset;
199fb9cd36dSAtsushi Murai } NbtDataHeader;
200fb9cd36dSAtsushi Murai
201fb9cd36dSAtsushi Murai #define OpQuery 0
202fb9cd36dSAtsushi Murai #define OpUnknown 4
203fb9cd36dSAtsushi Murai #define OpRegist 5
204fb9cd36dSAtsushi Murai #define OpRelease 6
205fb9cd36dSAtsushi Murai #define OpWACK 7
206fb9cd36dSAtsushi Murai #define OpRefresh 8
207fb9cd36dSAtsushi Murai typedef struct {
208fb9cd36dSAtsushi Murai u_short nametrid;
209fb9cd36dSAtsushi Murai u_short dir:1, opcode:4, nmflags:7, rcode:4;
210fb9cd36dSAtsushi Murai u_short qdcount;
211fb9cd36dSAtsushi Murai u_short ancount;
212fb9cd36dSAtsushi Murai u_short nscount;
213fb9cd36dSAtsushi Murai u_short arcount;
214fb9cd36dSAtsushi Murai } NbtNSHeader;
215fb9cd36dSAtsushi Murai
216fb9cd36dSAtsushi Murai #define FMT_ERR 0x1
217fb9cd36dSAtsushi Murai #define SRV_ERR 0x2
218fb9cd36dSAtsushi Murai #define IMP_ERR 0x4
219fb9cd36dSAtsushi Murai #define RFS_ERR 0x5
220fb9cd36dSAtsushi Murai #define ACT_ERR 0x6
221fb9cd36dSAtsushi Murai #define CFT_ERR 0x7
222fb9cd36dSAtsushi Murai
2236293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
224f0f93429SDag-Erling Smørgrav static void
PrintRcode(u_char rcode)225f0f93429SDag-Erling Smørgrav PrintRcode(u_char rcode)
226f0f93429SDag-Erling Smørgrav {
227fb9cd36dSAtsushi Murai switch (rcode) {
228fb9cd36dSAtsushi Murai case FMT_ERR:
229fb9cd36dSAtsushi Murai printf("\nFormat Error.");
230fb9cd36dSAtsushi Murai case SRV_ERR:
231fb9cd36dSAtsushi Murai printf("\nSever failure.");
232fb9cd36dSAtsushi Murai case IMP_ERR:
233fb9cd36dSAtsushi Murai printf("\nUnsupported request error.\n");
234fb9cd36dSAtsushi Murai case RFS_ERR:
235fb9cd36dSAtsushi Murai printf("\nRefused error.\n");
236fb9cd36dSAtsushi Murai case ACT_ERR:
237fb9cd36dSAtsushi Murai printf("\nActive error.\n");
238fb9cd36dSAtsushi Murai case CFT_ERR:
239fb9cd36dSAtsushi Murai printf("\nName in conflict error.\n");
240fb9cd36dSAtsushi Murai default:
241c7c5d95dSGarrett Wollman printf("\n?%c?=%0x\n", '?', rcode);
242fb9cd36dSAtsushi Murai }
243fb9cd36dSAtsushi Murai }
244f0f93429SDag-Erling Smørgrav
2454c32f5d2SBrian Somers #endif
246fb9cd36dSAtsushi Murai
247fb9cd36dSAtsushi Murai /* Handling Name field */
248f0f93429SDag-Erling Smørgrav static u_char *
AliasHandleName(u_char * p,char * pmax)249f0f93429SDag-Erling Smørgrav AliasHandleName(u_char *p, char *pmax)
250f0f93429SDag-Erling Smørgrav {
251fb9cd36dSAtsushi Murai u_char *s;
2523f6d3f02SJohn Baldwin #ifdef LIBALIAS_DEBUG
253fb9cd36dSAtsushi Murai u_char c;
2543f6d3f02SJohn Baldwin #endif
255fb9cd36dSAtsushi Murai int compress;
256fb9cd36dSAtsushi Murai
257fb9cd36dSAtsushi Murai /* Following length field */
258374fad8bSMatthew Dillon
259374fad8bSMatthew Dillon if (p == NULL || (char *)p >= pmax)
260374fad8bSMatthew Dillon return (NULL);
261374fad8bSMatthew Dillon
262fb9cd36dSAtsushi Murai if (*p & 0xc0) {
263fb9cd36dSAtsushi Murai p = p + 2;
264374fad8bSMatthew Dillon if ((char *)p > pmax)
265374fad8bSMatthew Dillon return (NULL);
266fb9cd36dSAtsushi Murai return ((u_char *)p);
267fb9cd36dSAtsushi Murai }
268fb9cd36dSAtsushi Murai while ((*p & 0x3f) != 0x00) {
269fb9cd36dSAtsushi Murai s = p + 1;
270fb9cd36dSAtsushi Murai if (*p == 0x20)
271fb9cd36dSAtsushi Murai compress = 1;
272fb9cd36dSAtsushi Murai else
273fb9cd36dSAtsushi Murai compress = 0;
274fb9cd36dSAtsushi Murai
275fb9cd36dSAtsushi Murai /* Get next length field */
276fb9cd36dSAtsushi Murai p = (u_char *)(p + (*p & 0x3f) + 1);
277374fad8bSMatthew Dillon if ((char *)p > pmax) {
278374fad8bSMatthew Dillon p = NULL;
279374fad8bSMatthew Dillon break;
280374fad8bSMatthew Dillon }
2816293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
282fb9cd36dSAtsushi Murai printf(":");
283fb9cd36dSAtsushi Murai #endif
284fb9cd36dSAtsushi Murai while (s < p) {
285fb9cd36dSAtsushi Murai if (compress == 1) {
2866293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
2873f6d3f02SJohn Baldwin c = (u_char) (((((*s & 0x0f) << 4) | (*(s + 1) & 0x0f)) - 0x11));
288fb9cd36dSAtsushi Murai if (isprint(c))
289fb9cd36dSAtsushi Murai printf("%c", c);
290fb9cd36dSAtsushi Murai else
291fb9cd36dSAtsushi Murai printf("<0x%02x>", c);
292fb9cd36dSAtsushi Murai #endif
293fb9cd36dSAtsushi Murai s += 2;
294fb9cd36dSAtsushi Murai } else {
2956293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
296fb9cd36dSAtsushi Murai printf("%c", *s);
297fb9cd36dSAtsushi Murai #endif
298fb9cd36dSAtsushi Murai s++;
299fb9cd36dSAtsushi Murai }
300fb9cd36dSAtsushi Murai }
3016293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
302fb9cd36dSAtsushi Murai printf(":");
303fb9cd36dSAtsushi Murai fflush(stdout);
304ae044057SGleb Smirnoff #endif
305fb9cd36dSAtsushi Murai }
306fb9cd36dSAtsushi Murai
307fb9cd36dSAtsushi Murai /* Set up to out of Name field */
308374fad8bSMatthew Dillon if (p == NULL || (char *)p >= pmax)
309374fad8bSMatthew Dillon p = NULL;
310374fad8bSMatthew Dillon else
311fb9cd36dSAtsushi Murai p++;
312fb9cd36dSAtsushi Murai return ((u_char *)p);
313fb9cd36dSAtsushi Murai }
314fb9cd36dSAtsushi Murai
315fb9cd36dSAtsushi Murai /*
316fb9cd36dSAtsushi Murai * NetBios Datagram Handler (IP/UDP)
317fb9cd36dSAtsushi Murai */
318fb9cd36dSAtsushi Murai #define DGM_DIRECT_UNIQ 0x10
319fb9cd36dSAtsushi Murai #define DGM_DIRECT_GROUP 0x11
320fb9cd36dSAtsushi Murai #define DGM_BROADCAST 0x12
321fb9cd36dSAtsushi Murai #define DGM_ERROR 0x13
322fb9cd36dSAtsushi Murai #define DGM_QUERY 0x14
323fb9cd36dSAtsushi Murai #define DGM_POSITIVE_RES 0x15
324fb9cd36dSAtsushi Murai #define DGM_NEGATIVE_RES 0x16
325fb9cd36dSAtsushi Murai
326be4f3cd0SPaolo Pisati static int
AliasHandleUdpNbt(struct libalias * la,struct ip * pip,struct alias_link * lnk,struct in_addr * alias_address,u_short alias_port)327f0f93429SDag-Erling Smørgrav AliasHandleUdpNbt(
3285e289f9eSPoul-Henning Kamp struct libalias *la,
329fb9cd36dSAtsushi Murai struct ip *pip, /* IP packet to examine/patch */
330ed01a582SDag-Erling Smørgrav struct alias_link *lnk,
331fb9cd36dSAtsushi Murai struct in_addr *alias_address,
332effc8e57SLutz Donnerhacke u_short alias_port)
333f0f93429SDag-Erling Smørgrav {
334fb9cd36dSAtsushi Murai struct udphdr *uh;
335fb9cd36dSAtsushi Murai NbtDataHeader *ndh;
336374fad8bSMatthew Dillon u_char *p = NULL;
337374fad8bSMatthew Dillon char *pmax;
3388144690aSEric van Gyzen #ifdef LIBALIAS_DEBUG
3398144690aSEric van Gyzen char addrbuf[INET_ADDRSTRLEN];
3408144690aSEric van Gyzen #endif
341fb9cd36dSAtsushi Murai
342ed01a582SDag-Erling Smørgrav (void)la;
343ed01a582SDag-Erling Smørgrav (void)lnk;
344ed01a582SDag-Erling Smørgrav
345fb9cd36dSAtsushi Murai /* Calculate data length of UDP packet */
3469fa0fd26SDag-Erling Smørgrav uh = (struct udphdr *)ip_next(pip);
347374fad8bSMatthew Dillon pmax = (char *)uh + ntohs(uh->uh_ulen);
348374fad8bSMatthew Dillon
3499fa0fd26SDag-Erling Smørgrav ndh = (NbtDataHeader *)udp_next(uh);
350374fad8bSMatthew Dillon if ((char *)(ndh + 1) > pmax)
351374fad8bSMatthew Dillon return (-1);
3526293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
353fb9cd36dSAtsushi Murai printf("\nType=%02x,", ndh->type);
354fb9cd36dSAtsushi Murai #endif
355fb9cd36dSAtsushi Murai switch (ndh->type) {
356fb9cd36dSAtsushi Murai case DGM_DIRECT_UNIQ:
357fb9cd36dSAtsushi Murai case DGM_DIRECT_GROUP:
358fb9cd36dSAtsushi Murai case DGM_BROADCAST:
359fb9cd36dSAtsushi Murai p = (u_char *)ndh + 14;
360374fad8bSMatthew Dillon p = AliasHandleName(p, pmax); /* Source Name */
361374fad8bSMatthew Dillon p = AliasHandleName(p, pmax); /* Destination Name */
362fb9cd36dSAtsushi Murai break;
363fb9cd36dSAtsushi Murai case DGM_ERROR:
364fb9cd36dSAtsushi Murai p = (u_char *)ndh + 11;
365fb9cd36dSAtsushi Murai break;
366fb9cd36dSAtsushi Murai case DGM_QUERY:
367fb9cd36dSAtsushi Murai case DGM_POSITIVE_RES:
368fb9cd36dSAtsushi Murai case DGM_NEGATIVE_RES:
369fb9cd36dSAtsushi Murai p = (u_char *)ndh + 10;
370374fad8bSMatthew Dillon p = AliasHandleName(p, pmax); /* Destination Name */
371fb9cd36dSAtsushi Murai break;
372fb9cd36dSAtsushi Murai }
373374fad8bSMatthew Dillon if (p == NULL || (char *)p > pmax)
374374fad8bSMatthew Dillon p = NULL;
3756293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
3768144690aSEric van Gyzen printf("%s:%d-->", inet_ntoa_r(ndh->source_ip, INET_NTOA_BUF(addrbuf)),
3778144690aSEric van Gyzen ntohs(ndh->source_port));
378fb9cd36dSAtsushi Murai #endif
3799d5abbddSJens Schweikhardt /* Doing an IP address and Port number Translation */
380fb9cd36dSAtsushi Murai if (uh->uh_sum != 0) {
381fb9cd36dSAtsushi Murai int acc;
382fb9cd36dSAtsushi Murai u_short *sptr;
383f0f93429SDag-Erling Smørgrav
384fb9cd36dSAtsushi Murai acc = ndh->source_port;
385fb9cd36dSAtsushi Murai acc -= alias_port;
386fb9cd36dSAtsushi Murai sptr = (u_short *)&(ndh->source_ip);
387fb9cd36dSAtsushi Murai acc += *sptr++;
388fb9cd36dSAtsushi Murai acc += *sptr;
389fb9cd36dSAtsushi Murai sptr = (u_short *)alias_address;
390fb9cd36dSAtsushi Murai acc -= *sptr++;
391fb9cd36dSAtsushi Murai acc -= *sptr;
39271593f95SBrian Somers ADJUST_CHECKSUM(acc, uh->uh_sum);
393fb9cd36dSAtsushi Murai }
394fb9cd36dSAtsushi Murai ndh->source_ip = *alias_address;
395fb9cd36dSAtsushi Murai ndh->source_port = alias_port;
3966293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
3978144690aSEric van Gyzen printf("%s:%d\n", inet_ntoa_r(ndh->source_ip, INET_NTOA_BUF(addrbuf)),
3988144690aSEric van Gyzen ntohs(ndh->source_port));
399fb9cd36dSAtsushi Murai fflush(stdout);
400fb9cd36dSAtsushi Murai #endif
401374fad8bSMatthew Dillon return ((p == NULL) ? -1 : 0);
402fb9cd36dSAtsushi Murai }
403f0f93429SDag-Erling Smørgrav
404fb9cd36dSAtsushi Murai /* Question Section */
405fb9cd36dSAtsushi Murai #define QS_TYPE_NB 0x0020
406fb9cd36dSAtsushi Murai #define QS_TYPE_NBSTAT 0x0021
407fb9cd36dSAtsushi Murai #define QS_CLAS_IN 0x0001
408fb9cd36dSAtsushi Murai typedef struct {
409fb9cd36dSAtsushi Murai u_short type; /* The type of Request */
410fb9cd36dSAtsushi Murai u_short class; /* The class of Request */
411fb9cd36dSAtsushi Murai } NBTNsQuestion;
412fb9cd36dSAtsushi Murai
4134c32f5d2SBrian Somers static u_char *
AliasHandleQuestion(u_short count,NBTNsQuestion * q,char * pmax,NBTArguments * nbtarg)414374fad8bSMatthew Dillon AliasHandleQuestion(
415374fad8bSMatthew Dillon u_short count,
416fb9cd36dSAtsushi Murai NBTNsQuestion * q,
417374fad8bSMatthew Dillon char *pmax,
418fb9cd36dSAtsushi Murai NBTArguments * nbtarg)
419fb9cd36dSAtsushi Murai {
420ed01a582SDag-Erling Smørgrav (void)nbtarg;
421ed01a582SDag-Erling Smørgrav
422fb9cd36dSAtsushi Murai while (count != 0) {
423fb9cd36dSAtsushi Murai /* Name Filed */
424374fad8bSMatthew Dillon q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax);
425374fad8bSMatthew Dillon
426374fad8bSMatthew Dillon if (q == NULL || (char *)(q + 1) > pmax) {
427374fad8bSMatthew Dillon q = NULL;
428374fad8bSMatthew Dillon break;
429374fad8bSMatthew Dillon }
430fb9cd36dSAtsushi Murai /* Type and Class filed */
431fb9cd36dSAtsushi Murai switch (ntohs(q->type)) {
432fb9cd36dSAtsushi Murai case QS_TYPE_NB:
433fb9cd36dSAtsushi Murai case QS_TYPE_NBSTAT:
434fb9cd36dSAtsushi Murai q = q + 1;
435fb9cd36dSAtsushi Murai break;
436fb9cd36dSAtsushi Murai default:
4376293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
438fb9cd36dSAtsushi Murai printf("\nUnknown Type on Question %0x\n", ntohs(q->type));
4394c32f5d2SBrian Somers #endif
440fb9cd36dSAtsushi Murai break;
441fb9cd36dSAtsushi Murai }
442fb9cd36dSAtsushi Murai count--;
443fb9cd36dSAtsushi Murai }
444fb9cd36dSAtsushi Murai
445fb9cd36dSAtsushi Murai /* Set up to out of Question Section */
446fb9cd36dSAtsushi Murai return ((u_char *)q);
447fb9cd36dSAtsushi Murai }
448fb9cd36dSAtsushi Murai
449fb9cd36dSAtsushi Murai /* Resource Record */
450fb9cd36dSAtsushi Murai #define RR_TYPE_A 0x0001
451fb9cd36dSAtsushi Murai #define RR_TYPE_NS 0x0002
452fb9cd36dSAtsushi Murai #define RR_TYPE_NULL 0x000a
453fb9cd36dSAtsushi Murai #define RR_TYPE_NB 0x0020
454fb9cd36dSAtsushi Murai #define RR_TYPE_NBSTAT 0x0021
455fb9cd36dSAtsushi Murai #define RR_CLAS_IN 0x0001
456fb9cd36dSAtsushi Murai #define SizeOfNsResource 8
457fb9cd36dSAtsushi Murai typedef struct {
458fb9cd36dSAtsushi Murai u_short type;
459fb9cd36dSAtsushi Murai u_short class;
460fb9cd36dSAtsushi Murai unsigned int ttl;
461fb9cd36dSAtsushi Murai u_short rdlen;
462fb9cd36dSAtsushi Murai } NBTNsResource;
463fb9cd36dSAtsushi Murai
464fb9cd36dSAtsushi Murai #define SizeOfNsRNB 6
465fb9cd36dSAtsushi Murai typedef struct {
466fb9cd36dSAtsushi Murai u_short g:1, ont:2, resv:13;
467fb9cd36dSAtsushi Murai struct in_addr addr;
468fb9cd36dSAtsushi Murai } NBTNsRNB;
469fb9cd36dSAtsushi Murai
4704c32f5d2SBrian Somers static u_char *
AliasHandleResourceNB(NBTNsResource * q,char * pmax,NBTArguments * nbtarg)471374fad8bSMatthew Dillon AliasHandleResourceNB(
472374fad8bSMatthew Dillon NBTNsResource *q,
473374fad8bSMatthew Dillon char *pmax,
474fb9cd36dSAtsushi Murai NBTArguments *nbtarg)
475fb9cd36dSAtsushi Murai {
476fb9cd36dSAtsushi Murai NBTNsRNB *nb;
477fb9cd36dSAtsushi Murai u_short bcount;
4788144690aSEric van Gyzen #ifdef LIBALIAS_DEBUG
4798144690aSEric van Gyzen char oldbuf[INET_ADDRSTRLEN];
4808144690aSEric van Gyzen char newbuf[INET_ADDRSTRLEN];
4818144690aSEric van Gyzen #endif
482fb9cd36dSAtsushi Murai
483374fad8bSMatthew Dillon if (q == NULL || (char *)(q + 1) > pmax)
484374fad8bSMatthew Dillon return (NULL);
485fb9cd36dSAtsushi Murai /* Check out a length */
486fb9cd36dSAtsushi Murai bcount = ntohs(q->rdlen);
487fb9cd36dSAtsushi Murai
488fb9cd36dSAtsushi Murai /* Forward to Resource NB position */
489fb9cd36dSAtsushi Murai nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource);
490fb9cd36dSAtsushi Murai
491fb9cd36dSAtsushi Murai /* Processing all in_addr array */
4926293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
4938144690aSEric van Gyzen printf("NB rec[%s->%s, %dbytes] ",
4948144690aSEric van Gyzen inet_ntoa_r(nbtarg->oldaddr, INET_NTOA_BUF(oldbuf)),
4958144690aSEric van Gyzen inet_ntoa_r(nbtarg->newaddr, INET_NTOA_BUF(newbuf)),
4968144690aSEric van Gyzen bcount);
497fb9cd36dSAtsushi Murai #endif
498374fad8bSMatthew Dillon while (nb != NULL && bcount != 0) {
499374fad8bSMatthew Dillon if ((char *)(nb + 1) > pmax) {
500374fad8bSMatthew Dillon nb = NULL;
501374fad8bSMatthew Dillon break;
502374fad8bSMatthew Dillon }
5036293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
5048144690aSEric van Gyzen printf("<%s>", inet_ntoa_r(nb->addr, INET_NTOA_BUF(newbuf)));
505fb9cd36dSAtsushi Murai #endif
506fb9cd36dSAtsushi Murai if (!bcmp(&nbtarg->oldaddr, &nb->addr, sizeof(struct in_addr))) {
507fb9cd36dSAtsushi Murai if (*nbtarg->uh_sum != 0) {
508fb9cd36dSAtsushi Murai int acc;
509fb9cd36dSAtsushi Murai u_short *sptr;
510fb9cd36dSAtsushi Murai
511fb9cd36dSAtsushi Murai sptr = (u_short *)&(nb->addr);
512fb9cd36dSAtsushi Murai acc = *sptr++;
513fb9cd36dSAtsushi Murai acc += *sptr;
514fb9cd36dSAtsushi Murai sptr = (u_short *)&(nbtarg->newaddr);
515fb9cd36dSAtsushi Murai acc -= *sptr++;
516fb9cd36dSAtsushi Murai acc -= *sptr;
51771593f95SBrian Somers ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
518fb9cd36dSAtsushi Murai }
519fb9cd36dSAtsushi Murai nb->addr = nbtarg->newaddr;
5206293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
521fb9cd36dSAtsushi Murai printf("O");
522fb9cd36dSAtsushi Murai #endif
523fb9cd36dSAtsushi Murai }
5246293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
525fb9cd36dSAtsushi Murai else {
526fb9cd36dSAtsushi Murai printf(".");
527fb9cd36dSAtsushi Murai }
528fb9cd36dSAtsushi Murai #endif
529fb9cd36dSAtsushi Murai nb = (NBTNsRNB *)((u_char *)nb + SizeOfNsRNB);
530fb9cd36dSAtsushi Murai bcount -= SizeOfNsRNB;
531fb9cd36dSAtsushi Murai }
532374fad8bSMatthew Dillon if (nb == NULL || (char *)(nb + 1) > pmax) {
533374fad8bSMatthew Dillon nb = NULL;
534374fad8bSMatthew Dillon }
535fb9cd36dSAtsushi Murai return ((u_char *)nb);
536fb9cd36dSAtsushi Murai }
537fb9cd36dSAtsushi Murai
538fb9cd36dSAtsushi Murai #define SizeOfResourceA 6
539fb9cd36dSAtsushi Murai typedef struct {
540fb9cd36dSAtsushi Murai struct in_addr addr;
541fb9cd36dSAtsushi Murai } NBTNsResourceA;
542fb9cd36dSAtsushi Murai
5434c32f5d2SBrian Somers static u_char *
AliasHandleResourceA(NBTNsResource * q,char * pmax,NBTArguments * nbtarg)544374fad8bSMatthew Dillon AliasHandleResourceA(
545374fad8bSMatthew Dillon NBTNsResource *q,
546374fad8bSMatthew Dillon char *pmax,
547fb9cd36dSAtsushi Murai NBTArguments *nbtarg)
548fb9cd36dSAtsushi Murai {
549fb9cd36dSAtsushi Murai NBTNsResourceA *a;
550fb9cd36dSAtsushi Murai u_short bcount;
5518144690aSEric van Gyzen #ifdef LIBALIAS_DEBUG
5528144690aSEric van Gyzen char oldbuf[INET_ADDRSTRLEN];
5538144690aSEric van Gyzen char newbuf[INET_ADDRSTRLEN];
5548144690aSEric van Gyzen #endif
555fb9cd36dSAtsushi Murai
556374fad8bSMatthew Dillon if (q == NULL || (char *)(q + 1) > pmax)
557374fad8bSMatthew Dillon return (NULL);
558374fad8bSMatthew Dillon
559fb9cd36dSAtsushi Murai /* Forward to Resource A position */
560fb9cd36dSAtsushi Murai a = (NBTNsResourceA *)((u_char *)q + sizeof(NBTNsResource));
561fb9cd36dSAtsushi Murai
562fb9cd36dSAtsushi Murai /* Check out of length */
563fb9cd36dSAtsushi Murai bcount = ntohs(q->rdlen);
564fb9cd36dSAtsushi Murai
565fb9cd36dSAtsushi Murai /* Processing all in_addr array */
5666293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
5678144690aSEric van Gyzen printf("Arec [%s->%s]",
5688144690aSEric van Gyzen inet_ntoa_r(nbtarg->oldaddr, INET_NTOA_BUF(oldbuf)),
5698144690aSEric van Gyzen inet_ntoa_r(nbtarg->newaddr, INET_NTOA_BUF(newbuf)));
570fb9cd36dSAtsushi Murai #endif
571fb9cd36dSAtsushi Murai while (bcount != 0) {
572374fad8bSMatthew Dillon if (a == NULL || (char *)(a + 1) > pmax)
573374fad8bSMatthew Dillon return (NULL);
5746293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
5758144690aSEric van Gyzen printf("..%s", inet_ntoa_r(a->addr, INET_NTOA_BUF(newbuf)));
576fb9cd36dSAtsushi Murai #endif
577fb9cd36dSAtsushi Murai if (!bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr))) {
578fb9cd36dSAtsushi Murai if (*nbtarg->uh_sum != 0) {
579fb9cd36dSAtsushi Murai int acc;
580fb9cd36dSAtsushi Murai u_short *sptr;
581fb9cd36dSAtsushi Murai
582fb9cd36dSAtsushi Murai sptr = (u_short *)&(a->addr); /* Old */
583fb9cd36dSAtsushi Murai acc = *sptr++;
584fb9cd36dSAtsushi Murai acc += *sptr;
585fb9cd36dSAtsushi Murai sptr = (u_short *)&nbtarg->newaddr; /* New */
586fb9cd36dSAtsushi Murai acc -= *sptr++;
587fb9cd36dSAtsushi Murai acc -= *sptr;
58871593f95SBrian Somers ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
589fb9cd36dSAtsushi Murai }
590fb9cd36dSAtsushi Murai a->addr = nbtarg->newaddr;
591fb9cd36dSAtsushi Murai }
592fb9cd36dSAtsushi Murai a++; /* XXXX */
593fb9cd36dSAtsushi Murai bcount -= SizeOfResourceA;
594fb9cd36dSAtsushi Murai }
595374fad8bSMatthew Dillon if (a == NULL || (char *)(a + 1) > pmax)
596374fad8bSMatthew Dillon a = NULL;
597fb9cd36dSAtsushi Murai return ((u_char *)a);
598fb9cd36dSAtsushi Murai }
599fb9cd36dSAtsushi Murai
600fb9cd36dSAtsushi Murai typedef struct {
601fb9cd36dSAtsushi Murai u_short opcode:4, flags:8, resv:4;
602fb9cd36dSAtsushi Murai } NBTNsResourceNULL;
603fb9cd36dSAtsushi Murai
6044c32f5d2SBrian Somers static u_char *
AliasHandleResourceNULL(NBTNsResource * q,char * pmax,NBTArguments * nbtarg)605374fad8bSMatthew Dillon AliasHandleResourceNULL(
606374fad8bSMatthew Dillon NBTNsResource *q,
607374fad8bSMatthew Dillon char *pmax,
608fb9cd36dSAtsushi Murai NBTArguments *nbtarg)
609fb9cd36dSAtsushi Murai {
610fb9cd36dSAtsushi Murai NBTNsResourceNULL *n;
611fb9cd36dSAtsushi Murai u_short bcount;
612fb9cd36dSAtsushi Murai
613ed01a582SDag-Erling Smørgrav (void)nbtarg;
614ed01a582SDag-Erling Smørgrav
615374fad8bSMatthew Dillon if (q == NULL || (char *)(q + 1) > pmax)
616374fad8bSMatthew Dillon return (NULL);
617374fad8bSMatthew Dillon
618fb9cd36dSAtsushi Murai /* Forward to Resource NULL position */
619fb9cd36dSAtsushi Murai n = (NBTNsResourceNULL *)((u_char *)q + sizeof(NBTNsResource));
620fb9cd36dSAtsushi Murai
621fb9cd36dSAtsushi Murai /* Check out of length */
622fb9cd36dSAtsushi Murai bcount = ntohs(q->rdlen);
623fb9cd36dSAtsushi Murai
624fb9cd36dSAtsushi Murai /* Processing all in_addr array */
625fb9cd36dSAtsushi Murai while (bcount != 0) {
626374fad8bSMatthew Dillon if ((char *)(n + 1) > pmax) {
627374fad8bSMatthew Dillon n = NULL;
628374fad8bSMatthew Dillon break;
629374fad8bSMatthew Dillon }
630fb9cd36dSAtsushi Murai n++;
631fb9cd36dSAtsushi Murai bcount -= sizeof(NBTNsResourceNULL);
632fb9cd36dSAtsushi Murai }
633374fad8bSMatthew Dillon if ((char *)(n + 1) > pmax)
634374fad8bSMatthew Dillon n = NULL;
635fb9cd36dSAtsushi Murai
636fb9cd36dSAtsushi Murai return ((u_char *)n);
637fb9cd36dSAtsushi Murai }
638fb9cd36dSAtsushi Murai
6394c32f5d2SBrian Somers static u_char *
AliasHandleResourceNS(NBTNsResource * q,char * pmax,NBTArguments * nbtarg)640374fad8bSMatthew Dillon AliasHandleResourceNS(
641374fad8bSMatthew Dillon NBTNsResource *q,
642374fad8bSMatthew Dillon char *pmax,
643fb9cd36dSAtsushi Murai NBTArguments *nbtarg)
644fb9cd36dSAtsushi Murai {
645fb9cd36dSAtsushi Murai NBTNsResourceNULL *n;
646fb9cd36dSAtsushi Murai u_short bcount;
647fb9cd36dSAtsushi Murai
648ed01a582SDag-Erling Smørgrav (void)nbtarg;
649ed01a582SDag-Erling Smørgrav
650374fad8bSMatthew Dillon if (q == NULL || (char *)(q + 1) > pmax)
651374fad8bSMatthew Dillon return (NULL);
652374fad8bSMatthew Dillon
653fb9cd36dSAtsushi Murai /* Forward to Resource NULL position */
654fb9cd36dSAtsushi Murai n = (NBTNsResourceNULL *)((u_char *)q + sizeof(NBTNsResource));
655fb9cd36dSAtsushi Murai
656fb9cd36dSAtsushi Murai /* Check out of length */
657fb9cd36dSAtsushi Murai bcount = ntohs(q->rdlen);
658fb9cd36dSAtsushi Murai
659fb9cd36dSAtsushi Murai /* Resource Record Name Filed */
660374fad8bSMatthew Dillon q = (NBTNsResource *)AliasHandleName((u_char *)n, pmax); /* XXX */
661fb9cd36dSAtsushi Murai
662374fad8bSMatthew Dillon if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
663374fad8bSMatthew Dillon return (NULL);
664374fad8bSMatthew Dillon else
665fb9cd36dSAtsushi Murai return ((u_char *)n + bcount);
666fb9cd36dSAtsushi Murai }
667fb9cd36dSAtsushi Murai
668fb9cd36dSAtsushi Murai typedef struct {
669fb9cd36dSAtsushi Murai u_short numnames;
670fb9cd36dSAtsushi Murai } NBTNsResourceNBSTAT;
671fb9cd36dSAtsushi Murai
6724c32f5d2SBrian Somers static u_char *
AliasHandleResourceNBSTAT(NBTNsResource * q,char * pmax,NBTArguments * nbtarg)673374fad8bSMatthew Dillon AliasHandleResourceNBSTAT(
674374fad8bSMatthew Dillon NBTNsResource *q,
675374fad8bSMatthew Dillon char *pmax,
676fb9cd36dSAtsushi Murai NBTArguments *nbtarg)
677fb9cd36dSAtsushi Murai {
678fb9cd36dSAtsushi Murai NBTNsResourceNBSTAT *n;
679fb9cd36dSAtsushi Murai u_short bcount;
680fb9cd36dSAtsushi Murai
681ed01a582SDag-Erling Smørgrav (void)nbtarg;
682ed01a582SDag-Erling Smørgrav
683374fad8bSMatthew Dillon if (q == NULL || (char *)(q + 1) > pmax)
684374fad8bSMatthew Dillon return (NULL);
685374fad8bSMatthew Dillon
686fb9cd36dSAtsushi Murai /* Forward to Resource NBSTAT position */
687fb9cd36dSAtsushi Murai n = (NBTNsResourceNBSTAT *)((u_char *)q + sizeof(NBTNsResource));
688fb9cd36dSAtsushi Murai
689fb9cd36dSAtsushi Murai /* Check out of length */
690fb9cd36dSAtsushi Murai bcount = ntohs(q->rdlen);
691fb9cd36dSAtsushi Murai
692374fad8bSMatthew Dillon if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
693374fad8bSMatthew Dillon return (NULL);
694374fad8bSMatthew Dillon else
695fb9cd36dSAtsushi Murai return ((u_char *)n + bcount);
696fb9cd36dSAtsushi Murai }
697fb9cd36dSAtsushi Murai
6984c32f5d2SBrian Somers static u_char *
AliasHandleResource(u_short count,NBTNsResource * q,char * pmax,NBTArguments * nbtarg)699374fad8bSMatthew Dillon AliasHandleResource(
700374fad8bSMatthew Dillon u_short count,
701fb9cd36dSAtsushi Murai NBTNsResource *q,
702374fad8bSMatthew Dillon char *pmax,
703effc8e57SLutz Donnerhacke NBTArguments *nbtarg)
704fb9cd36dSAtsushi Murai {
705fb9cd36dSAtsushi Murai while (count != 0) {
706fb9cd36dSAtsushi Murai /* Resource Record Name Filed */
707374fad8bSMatthew Dillon q = (NBTNsResource *)AliasHandleName((u_char *)q, pmax);
708374fad8bSMatthew Dillon
709374fad8bSMatthew Dillon if (q == NULL || (char *)(q + 1) > pmax)
710374fad8bSMatthew Dillon break;
7116293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
712fb9cd36dSAtsushi Murai printf("type=%02x, count=%d\n", ntohs(q->type), count);
713fb9cd36dSAtsushi Murai #endif
714fb9cd36dSAtsushi Murai
715fb9cd36dSAtsushi Murai /* Type and Class filed */
716fb9cd36dSAtsushi Murai switch (ntohs(q->type)) {
717fb9cd36dSAtsushi Murai case RR_TYPE_NB:
718374fad8bSMatthew Dillon q = (NBTNsResource *)AliasHandleResourceNB(
719effc8e57SLutz Donnerhacke q, pmax, nbtarg);
720fb9cd36dSAtsushi Murai break;
721fb9cd36dSAtsushi Murai case RR_TYPE_A:
722374fad8bSMatthew Dillon q = (NBTNsResource *)AliasHandleResourceA(
723effc8e57SLutz Donnerhacke q, pmax, nbtarg);
724fb9cd36dSAtsushi Murai break;
725fb9cd36dSAtsushi Murai case RR_TYPE_NS:
726374fad8bSMatthew Dillon q = (NBTNsResource *)AliasHandleResourceNS(
727effc8e57SLutz Donnerhacke q, pmax, nbtarg);
728fb9cd36dSAtsushi Murai break;
729fb9cd36dSAtsushi Murai case RR_TYPE_NULL:
730374fad8bSMatthew Dillon q = (NBTNsResource *)AliasHandleResourceNULL(
731effc8e57SLutz Donnerhacke q, pmax, nbtarg);
732fb9cd36dSAtsushi Murai break;
733fb9cd36dSAtsushi Murai case RR_TYPE_NBSTAT:
734374fad8bSMatthew Dillon q = (NBTNsResource *)AliasHandleResourceNBSTAT(
735effc8e57SLutz Donnerhacke q, pmax, nbtarg);
736fb9cd36dSAtsushi Murai break;
737374fad8bSMatthew Dillon default:
7386293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
739374fad8bSMatthew Dillon printf(
740374fad8bSMatthew Dillon "\nUnknown Type of Resource %0x\n",
741374fad8bSMatthew Dillon ntohs(q->type)
742374fad8bSMatthew Dillon );
743ae044057SGleb Smirnoff fflush(stdout);
7444c32f5d2SBrian Somers #endif
745fb9cd36dSAtsushi Murai break;
746fb9cd36dSAtsushi Murai }
747fb9cd36dSAtsushi Murai count--;
748fb9cd36dSAtsushi Murai }
749fb9cd36dSAtsushi Murai return ((u_char *)q);
750fb9cd36dSAtsushi Murai }
751fb9cd36dSAtsushi Murai
752be4f3cd0SPaolo Pisati 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)753f0f93429SDag-Erling Smørgrav AliasHandleUdpNbtNS(
7545e289f9eSPoul-Henning Kamp struct libalias *la,
755fb9cd36dSAtsushi Murai struct ip *pip, /* IP packet to examine/patch */
756ed01a582SDag-Erling Smørgrav struct alias_link *lnk,
757fb9cd36dSAtsushi Murai struct in_addr *alias_address,
758fb9cd36dSAtsushi Murai u_short *alias_port,
759fb9cd36dSAtsushi Murai struct in_addr *original_address,
760fb9cd36dSAtsushi Murai u_short *original_port)
761fb9cd36dSAtsushi Murai {
762fb9cd36dSAtsushi Murai struct udphdr *uh;
763fb9cd36dSAtsushi Murai NbtNSHeader *nsh;
764fb9cd36dSAtsushi Murai u_char *p;
765374fad8bSMatthew Dillon char *pmax;
766fb9cd36dSAtsushi Murai NBTArguments nbtarg;
767fb9cd36dSAtsushi Murai
768ed01a582SDag-Erling Smørgrav (void)la;
769ed01a582SDag-Erling Smørgrav (void)lnk;
770ed01a582SDag-Erling Smørgrav
771fb9cd36dSAtsushi Murai /* Set up Common Parameter */
772fb9cd36dSAtsushi Murai nbtarg.oldaddr = *alias_address;
773fb9cd36dSAtsushi Murai nbtarg.oldport = *alias_port;
774fb9cd36dSAtsushi Murai nbtarg.newaddr = *original_address;
775fb9cd36dSAtsushi Murai nbtarg.newport = *original_port;
776fb9cd36dSAtsushi Murai
777fb9cd36dSAtsushi Murai /* Calculate data length of UDP packet */
7789fa0fd26SDag-Erling Smørgrav uh = (struct udphdr *)ip_next(pip);
779fb9cd36dSAtsushi Murai nbtarg.uh_sum = &(uh->uh_sum);
7809fa0fd26SDag-Erling Smørgrav nsh = (NbtNSHeader *)udp_next(uh);
781fb9cd36dSAtsushi Murai p = (u_char *)(nsh + 1);
782374fad8bSMatthew Dillon pmax = (char *)uh + ntohs(uh->uh_ulen);
783374fad8bSMatthew Dillon
784374fad8bSMatthew Dillon if ((char *)(nsh + 1) > pmax)
785374fad8bSMatthew Dillon return (-1);
786fb9cd36dSAtsushi Murai
7876293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
788374fad8bSMatthew Dillon printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
789374fad8bSMatthew Dillon ", an=%04x, ns=%04x, ar=%04x, [%d]-->",
790fb9cd36dSAtsushi Murai nsh->dir ? "Response" : "Request",
791fb9cd36dSAtsushi Murai nsh->nametrid,
792fb9cd36dSAtsushi Murai nsh->opcode,
793fb9cd36dSAtsushi Murai nsh->nmflags,
794fb9cd36dSAtsushi Murai nsh->rcode,
795fb9cd36dSAtsushi Murai ntohs(nsh->qdcount),
796fb9cd36dSAtsushi Murai ntohs(nsh->ancount),
797fb9cd36dSAtsushi Murai ntohs(nsh->nscount),
798fb9cd36dSAtsushi Murai ntohs(nsh->arcount),
799374fad8bSMatthew Dillon (u_char *)p - (u_char *)nsh
800374fad8bSMatthew Dillon );
801fb9cd36dSAtsushi Murai #endif
802fb9cd36dSAtsushi Murai
803fb9cd36dSAtsushi Murai /* Question Entries */
804fb9cd36dSAtsushi Murai if (ntohs(nsh->qdcount) != 0) {
805374fad8bSMatthew Dillon p = AliasHandleQuestion(
806374fad8bSMatthew Dillon ntohs(nsh->qdcount),
807374fad8bSMatthew Dillon (NBTNsQuestion *)p,
808374fad8bSMatthew Dillon pmax,
809374fad8bSMatthew Dillon &nbtarg
810374fad8bSMatthew Dillon );
811fb9cd36dSAtsushi Murai }
812fb9cd36dSAtsushi Murai /* Answer Resource Records */
813fb9cd36dSAtsushi Murai if (ntohs(nsh->ancount) != 0) {
814374fad8bSMatthew Dillon p = AliasHandleResource(
815374fad8bSMatthew Dillon ntohs(nsh->ancount),
816374fad8bSMatthew Dillon (NBTNsResource *)p,
817374fad8bSMatthew Dillon pmax,
818374fad8bSMatthew Dillon &nbtarg
819374fad8bSMatthew Dillon );
820fb9cd36dSAtsushi Murai }
821fb9cd36dSAtsushi Murai /* Authority Resource Recodrs */
822fb9cd36dSAtsushi Murai if (ntohs(nsh->nscount) != 0) {
823374fad8bSMatthew Dillon p = AliasHandleResource(
824374fad8bSMatthew Dillon ntohs(nsh->nscount),
825374fad8bSMatthew Dillon (NBTNsResource *)p,
826374fad8bSMatthew Dillon pmax,
827374fad8bSMatthew Dillon &nbtarg
828374fad8bSMatthew Dillon );
829fb9cd36dSAtsushi Murai }
830fb9cd36dSAtsushi Murai /* Additional Resource Recodrs */
831fb9cd36dSAtsushi Murai if (ntohs(nsh->arcount) != 0) {
832374fad8bSMatthew Dillon p = AliasHandleResource(
833374fad8bSMatthew Dillon ntohs(nsh->arcount),
834374fad8bSMatthew Dillon (NBTNsResource *)p,
835374fad8bSMatthew Dillon pmax,
836374fad8bSMatthew Dillon &nbtarg
837374fad8bSMatthew Dillon );
838fb9cd36dSAtsushi Murai }
8396293e003SGleb Smirnoff #ifdef LIBALIAS_DEBUG
840fb9cd36dSAtsushi Murai PrintRcode(nsh->rcode);
841fb9cd36dSAtsushi Murai #endif
842374fad8bSMatthew Dillon return ((p == NULL) ? -1 : 0);
843fb9cd36dSAtsushi Murai }
844