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: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 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: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 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. 41*/ 42 43/* Includes */ 44#include <ctype.h> 45#include <stdio.h> 46#include <string.h> 47#include <sys/types.h> 48#include <netinet/in_systm.h> 49#include <netinet/in.h> 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. 41*/ 42 43/* Includes */ 44#include <ctype.h> 45#include <stdio.h> 46#include <string.h> 47#include <sys/types.h> 48#include <netinet/in_systm.h> 49#include <netinet/in.h> 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}
|