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_pptp_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_pptp_pxy.c,v 1.1.1.1.2.1 2004/08/13 03:55:49 jmc Exp $      */
    2 
    3 /*
    4  * Copyright (C) 2002-2003 by Darren Reed
    5  *
    6  * Simple PPTP transparent proxy for in-kernel use.  For use with the NAT
    7  * code.
    8  *
    9  * Id: ip_pptp_pxy.c,v 2.10.2.5 2004/06/07 14:20:05 darrenr Exp
   10  *
   11  */
   12 #define IPF_PPTP_PROXY
   13 
   14 typedef struct pptp_pxy {
   15         ipnat_t         pptp_rule;
   16         nat_t           *pptp_nat;
   17         ipstate_t       *pptp_state;
   18         int             pptp_seencookie;
   19         u_32_t          pptp_cookie;
   20 } pptp_pxy_t;
   21 
   22 
   23 int ippr_pptp_init __P((void));
   24 void ippr_pptp_fini __P((void));
   25 int ippr_pptp_new __P((fr_info_t *, ap_session_t *, nat_t *));
   26 void ippr_pptp_del __P((ap_session_t *));
   27 int ippr_pptp_inout __P((fr_info_t *, ap_session_t *, nat_t *));
   28 int ippr_pptp_match __P((fr_info_t *, ap_session_t *, nat_t *));
   29 
   30 static  frentry_t       pptpfr;
   31 
   32 int     pptp_proxy_init = 0;
   33 
   34 
   35 /*
   36  * PPTP application proxy initialization.
   37  */
   38 int ippr_pptp_init()
   39 {
   40         bzero((char *)&pptpfr, sizeof(pptpfr));
   41         pptpfr.fr_ref = 1;
   42         pptpfr.fr_flags = FR_OUTQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
   43         MUTEX_INIT(&pptpfr.fr_lock, "PPTP proxy rule lock");
   44         pptp_proxy_init = 1;
   45 
   46         return 0;
   47 }
   48 
   49 
   50 void ippr_pptp_fini()
   51 {
   52         if (pptp_proxy_init == 1) {
   53                 MUTEX_DESTROY(&pptpfr.fr_lock);
   54                 pptp_proxy_init = 0;
   55         }
   56 }
   57 
   58 
   59 /*
   60  * Setup for a new PPTP proxy.
   61  */
   62 int ippr_pptp_new(fin, aps, nat)
   63 fr_info_t *fin;
   64 ap_session_t *aps;
   65 nat_t *nat;
   66 {
   67         pptp_pxy_t *pptp;
   68         fr_info_t fi;
   69         ipnat_t *ipn;
   70         nat_t *nat2;
   71         int p, off;
   72         ip_t *ip;
   73 
   74         ip = fin->fin_ip;
   75         off = fin->fin_hlen + sizeof(udphdr_t);
   76 
   77         if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip,
   78                           ip->ip_dst) != NULL)
   79                 return -1;
   80 
   81         aps->aps_psiz = sizeof(*pptp);
   82         KMALLOCS(aps->aps_data, pptp_pxy_t *, sizeof(*pptp));
   83         if (aps->aps_data == NULL)
   84                 return -1;
   85 
   86         ip = fin->fin_ip;
   87         pptp = aps->aps_data;
   88         bzero((char *)pptp, sizeof(*pptp));
   89 
   90         /*
   91          * Create NAT rule against which the tunnel/transport mapping is
   92          * created.  This is required because the current NAT rule does not
   93          * describe GRE but TCP instead.
   94          */
   95         ipn = &pptp->pptp_rule;
   96         ipn->in_ifps[0] = fin->fin_ifp;
   97         ipn->in_apr = NULL;
   98         ipn->in_use = 1;
   99         ipn->in_hits = 1;
  100         ipn->in_nip = ntohl(nat->nat_outip.s_addr);
  101         ipn->in_ippip = 1;
  102         ipn->in_inip = nat->nat_inip.s_addr;
  103         ipn->in_inmsk = 0xffffffff;
  104         ipn->in_outip = fin->fin_saddr;
  105         ipn->in_outmsk = nat->nat_outip.s_addr;
  106         ipn->in_srcip = fin->fin_saddr;
  107         ipn->in_srcmsk = 0xffffffff;
  108         ipn->in_redir = NAT_MAP;
  109         bcopy(nat->nat_ptr->in_ifnames[0], ipn->in_ifnames[0],
  110               sizeof(ipn->in_ifnames[0]));
  111         ipn->in_p = IPPROTO_GRE;
  112 
  113         bcopy((char *)fin, (char *)&fi, sizeof(fi));
  114         fi.fin_fi.fi_p = IPPROTO_GRE;
  115         fi.fin_fr = &pptpfr;
  116         fi.fin_data[0] = 0;
  117         fi.fin_data[1] = 0;
  118         p = ip->ip_p;
  119         ip->ip_p = IPPROTO_GRE;
  120         fi.fin_flx &= ~FI_TCPUDP;
  121         fi.fin_flx |= FI_IGNORE;
  122 
  123         nat2 = nat_new(&fi, ipn, &pptp->pptp_nat, 0, NAT_OUTBOUND);
  124         pptp->pptp_nat = nat2;
  125         if (nat2 != NULL) {
  126                 (void) nat_proto(&fi, nat2, 0);
  127                 nat_update(&fi, nat2, nat2->nat_ptr);
  128 
  129                 fi.fin_data[0] = 0;
  130                 fi.fin_data[1] = 0;
  131                 pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state, 0);
  132         }
  133         ip->ip_p = p;
  134         return 0;
  135 }
  136 
  137 
  138 /*
  139  * For outgoing PPTP packets.  refresh timeouts for NAT & state entries, if
  140  * we can.  If they have disappeared, recreate them.
  141  */
  142 int ippr_pptp_inout(fin, aps, nat)
  143 fr_info_t *fin;
  144 ap_session_t *aps;
  145 nat_t *nat;
  146 {
  147         pptp_pxy_t *pptp;
  148         fr_info_t fi;
  149         nat_t *nat2;
  150         ip_t *ip;
  151         int p;
  152 
  153         if ((fin->fin_out == 1) && (nat->nat_dir == NAT_INBOUND))
  154                 return 0;
  155 
  156         if ((fin->fin_out == 0) && (nat->nat_dir == NAT_OUTBOUND))
  157                 return 0;
  158 
  159         pptp = aps->aps_data;
  160 
  161         if (pptp != NULL) {
  162                 ip = fin->fin_ip;
  163                 p = ip->ip_p;
  164 
  165                 if ((pptp->pptp_nat == NULL) || (pptp->pptp_state == NULL)) {
  166                         bcopy((char *)fin, (char *)&fi, sizeof(fi));
  167                         fi.fin_fi.fi_p = IPPROTO_GRE;
  168                         fi.fin_fr = &pptpfr;
  169                         fi.fin_data[0] = 0;
  170                         fi.fin_data[1] = 0;
  171                         ip->ip_p = IPPROTO_GRE;
  172                         fi.fin_flx &= ~FI_TCPUDP;
  173                         fi.fin_flx |= FI_IGNORE;
  174                 }
  175 
  176                 /*
  177                  * Update NAT timeout/create NAT if missing.
  178                  */
  179                 if (pptp->pptp_nat != NULL)
  180                         fr_queueback(&pptp->pptp_nat->nat_tqe);
  181                 else {
  182                         nat2 = nat_new(&fi, &pptp->pptp_rule, &pptp->pptp_nat,
  183                                        NAT_SLAVE, nat->nat_dir);
  184                         pptp->pptp_nat = nat2;
  185                         if (nat2 != NULL) {
  186                                 (void) nat_proto(&fi, nat2, 0);
  187                                 nat_update(&fi, nat2, nat2->nat_ptr);
  188                         }
  189                 }
  190 
  191                 /*
  192                  * Update state timeout/create state if missing.
  193                  */
  194                 READ_ENTER(&ipf_state);
  195                 if (pptp->pptp_state != NULL) {
  196                         fr_queueback(&pptp->pptp_state->is_sti);
  197                         RWLOCK_EXIT(&ipf_state);
  198                 } else {
  199                         RWLOCK_EXIT(&ipf_state);
  200                         fi.fin_data[0] = 0;
  201                         fi.fin_data[1] = 0;
  202                         pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state,
  203                                                        0);
  204                 }
  205                 ip->ip_p = p;
  206         }
  207         return 0;
  208 }
  209 
  210 
  211 /*
  212  * clean up after ourselves.
  213  */
  214 void ippr_pptp_del(aps)
  215 ap_session_t *aps;
  216 {
  217         pptp_pxy_t *pptp;
  218 
  219         pptp = aps->aps_data;
  220 
  221         if (pptp != NULL) {
  222                 /*
  223                  * Don't bother changing any of the NAT structure details,
  224                  * *_del() is on a callback from aps_free(), from nat_delete()
  225                  */
  226 
  227                 READ_ENTER(&ipf_state);
  228                 if (pptp->pptp_state != NULL) {
  229                         pptp->pptp_state->is_die = fr_ticks + 1;
  230                         pptp->pptp_state->is_me = NULL;
  231                         fr_queuefront(&pptp->pptp_state->is_sti);
  232                 }
  233                 RWLOCK_EXIT(&ipf_state);
  234 
  235                 pptp->pptp_state = NULL;
  236                 pptp->pptp_nat = NULL;
  237         }
  238 }
  239 
  240 
  241 int ippr_pptp_match(fin, aps, nat)
  242 fr_info_t *fin;
  243 ap_session_t *aps;
  244 nat_t *nat;
  245 {
  246         pptp_pxy_t *pptp;
  247         tcphdr_t *tcp;
  248         u_32_t cookie;
  249 
  250         pptp = aps->aps_data;
  251         tcp = fin->fin_dp;
  252 
  253         if ((pptp != NULL) && (fin->fin_dlen - (TCP_OFF(tcp) << 2) >= 8)) {
  254                 u_char *cs;
  255 
  256                 cs = (u_char *)tcp + (TCP_OFF(tcp) << 2) + 4;
  257 
  258                 if (pptp->pptp_seencookie == 0) {
  259                         pptp->pptp_seencookie = 1;
  260                         pptp->pptp_cookie = (cs[0] << 24) | (cs[1] << 16) |
  261                                             (cs[2] << 8) | cs[3];
  262                 } else {
  263                         cookie = (cs[0] << 24) | (cs[1] << 16) |
  264                                  (cs[2] << 8) | cs[3];
  265                         if (cookie != pptp->pptp_cookie)
  266                                 return -1;
  267                 }
  268 
  269         }
  270         return 0;
  271 }

Cache object: 4dbfe7ac28f0b0d8f9dd1a1c29fb1e20


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