Deleted Added
full compact
alias_nbt.c (124621) alias_nbt.c (127094)
1/*-
2 * Written by Atsushi Murai <amurai@spec.co.jp>
3 * Copyright (c) 1998, System Planning and Engineering Co.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 15 unchanged lines hidden (view full) ---

24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 * TODO:
27 * oClean up.
28 * oConsidering for word alignment for other platform.
29 */
30
31#include <sys/cdefs.h>
1/*-
2 * Written by Atsushi Murai <amurai@spec.co.jp>
3 * Copyright (c) 1998, System Planning and Engineering Co.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 15 unchanged lines hidden (view full) ---

24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 * TODO:
27 * oClean up.
28 * oConsidering for word alignment for other platform.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias_nbt.c 124621 2004-01-17 10:52:21Z phk $");
32__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias_nbt.c 127094 2004-03-16 21:30:41Z des $");
33
34/*
35 alias_nbt.c performs special processing for NetBios over TCP/IP
36 sessions by UDP.
37
38 Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>)
39
40 See HISTORY file for record of revisions.

--- 9 unchanged lines hidden (view full) ---

50#include <arpa/inet.h>
51#include <netinet/ip.h>
52#include <netinet/udp.h>
53#include <netinet/tcp.h>
54
55#include "alias_local.h"
56
57typedef struct {
33
34/*
35 alias_nbt.c performs special processing for NetBios over TCP/IP
36 sessions by UDP.
37
38 Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>)
39
40 See HISTORY file for record of revisions.

--- 9 unchanged lines hidden (view full) ---

50#include <arpa/inet.h>
51#include <netinet/ip.h>
52#include <netinet/udp.h>
53#include <netinet/tcp.h>
54
55#include "alias_local.h"
56
57typedef struct {
58 struct in_addr oldaddr;
59 u_short oldport;
60 struct in_addr newaddr;
61 u_short newport;
62 u_short *uh_sum;
63} NBTArguments;
58 struct in_addr oldaddr;
59 u_short oldport;
60 struct in_addr newaddr;
61 u_short newport;
62 u_short *uh_sum;
63} NBTArguments;
64
65typedef struct {
64
65typedef struct {
66 unsigned char type;
67 unsigned char flags;
68 u_short id;
69 struct in_addr source_ip;
70 u_short source_port;
71 u_short len;
72 u_short offset;
73} NbtDataHeader;
66 unsigned char type;
67 unsigned char flags;
68 u_short id;
69 struct in_addr source_ip;
70 u_short source_port;
71 u_short len;
72 u_short offset;
73} NbtDataHeader;
74
75#define OpQuery 0
76#define OpUnknown 4
77#define OpRegist 5
78#define OpRelease 6
79#define OpWACK 7
80#define OpRefresh 8
81typedef struct {
74
75#define OpQuery 0
76#define OpUnknown 4
77#define OpRegist 5
78#define OpRelease 6
79#define OpWACK 7
80#define OpRefresh 8
81typedef struct {
82 u_short nametrid;
83 u_short dir:1, opcode:4, nmflags:7, rcode:4;
84 u_short qdcount;
85 u_short ancount;
86 u_short nscount;
87 u_short arcount;
88} NbtNSHeader;
82 u_short nametrid;
83 u_short dir: 1, opcode:4, nmflags:7, rcode:4;
84 u_short qdcount;
85 u_short ancount;
86 u_short nscount;
87 u_short arcount;
88} NbtNSHeader;
89
90#define FMT_ERR 0x1
91#define SRV_ERR 0x2
92#define IMP_ERR 0x4
93#define RFS_ERR 0x5
94#define ACT_ERR 0x6
95#define CFT_ERR 0x7
96
97
98#ifdef DEBUG
89
90#define FMT_ERR 0x1
91#define SRV_ERR 0x2
92#define IMP_ERR 0x4
93#define RFS_ERR 0x5
94#define ACT_ERR 0x6
95#define CFT_ERR 0x7
96
97
98#ifdef DEBUG
99static void PrintRcode( u_char rcode ) {
99static void
100PrintRcode(u_char rcode)
101{
100
101 switch (rcode) {
102 case FMT_ERR:
102
103 switch (rcode) {
104 case FMT_ERR:
103 printf("\nFormat Error.");
104 case SRV_ERR:
105 printf("\nSever failure.");
106 case IMP_ERR:
107 printf("\nUnsupported request error.\n");
108 case RFS_ERR:
109 printf("\nRefused error.\n");
110 case ACT_ERR:
111 printf("\nActive error.\n");
112 case CFT_ERR:
113 printf("\nName in conflict error.\n");
114 default:
115 printf("\n?%c?=%0x\n", '?', rcode );
105 printf("\nFormat Error.");
106 case SRV_ERR:
107 printf("\nSever failure.");
108 case IMP_ERR:
109 printf("\nUnsupported request error.\n");
110 case RFS_ERR:
111 printf("\nRefused error.\n");
112 case ACT_ERR:
113 printf("\nActive error.\n");
114 case CFT_ERR:
115 printf("\nName in conflict error.\n");
116 default:
117 printf("\n?%c?=%0x\n", '?', rcode);
116
117 }
118}
118
119 }
120}
121
119#endif
120
121
122/* Handling Name field */
122#endif
123
124
125/* Handling Name field */
123static u_char *AliasHandleName ( u_char *p, char *pmax ) {
126static u_char *
127AliasHandleName(u_char * p, char *pmax)
128{
124
125 u_char *s;
126 u_char c;
129
130 u_char *s;
131 u_char c;
127 int compress;
132 int compress;
128
129 /* Following length field */
130
131 if (p == NULL || (char *)p >= pmax)
133
134 /* Following length field */
135
136 if (p == NULL || (char *)p >= pmax)
132 return(NULL);
137 return (NULL);
133
138
134 if (*p & 0xc0 ) {
139 if (*p & 0xc0) {
135 p = p + 2;
136 if ((char *)p > pmax)
140 p = p + 2;
141 if ((char *)p > pmax)
137 return(NULL);
138 return ((u_char *)p);
142 return (NULL);
143 return ((u_char *) p);
139 }
144 }
140 while ( ( *p & 0x3f) != 0x00 ) {
145 while ((*p & 0x3f) != 0x00) {
141 s = p + 1;
146 s = p + 1;
142 if ( *p == 0x20 )
147 if (*p == 0x20)
143 compress = 1;
144 else
145 compress = 0;
146
148 compress = 1;
149 else
150 compress = 0;
151
147 /* Get next length field */
148 p = (u_char *)(p + (*p & 0x3f) + 1);
152 /* Get next length field */
153 p = (u_char *) (p + (*p & 0x3f) + 1);
149 if ((char *)p > pmax) {
150 p = NULL;
151 break;
152 }
153#ifdef DEBUG
154 printf(":");
155#endif
156 while (s < p) {
154 if ((char *)p > pmax) {
155 p = NULL;
156 break;
157 }
158#ifdef DEBUG
159 printf(":");
160#endif
161 while (s < p) {
157 if ( compress == 1 ) {
158 c = (u_char )(((((*s & 0x0f) << 4) | (*(s+1) & 0x0f)) - 0x11));
162 if (compress == 1) {
163 c = (u_char) (((((*s & 0x0f) << 4) | (*(s + 1) & 0x0f)) - 0x11));
159#ifdef DEBUG
164#ifdef DEBUG
160 if (isprint( c ) )
161 printf("%c", c );
165 if (isprint(c))
166 printf("%c", c);
162 else
167 else
163 printf("<0x%02x>", c );
168 printf("<0x%02x>", c);
164#endif
169#endif
165 s +=2;
170 s += 2;
166 } else {
167#ifdef DEBUG
168 printf("%c", *s);
169#endif
170 s++;
171 }
172 }
173#ifdef DEBUG
174 printf(":");
175#endif
176 fflush(stdout);
171 } else {
172#ifdef DEBUG
173 printf("%c", *s);
174#endif
175 s++;
176 }
177 }
178#ifdef DEBUG
179 printf(":");
180#endif
181 fflush(stdout);
177 }
182 }
178
179 /* Set up to out of Name field */
180 if (p == NULL || (char *)p >= pmax)
183
184 /* Set up to out of Name field */
185 if (p == NULL || (char *)p >= pmax)
181 p = NULL;
186 p = NULL;
182 else
187 else
183 p++;
184 return ((u_char *)p);
188 p++;
189 return ((u_char *) p);
185}
186
187/*
188 * NetBios Datagram Handler (IP/UDP)
189 */
190#define DGM_DIRECT_UNIQ 0x10
191#define DGM_DIRECT_GROUP 0x11
192#define DGM_BROADCAST 0x12
193#define DGM_ERROR 0x13
194#define DGM_QUERY 0x14
195#define DGM_POSITIVE_RES 0x15
196#define DGM_NEGATIVE_RES 0x16
197
190}
191
192/*
193 * NetBios Datagram Handler (IP/UDP)
194 */
195#define DGM_DIRECT_UNIQ 0x10
196#define DGM_DIRECT_GROUP 0x11
197#define DGM_BROADCAST 0x12
198#define DGM_ERROR 0x13
199#define DGM_QUERY 0x14
200#define DGM_POSITIVE_RES 0x15
201#define DGM_NEGATIVE_RES 0x16
202
198int AliasHandleUdpNbt(
199 struct libalias *la,
200 struct ip *pip, /* IP packet to examine/patch */
201 struct alias_link *link,
202 struct in_addr *alias_address,
203 u_short alias_port
204) {
205 struct udphdr * uh;
206 NbtDataHeader *ndh;
207 u_char *p = NULL;
208 char *pmax;
203int
204AliasHandleUdpNbt(
205 struct libalias *la,
206 struct ip *pip, /* IP packet to examine/patch */
207 struct alias_link *link,
208 struct in_addr *alias_address,
209 u_short alias_port
210)
211{
212 struct udphdr *uh;
213 NbtDataHeader *ndh;
214 u_char *p = NULL;
215 char *pmax;
209
216
210 /* Calculate data length of UDP packet */
211 uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
212 pmax = (char *)uh + ntohs( uh->uh_ulen );
217 /* Calculate data length of UDP packet */
218 uh = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
219 pmax = (char *)uh + ntohs(uh->uh_ulen);
213
220
214 ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr)));
215 if ((char *)(ndh + 1) > pmax)
216 return(-1);
221 ndh = (NbtDataHeader *) ((char *)uh + (sizeof(struct udphdr)));
222 if ((char *)(ndh + 1) > pmax)
223 return (-1);
217#ifdef DEBUG
224#ifdef DEBUG
218 printf("\nType=%02x,", ndh->type );
225 printf("\nType=%02x,", ndh->type);
219#endif
226#endif
220 switch ( ndh->type ) {
221 case DGM_DIRECT_UNIQ:
222 case DGM_DIRECT_GROUP:
223 case DGM_BROADCAST:
224 p = (u_char *)ndh + 14;
225 p = AliasHandleName ( p, pmax ); /* Source Name */
226 p = AliasHandleName ( p, pmax ); /* Destination Name */
227 break;
228 case DGM_ERROR:
229 p = (u_char *)ndh + 11;
230 break;
231 case DGM_QUERY:
232 case DGM_POSITIVE_RES:
233 case DGM_NEGATIVE_RES:
234 p = (u_char *)ndh + 10;
235 p = AliasHandleName ( p, pmax ); /* Destination Name */
236 break;
227 switch (ndh->type) {
228 case DGM_DIRECT_UNIQ:
229 case DGM_DIRECT_GROUP:
230 case DGM_BROADCAST:
231 p = (u_char *) ndh + 14;
232 p = AliasHandleName(p, pmax); /* Source Name */
233 p = AliasHandleName(p, pmax); /* Destination Name */
234 break;
235 case DGM_ERROR:
236 p = (u_char *) ndh + 11;
237 break;
238 case DGM_QUERY:
239 case DGM_POSITIVE_RES:
240 case DGM_NEGATIVE_RES:
241 p = (u_char *) ndh + 10;
242 p = AliasHandleName(p, pmax); /* Destination Name */
243 break;
237 }
244 }
238 if (p == NULL || (char *)p > pmax)
239 p = NULL;
245 if (p == NULL || (char *)p > pmax)
246 p = NULL;
240#ifdef DEBUG
247#ifdef DEBUG
241 printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) );
248 printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
242#endif
243 /* Doing an IP address and Port number Translation */
249#endif
250 /* Doing an IP address and Port number Translation */
244 if ( uh->uh_sum != 0 ) {
245 int acc;
246 u_short *sptr;
247 acc = ndh->source_port;
251 if (uh->uh_sum != 0) {
252 int acc;
253 u_short *sptr;
254
255 acc = ndh->source_port;
248 acc -= alias_port;
256 acc -= alias_port;
249 sptr = (u_short *) &(ndh->source_ip);
257 sptr = (u_short *) & (ndh->source_ip);
250 acc += *sptr++;
251 acc += *sptr;
252 sptr = (u_short *) alias_address;
253 acc -= *sptr++;
254 acc -= *sptr;
255 ADJUST_CHECKSUM(acc, uh->uh_sum);
256 }
258 acc += *sptr++;
259 acc += *sptr;
260 sptr = (u_short *) alias_address;
261 acc -= *sptr++;
262 acc -= *sptr;
263 ADJUST_CHECKSUM(acc, uh->uh_sum);
264 }
257 ndh->source_ip = *alias_address;
258 ndh->source_port = alias_port;
265 ndh->source_ip = *alias_address;
266 ndh->source_port = alias_port;
259#ifdef DEBUG
267#ifdef DEBUG
260 printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) );
268 printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
261 fflush(stdout);
262#endif
269 fflush(stdout);
270#endif
263 return((p == NULL) ? -1 : 0);
271 return ((p == NULL) ? -1 : 0);
264}
272}
273
265/* Question Section */
266#define QS_TYPE_NB 0x0020
267#define QS_TYPE_NBSTAT 0x0021
268#define QS_CLAS_IN 0x0001
269typedef struct {
274/* Question Section */
275#define QS_TYPE_NB 0x0020
276#define QS_TYPE_NBSTAT 0x0021
277#define QS_CLAS_IN 0x0001
278typedef struct {
270 u_short type; /* The type of Request */
271 u_short class; /* The class of Request */
272} NBTNsQuestion;
279 u_short type; /* The type of Request */
280 u_short class; /* The class of Request */
281} NBTNsQuestion;
273
282
274static u_char *
283static u_char *
275AliasHandleQuestion(
276 u_short count,
284AliasHandleQuestion(
285 u_short count,
277 NBTNsQuestion *q,
286 NBTNsQuestion * q,
278 char *pmax,
287 char *pmax,
279 NBTArguments *nbtarg)
288 NBTArguments * nbtarg)
280{
281
289{
290
282 while ( count != 0 ) {
291 while (count != 0) {
283 /* Name Filed */
292 /* Name Filed */
284 q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax);
293 q = (NBTNsQuestion *) AliasHandleName((u_char *) q, pmax);
285
286 if (q == NULL || (char *)(q + 1) > pmax) {
287 q = NULL;
288 break;
289 }
294
295 if (q == NULL || (char *)(q + 1) > pmax) {
296 q = NULL;
297 break;
298 }
290
291 /* Type and Class filed */
299 /* Type and Class filed */
292 switch ( ntohs(q->type) ) {
293 case QS_TYPE_NB:
294 case QS_TYPE_NBSTAT:
295 q= q+1;
300 switch (ntohs(q->type)) {
301 case QS_TYPE_NB:
302 case QS_TYPE_NBSTAT:
303 q = q + 1;
296 break;
304 break;
297 default:
305 default:
298#ifdef DEBUG
306#ifdef DEBUG
299 printf("\nUnknown Type on Question %0x\n", ntohs(q->type) );
307 printf("\nUnknown Type on Question %0x\n", ntohs(q->type));
300#endif
301 break;
302 }
303 count--;
304 }
305
306 /* Set up to out of Question Section */
308#endif
309 break;
310 }
311 count--;
312 }
313
314 /* Set up to out of Question Section */
307 return ((u_char *)q);
315 return ((u_char *) q);
308}
309
310/* Resource Record */
311#define RR_TYPE_A 0x0001
312#define RR_TYPE_NS 0x0002
313#define RR_TYPE_NULL 0x000a
314#define RR_TYPE_NB 0x0020
315#define RR_TYPE_NBSTAT 0x0021
316#define RR_CLAS_IN 0x0001
317#define SizeOfNsResource 8
318typedef struct {
316}
317
318/* Resource Record */
319#define RR_TYPE_A 0x0001
320#define RR_TYPE_NS 0x0002
321#define RR_TYPE_NULL 0x000a
322#define RR_TYPE_NB 0x0020
323#define RR_TYPE_NBSTAT 0x0021
324#define RR_CLAS_IN 0x0001
325#define SizeOfNsResource 8
326typedef struct {
319 u_short type;
320 u_short class;
321 unsigned int ttl;
322 u_short rdlen;
323} NBTNsResource;
327 u_short type;
328 u_short class;
329 unsigned int ttl;
330 u_short rdlen;
331} NBTNsResource;
324
325#define SizeOfNsRNB 6
326typedef struct {
332
333#define SizeOfNsRNB 6
334typedef struct {
327 u_short g:1, ont:2, resv:13;
328 struct in_addr addr;
329} NBTNsRNB;
335 u_short g: 1 , ont:2, resv:13;
336 struct in_addr addr;
337} NBTNsRNB;
330
338
331static u_char *
339static u_char *
332AliasHandleResourceNB(
340AliasHandleResourceNB(
333 NBTNsResource *q,
341 NBTNsResource * q,
334 char *pmax,
342 char *pmax,
335 NBTArguments *nbtarg)
343 NBTArguments * nbtarg)
336{
344{
337 NBTNsRNB *nb;
345 NBTNsRNB *nb;
338 u_short bcount;
339
340 if (q == NULL || (char *)(q + 1) > pmax)
346 u_short bcount;
347
348 if (q == NULL || (char *)(q + 1) > pmax)
341 return(NULL);
349 return (NULL);
342 /* Check out a length */
343 bcount = ntohs(q->rdlen);
344
345 /* Forward to Resource NB position */
350 /* Check out a length */
351 bcount = ntohs(q->rdlen);
352
353 /* Forward to Resource NB position */
346 nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource);
354 nb = (NBTNsRNB *) ((u_char *) q + SizeOfNsResource);
347
348 /* Processing all in_addr array */
349#ifdef DEBUG
350 printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr));
355
356 /* Processing all in_addr array */
357#ifdef DEBUG
358 printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr));
351 printf("->%s, %dbytes] ",inet_ntoa(nbtarg->newaddr ), bcount);
359 printf("->%s, %dbytes] ", inet_ntoa(nbtarg->newaddr), bcount);
352#endif
360#endif
353 while ( nb != NULL && bcount != 0 ) {
361 while (nb != NULL && bcount != 0) {
354 if ((char *)(nb + 1) > pmax) {
355 nb = NULL;
356 break;
357 }
358#ifdef DEBUG
362 if ((char *)(nb + 1) > pmax) {
363 nb = NULL;
364 break;
365 }
366#ifdef DEBUG
359 printf("<%s>", inet_ntoa(nb->addr) );
367 printf("<%s>", inet_ntoa(nb->addr));
360#endif
368#endif
361 if (!bcmp(&nbtarg->oldaddr,&nb->addr, sizeof(struct in_addr) ) ) {
362 if ( *nbtarg->uh_sum != 0 ) {
363 int acc;
364 u_short *sptr;
369 if (!bcmp(&nbtarg->oldaddr, &nb->addr, sizeof(struct in_addr))) {
370 if (*nbtarg->uh_sum != 0) {
371 int acc;
372 u_short *sptr;
365
373
366 sptr = (u_short *) &(nb->addr);
367 acc = *sptr++;
368 acc += *sptr;
369 sptr = (u_short *) &(nbtarg->newaddr);
370 acc -= *sptr++;
371 acc -= *sptr;
372 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
374 sptr = (u_short *) & (nb->addr);
375 acc = *sptr++;
376 acc += *sptr;
377 sptr = (u_short *) & (nbtarg->newaddr);
378 acc -= *sptr++;
379 acc -= *sptr;
380 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
373 }
381 }
374
375 nb->addr = nbtarg->newaddr;
376#ifdef DEBUG
377 printf("O");
378#endif
379 }
380#ifdef DEBUG
382 nb->addr = nbtarg->newaddr;
383#ifdef DEBUG
384 printf("O");
385#endif
386 }
387#ifdef DEBUG
381 else {
388 else {
382 printf(".");
383 }
384#endif
389 printf(".");
390 }
391#endif
385 nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB);
386 bcount -= SizeOfNsRNB;
392 nb = (NBTNsRNB *) ((u_char *) nb + SizeOfNsRNB);
393 bcount -= SizeOfNsRNB;
387 }
388 if (nb == NULL || (char *)(nb + 1) > pmax) {
389 nb = NULL;
390 }
394 }
395 if (nb == NULL || (char *)(nb + 1) > pmax) {
396 nb = NULL;
397 }
391
392 return ((u_char *)nb);
398 return ((u_char *) nb);
393}
394
395#define SizeOfResourceA 6
396typedef struct {
399}
400
401#define SizeOfResourceA 6
402typedef struct {
397 struct in_addr addr;
398} NBTNsResourceA;
403 struct in_addr addr;
404} NBTNsResourceA;
399
405
400static u_char *
406static u_char *
401AliasHandleResourceA(
407AliasHandleResourceA(
402 NBTNsResource *q,
408 NBTNsResource * q,
403 char *pmax,
409 char *pmax,
404 NBTArguments *nbtarg)
410 NBTArguments * nbtarg)
405{
411{
406 NBTNsResourceA *a;
412 NBTNsResourceA *a;
407 u_short bcount;
408
409 if (q == NULL || (char *)(q + 1) > pmax)
413 u_short bcount;
414
415 if (q == NULL || (char *)(q + 1) > pmax)
410 return(NULL);
416 return (NULL);
411
412 /* Forward to Resource A position */
417
418 /* Forward to Resource A position */
413 a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) );
419 a = (NBTNsResourceA *) ((u_char *) q + sizeof(NBTNsResource));
414
415 /* Check out of length */
416 bcount = ntohs(q->rdlen);
417
418 /* Processing all in_addr array */
419#ifdef DEBUG
420 printf("Arec [%s", inet_ntoa(nbtarg->oldaddr));
420
421 /* Check out of length */
422 bcount = ntohs(q->rdlen);
423
424 /* Processing all in_addr array */
425#ifdef DEBUG
426 printf("Arec [%s", inet_ntoa(nbtarg->oldaddr));
421 printf("->%s]",inet_ntoa(nbtarg->newaddr ));
427 printf("->%s]", inet_ntoa(nbtarg->newaddr));
422#endif
428#endif
423 while ( bcount != 0 ) {
429 while (bcount != 0) {
424 if (a == NULL || (char *)(a + 1) > pmax)
430 if (a == NULL || (char *)(a + 1) > pmax)
425 return(NULL);
431 return (NULL);
426#ifdef DEBUG
432#ifdef DEBUG
427 printf("..%s", inet_ntoa(a->addr) );
433 printf("..%s", inet_ntoa(a->addr));
428#endif
434#endif
429 if ( !bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr) ) ) {
430 if ( *nbtarg->uh_sum != 0 ) {
431 int acc;
432 u_short *sptr;
435 if (!bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr))) {
436 if (*nbtarg->uh_sum != 0) {
437 int acc;
438 u_short *sptr;
433
439
434 sptr = (u_short *) &(a->addr); /* Old */
435 acc = *sptr++;
436 acc += *sptr;
437 sptr = (u_short *) &nbtarg->newaddr; /* New */
438 acc -= *sptr++;
439 acc -= *sptr;
440 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
440 sptr = (u_short *) & (a->addr); /* Old */
441 acc = *sptr++;
442 acc += *sptr;
443 sptr = (u_short *) & nbtarg->newaddr; /* New */
444 acc -= *sptr++;
445 acc -= *sptr;
446 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
441 }
447 }
442
443 a->addr = nbtarg->newaddr;
444 }
448 a->addr = nbtarg->newaddr;
449 }
445 a++; /*XXXX*/
450 a++; /* XXXX */
446 bcount -= SizeOfResourceA;
447 }
448 if (a == NULL || (char *)(a + 1) > pmax)
451 bcount -= SizeOfResourceA;
452 }
453 if (a == NULL || (char *)(a + 1) > pmax)
449 a = NULL;
450 return ((u_char *)a);
454 a = NULL;
455 return ((u_char *) a);
451}
452
453typedef struct {
456}
457
458typedef struct {
454 u_short opcode:4, flags:8, resv:4;
455} NBTNsResourceNULL;
459 u_short opcode:4, flags:8, resv:4;
460} NBTNsResourceNULL;
456
461
457static u_char *
462static u_char *
458AliasHandleResourceNULL(
463AliasHandleResourceNULL(
459 NBTNsResource *q,
464 NBTNsResource * q,
460 char *pmax,
465 char *pmax,
461 NBTArguments *nbtarg)
466 NBTArguments * nbtarg)
462{
467{
463 NBTNsResourceNULL *n;
468 NBTNsResourceNULL *n;
464 u_short bcount;
465
466 if (q == NULL || (char *)(q + 1) > pmax)
469 u_short bcount;
470
471 if (q == NULL || (char *)(q + 1) > pmax)
467 return(NULL);
472 return (NULL);
468
469 /* Forward to Resource NULL position */
473
474 /* Forward to Resource NULL position */
470 n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) );
475 n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource));
471
472 /* Check out of length */
473 bcount = ntohs(q->rdlen);
474
475 /* Processing all in_addr array */
476
477 /* Check out of length */
478 bcount = ntohs(q->rdlen);
479
480 /* Processing all in_addr array */
476 while ( bcount != 0 ) {
481 while (bcount != 0) {
477 if ((char *)(n + 1) > pmax) {
478 n = NULL;
479 break;
480 }
481 n++;
482 bcount -= sizeof(NBTNsResourceNULL);
483 }
484 if ((char *)(n + 1) > pmax)
485 n = NULL;
486
482 if ((char *)(n + 1) > pmax) {
483 n = NULL;
484 break;
485 }
486 n++;
487 bcount -= sizeof(NBTNsResourceNULL);
488 }
489 if ((char *)(n + 1) > pmax)
490 n = NULL;
491
487 return ((u_char *)n);
492 return ((u_char *) n);
488}
489
493}
494
490static u_char *
495static u_char *
491AliasHandleResourceNS(
496AliasHandleResourceNS(
492 NBTNsResource *q,
497 NBTNsResource * q,
493 char *pmax,
498 char *pmax,
494 NBTArguments *nbtarg)
499 NBTArguments * nbtarg)
495{
500{
496 NBTNsResourceNULL *n;
501 NBTNsResourceNULL *n;
497 u_short bcount;
498
499 if (q == NULL || (char *)(q + 1) > pmax)
502 u_short bcount;
503
504 if (q == NULL || (char *)(q + 1) > pmax)
500 return(NULL);
505 return (NULL);
501
502 /* Forward to Resource NULL position */
506
507 /* Forward to Resource NULL position */
503 n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) );
508 n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource));
504
505 /* Check out of length */
506 bcount = ntohs(q->rdlen);
507
508 /* Resource Record Name Filed */
509
510 /* Check out of length */
511 bcount = ntohs(q->rdlen);
512
513 /* Resource Record Name Filed */
509 q = (NBTNsResource *)AliasHandleName( (u_char *)n, pmax ); /* XXX */
514 q = (NBTNsResource *) AliasHandleName((u_char *) n, pmax); /* XXX */
510
515
511 if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
512 return(NULL);
516 if (q == NULL || (char *)((u_char *) n + bcount) > pmax)
517 return (NULL);
513 else
518 else
514 return ((u_char *)n + bcount);
519 return ((u_char *) n + bcount);
515}
516
517typedef struct {
520}
521
522typedef struct {
518 u_short numnames;
519} NBTNsResourceNBSTAT;
523 u_short numnames;
524} NBTNsResourceNBSTAT;
520
525
521static u_char *
526static u_char *
522AliasHandleResourceNBSTAT(
527AliasHandleResourceNBSTAT(
523 NBTNsResource *q,
528 NBTNsResource * q,
524 char *pmax,
529 char *pmax,
525 NBTArguments *nbtarg)
530 NBTArguments * nbtarg)
526{
531{
527 NBTNsResourceNBSTAT *n;
532 NBTNsResourceNBSTAT *n;
528 u_short bcount;
529
530 if (q == NULL || (char *)(q + 1) > pmax)
533 u_short bcount;
534
535 if (q == NULL || (char *)(q + 1) > pmax)
531 return(NULL);
536 return (NULL);
532
533 /* Forward to Resource NBSTAT position */
537
538 /* Forward to Resource NBSTAT position */
534 n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) );
539 n = (NBTNsResourceNBSTAT *) ((u_char *) q + sizeof(NBTNsResource));
535
536 /* Check out of length */
537 bcount = ntohs(q->rdlen);
538
540
541 /* Check out of length */
542 bcount = ntohs(q->rdlen);
543
539 if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
540 return(NULL);
544 if (q == NULL || (char *)((u_char *) n + bcount) > pmax)
545 return (NULL);
541 else
546 else
542 return ((u_char *)n + bcount);
547 return ((u_char *) n + bcount);
543}
544
548}
549
545static u_char *
550static u_char *
546AliasHandleResource(
547 u_short count,
551AliasHandleResource(
552 u_short count,
548 NBTNsResource *q,
553 NBTNsResource * q,
549 char *pmax,
550 NBTArguments
554 char *pmax,
555 NBTArguments
551 *nbtarg)
556 * nbtarg)
552{
557{
553 while ( count != 0 ) {
558 while (count != 0) {
554 /* Resource Record Name Filed */
559 /* Resource Record Name Filed */
555 q = (NBTNsResource *)AliasHandleName( (u_char *)q, pmax );
560 q = (NBTNsResource *) AliasHandleName((u_char *) q, pmax);
556
557 if (q == NULL || (char *)(q + 1) > pmax)
558 break;
559#ifdef DEBUG
561
562 if (q == NULL || (char *)(q + 1) > pmax)
563 break;
564#ifdef DEBUG
560 printf("type=%02x, count=%d\n", ntohs(q->type), count );
565 printf("type=%02x, count=%d\n", ntohs(q->type), count);
561#endif
562
563 /* Type and Class filed */
566#endif
567
568 /* Type and Class filed */
564 switch ( ntohs(q->type) ) {
565 case RR_TYPE_NB:
566 q = (NBTNsResource *)AliasHandleResourceNB(
567 q,
568 pmax,
569 nbtarg
570 );
571 break;
572 case RR_TYPE_A:
573 q = (NBTNsResource *)AliasHandleResourceA(
574 q,
575 pmax,
576 nbtarg
577 );
578 break;
579 case RR_TYPE_NS:
580 q = (NBTNsResource *)AliasHandleResourceNS(
581 q,
582 pmax,
583 nbtarg
584 );
585 break;
586 case RR_TYPE_NULL:
587 q = (NBTNsResource *)AliasHandleResourceNULL(
588 q,
589 pmax,
590 nbtarg
591 );
592 break;
593 case RR_TYPE_NBSTAT:
594 q = (NBTNsResource *)AliasHandleResourceNBSTAT(
595 q,
596 pmax,
597 nbtarg
598 );
599 break;
600 default:
569 switch (ntohs(q->type)) {
570 case RR_TYPE_NB:
571 q = (NBTNsResource *) AliasHandleResourceNB(
572 q,
573 pmax,
574 nbtarg
575 );
576 break;
577 case RR_TYPE_A:
578 q = (NBTNsResource *) AliasHandleResourceA(
579 q,
580 pmax,
581 nbtarg
582 );
583 break;
584 case RR_TYPE_NS:
585 q = (NBTNsResource *) AliasHandleResourceNS(
586 q,
587 pmax,
588 nbtarg
589 );
590 break;
591 case RR_TYPE_NULL:
592 q = (NBTNsResource *) AliasHandleResourceNULL(
593 q,
594 pmax,
595 nbtarg
596 );
597 break;
598 case RR_TYPE_NBSTAT:
599 q = (NBTNsResource *) AliasHandleResourceNBSTAT(
600 q,
601 pmax,
602 nbtarg
603 );
604 break;
605 default:
601#ifdef DEBUG
606#ifdef DEBUG
602 printf(
603 "\nUnknown Type of Resource %0x\n",
604 ntohs(q->type)
605 );
607 printf(
608 "\nUnknown Type of Resource %0x\n",
609 ntohs(q->type)
610 );
606#endif
611#endif
607 break;
612 break;
608 }
609 count--;
610 }
611 fflush(stdout);
613 }
614 count--;
615 }
616 fflush(stdout);
612 return ((u_char *)q);
617 return ((u_char *) q);
613}
614
618}
619
615int AliasHandleUdpNbtNS(
616 struct libalias *la,
617 struct ip *pip, /* IP packet to examine/patch */
618 struct alias_link *link,
619 struct in_addr *alias_address,
620 u_short *alias_port,
621 struct in_addr *original_address,
622 u_short *original_port )
620int
621AliasHandleUdpNbtNS(
622 struct libalias *la,
623 struct ip *pip, /* IP packet to examine/patch */
624 struct alias_link *link,
625 struct in_addr *alias_address,
626 u_short * alias_port,
627 struct in_addr *original_address,
628 u_short * original_port)
623{
629{
624 struct udphdr * uh;
625 NbtNSHeader * nsh;
626 u_char * p;
627 char *pmax;
628 NBTArguments nbtarg;
630 struct udphdr *uh;
631 NbtNSHeader *nsh;
632 u_char *p;
633 char *pmax;
634 NBTArguments nbtarg;
629
630 /* Set up Common Parameter */
635
636 /* Set up Common Parameter */
631 nbtarg.oldaddr = *alias_address;
632 nbtarg.oldport = *alias_port;
633 nbtarg.newaddr = *original_address;
634 nbtarg.newport = *original_port;
637 nbtarg.oldaddr = *alias_address;
638 nbtarg.oldport = *alias_port;
639 nbtarg.newaddr = *original_address;
640 nbtarg.newport = *original_port;
635
641
636 /* Calculate data length of UDP packet */
637 uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
638 nbtarg.uh_sum = &(uh->uh_sum);
639 nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr)));
640 p = (u_char *)(nsh + 1);
641 pmax = (char *)uh + ntohs( uh->uh_ulen );
642 /* Calculate data length of UDP packet */
643 uh = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
644 nbtarg.uh_sum = &(uh->uh_sum);
645 nsh = (NbtNSHeader *) ((char *)uh + (sizeof(struct udphdr)));
646 p = (u_char *) (nsh + 1);
647 pmax = (char *)uh + ntohs(uh->uh_ulen);
642
648
643 if ((char *)(nsh + 1) > pmax)
644 return(-1);
649 if ((char *)(nsh + 1) > pmax)
650 return (-1);
645
646#ifdef DEBUG
651
652#ifdef DEBUG
647 printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
648 ", an=%04x, ns=%04x, ar=%04x, [%d]-->",
649 nsh->dir ? "Response": "Request",
650 nsh->nametrid,
651 nsh->opcode,
652 nsh->nmflags,
653 nsh->rcode,
654 ntohs(nsh->qdcount),
655 ntohs(nsh->ancount),
656 ntohs(nsh->nscount),
657 ntohs(nsh->arcount),
658 (u_char *)p -(u_char *)nsh
659 );
653 printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
654 ", an=%04x, ns=%04x, ar=%04x, [%d]-->",
655 nsh->dir ? "Response" : "Request",
656 nsh->nametrid,
657 nsh->opcode,
658 nsh->nmflags,
659 nsh->rcode,
660 ntohs(nsh->qdcount),
661 ntohs(nsh->ancount),
662 ntohs(nsh->nscount),
663 ntohs(nsh->arcount),
664 (u_char *) p - (u_char *) nsh
665 );
660#endif
661
662 /* Question Entries */
666#endif
667
668 /* Question Entries */
663 if (ntohs(nsh->qdcount) !=0 ) {
664 p = AliasHandleQuestion(
665 ntohs(nsh->qdcount),
666 (NBTNsQuestion *)p,
667 pmax,
668 &nbtarg
669 );
669 if (ntohs(nsh->qdcount) != 0) {
670 p = AliasHandleQuestion(
671 ntohs(nsh->qdcount),
672 (NBTNsQuestion *) p,
673 pmax,
674 &nbtarg
675 );
670 }
676 }
671
672 /* Answer Resource Records */
677 /* Answer Resource Records */
673 if (ntohs(nsh->ancount) !=0 ) {
674 p = AliasHandleResource(
675 ntohs(nsh->ancount),
676 (NBTNsResource *)p,
677 pmax,
678 &nbtarg
679 );
678 if (ntohs(nsh->ancount) != 0) {
679 p = AliasHandleResource(
680 ntohs(nsh->ancount),
681 (NBTNsResource *) p,
682 pmax,
683 &nbtarg
684 );
680 }
685 }
681
682 /* Authority Resource Recodrs */
686 /* Authority Resource Recodrs */
683 if (ntohs(nsh->nscount) !=0 ) {
684 p = AliasHandleResource(
685 ntohs(nsh->nscount),
686 (NBTNsResource *)p,
687 pmax,
688 &nbtarg
689 );
687 if (ntohs(nsh->nscount) != 0) {
688 p = AliasHandleResource(
689 ntohs(nsh->nscount),
690 (NBTNsResource *) p,
691 pmax,
692 &nbtarg
693 );
690 }
694 }
691
692 /* Additional Resource Recodrs */
695 /* Additional Resource Recodrs */
693 if (ntohs(nsh->arcount) !=0 ) {
694 p = AliasHandleResource(
695 ntohs(nsh->arcount),
696 (NBTNsResource *)p,
697 pmax,
698 &nbtarg
699 );
696 if (ntohs(nsh->arcount) != 0) {
697 p = AliasHandleResource(
698 ntohs(nsh->arcount),
699 (NBTNsResource *) p,
700 pmax,
701 &nbtarg
702 );
700 }
703 }
701
702#ifdef DEBUG
704#ifdef DEBUG
703 PrintRcode(nsh->rcode);
705 PrintRcode(nsh->rcode);
704#endif
706#endif
705 return ((p == NULL) ? -1 : 0);
707 return ((p == NULL) ? -1 : 0);
706}
708}