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/ip_rcmd_pxy.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 /*      $NetBSD: ip_rcmd_pxy.c,v 1.10.2.1 2004/08/13 03:55:58 jmc Exp $ */
    2 
    3 #include <sys/cdefs.h>
    4 __KERNEL_RCSID(1, "$NetBSD: ip_rcmd_pxy.c,v 1.10.2.1 2004/08/13 03:55:58 jmc Exp $");
    5 
    6 /*
    7  * Copyright (C) 1998-2003 by Darren Reed
    8  *
    9  * See the IPFILTER.LICENCE file for details on licencing.
   10  *
   11  * Id: ip_rcmd_pxy.c,v 1.41.2.2 2004/05/24 14:01:49 darrenr Exp
   12  *
   13  * Simple RCMD transparent proxy for in-kernel use.  For use with the NAT
   14  * code.
   15  */
   16 
   17 #define IPF_RCMD_PROXY
   18 
   19 
   20 int ippr_rcmd_init __P((void));
   21 void ippr_rcmd_fini __P((void));
   22 int ippr_rcmd_new __P((fr_info_t *, ap_session_t *, nat_t *));
   23 int ippr_rcmd_out __P((fr_info_t *, ap_session_t *, nat_t *));
   24 int ippr_rcmd_in __P((fr_info_t *, ap_session_t *, nat_t *));
   25 u_short ipf_rcmd_atoi __P((char *));
   26 int ippr_rcmd_portmsg __P((fr_info_t *, ap_session_t *, nat_t *));
   27 
   28 static  frentry_t       rcmdfr;
   29 
   30 int     rcmd_proxy_init = 0;
   31 
   32 
   33 /*
   34  * RCMD application proxy initialization.
   35  */
   36 int ippr_rcmd_init()
   37 {
   38         bzero((char *)&rcmdfr, sizeof(rcmdfr));
   39         rcmdfr.fr_ref = 1;
   40         rcmdfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
   41         MUTEX_INIT(&rcmdfr.fr_lock, "RCMD proxy rule lock");
   42         rcmd_proxy_init = 1;
   43 
   44         return 0;
   45 }
   46 
   47 
   48 void ippr_rcmd_fini()
   49 {
   50         if (rcmd_proxy_init == 1) {
   51                 MUTEX_DESTROY(&rcmdfr.fr_lock);
   52                 rcmd_proxy_init = 0;
   53         }
   54 }
   55 
   56 
   57 /*
   58  * Setup for a new RCMD proxy.
   59  */
   60 int ippr_rcmd_new(fin, aps, nat)
   61 fr_info_t *fin;
   62 ap_session_t *aps;
   63 nat_t *nat;
   64 {
   65         tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
   66 
   67         fin = fin;      /* LINT */
   68         nat = nat;      /* LINT */
   69 
   70         aps->aps_psiz = sizeof(u_32_t);
   71         KMALLOCS(aps->aps_data, u_32_t *, sizeof(u_32_t));
   72         if (aps->aps_data == NULL) {
   73 #ifdef IP_RCMD_PROXY_DEBUG
   74                 printf("ippr_rcmd_new:KMALLOCS(%d) failed\n", sizeof(u_32_t));
   75 #endif
   76                 return -1;
   77         }
   78         *(u_32_t *)aps->aps_data = 0;
   79         aps->aps_sport = tcp->th_sport;
   80         aps->aps_dport = tcp->th_dport;
   81         return 0;
   82 }
   83 
   84 
   85 /*
   86  * ipf_rcmd_atoi - implement a simple version of atoi
   87  */
   88 u_short ipf_rcmd_atoi(ptr)
   89 char *ptr;
   90 {
   91         register char *s = ptr, c;
   92         register u_short i = 0;
   93 
   94         while (((c = *s++) != '\0') && isdigit(c)) {
   95                 i *= 10;
   96                 i += c - '';
   97         }
   98         return i;
   99 }
  100 
  101 
  102 int ippr_rcmd_portmsg(fin, aps, nat)
  103 fr_info_t *fin;
  104 ap_session_t *aps;
  105 nat_t *nat;
  106 {
  107         tcphdr_t *tcp, tcph, *tcp2 = &tcph;
  108         struct in_addr swip, swip2;
  109         int off, dlen, nflags;
  110         char portbuf[8], *s;
  111         fr_info_t fi;
  112         u_short sp;
  113         nat_t *nat2;
  114         ip_t *ip;
  115         mb_t *m;
  116 
  117         tcp = (tcphdr_t *)fin->fin_dp;
  118 
  119         if (tcp->th_flags & TH_SYN) {
  120                 *(u_32_t *)aps->aps_data = htonl(ntohl(tcp->th_seq) + 1);
  121                 return 0;
  122         }
  123 
  124         if ((*(u_32_t *)aps->aps_data != 0) &&
  125             (tcp->th_seq != *(u_32_t *)aps->aps_data))
  126                 return 0;
  127 
  128         m = fin->fin_m;
  129         ip = fin->fin_ip;
  130         off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
  131 
  132 #ifdef __sgi
  133         dlen = fin->fin_plen - off;
  134 #else
  135         dlen = MSGDSIZE(m) - off;
  136 #endif
  137         if (dlen <= 0)
  138                 return 0;
  139 
  140         bzero(portbuf, sizeof(portbuf));
  141         COPYDATA(m, off, MIN(sizeof(portbuf), dlen), portbuf);
  142 
  143         portbuf[sizeof(portbuf) - 1] = '\0';
  144         s = portbuf;
  145         sp = ipf_rcmd_atoi(s);
  146         if (sp == 0) {
  147 #ifdef IP_RCMD_PROXY_DEBUG
  148                 printf("ippr_rcmd_portmsg:sp == 0 dlen %d [%s]\n",
  149                        dlen, portbuf);
  150 #endif
  151                 return 0;
  152         }
  153 
  154         /*
  155          * Add skeleton NAT entry for connection which will come back the
  156          * other way.
  157          */
  158         bcopy((char *)fin, (char *)&fi, sizeof(fi));
  159         fi.fin_flx |= FI_IGNORE;
  160         fi.fin_data[0] = sp;
  161         fi.fin_data[1] = 0;
  162         if (nat->nat_dir == NAT_OUTBOUND)
  163                 nat2 = nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p,
  164                                      nat->nat_inip, nat->nat_oip);
  165         else
  166                 nat2 = nat_inlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p,
  167                                     nat->nat_inip, nat->nat_oip);
  168         if (nat2 == NULL) {
  169                 int slen;
  170 
  171                 slen = ip->ip_len;
  172                 ip->ip_len = fin->fin_hlen + sizeof(*tcp);
  173                 bzero((char *)tcp2, sizeof(*tcp2));
  174                 tcp2->th_win = htons(8192);
  175                 tcp2->th_sport = htons(sp);
  176                 tcp2->th_dport = 0; /* XXX - don't specify remote port */
  177                 TCP_OFF_A(tcp2, 5);
  178                 tcp2->th_flags = TH_SYN;
  179                 fi.fin_dp = (char *)tcp2;
  180                 fi.fin_fr = &rcmdfr;
  181                 fi.fin_dlen = sizeof(*tcp2);
  182                 fi.fin_plen = fi.fin_hlen + sizeof(*tcp2);
  183                 fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE;
  184                 nflags = NAT_SLAVE|IPN_TCP|SI_W_DPORT;
  185 
  186                 swip = ip->ip_src;
  187                 swip2 = ip->ip_dst;
  188 
  189                 if (nat->nat_dir == NAT_OUTBOUND) {
  190                         fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
  191                         ip->ip_src = nat->nat_inip;
  192                 } else {
  193                         fi.fin_fi.fi_saddr = nat->nat_oip.s_addr;
  194                         ip->ip_src = nat->nat_oip;
  195                         nflags |= NAT_NOTRULEPORT;
  196                 }
  197 
  198                 nat2 = nat_new(&fi, nat->nat_ptr, NULL, nflags, nat->nat_dir);
  199 
  200                 if (nat2 != NULL) {
  201                         (void) nat_proto(&fi, nat2, IPN_TCP);
  202                         nat_update(&fi, nat2, nat2->nat_ptr);
  203                         fi.fin_ifp = NULL;
  204                         if (nat->nat_dir == NAT_INBOUND) {
  205                                 fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
  206                                 ip->ip_dst = nat->nat_inip;
  207                         }
  208                         (void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT);
  209                 }
  210                 ip->ip_len = slen;
  211                 ip->ip_src = swip;
  212                 ip->ip_dst = swip2;
  213         }
  214         return 0;
  215 }
  216 
  217 
  218 int ippr_rcmd_out(fin, aps, nat)
  219 fr_info_t *fin;
  220 ap_session_t *aps;
  221 nat_t *nat;
  222 {
  223         if (nat->nat_dir == NAT_OUTBOUND)
  224                 return ippr_rcmd_portmsg(fin, aps, nat);
  225         return 0;
  226 }
  227 
  228 
  229 int ippr_rcmd_in(fin, aps, nat)
  230 fr_info_t *fin;
  231 ap_session_t *aps;
  232 nat_t *nat;
  233 {
  234         if (nat->nat_dir == NAT_INBOUND)
  235                 return ippr_rcmd_portmsg(fin, aps, nat);
  236         return 0;
  237 }

Cache object: 73be52e84ce06cb2678b7203def20dce


[ 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.