The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/libalias/alias_nbt.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 19e12dc78f66ac9cf40bbd6f39e4669b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.