Annotation of embedaddon/mpd/src/pptp.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * pptp.c
                      4:  *
                      5:  * Written by Archie Cobbs <archie@freebsd.org>
                      6:  * Copyright (c) 1998-1999 Whistle Communications, Inc. All rights reserved.
                      7:  * See ``COPYRIGHT.whistle''
                      8:  */
                      9: 
                     10: #include "ppp.h"
                     11: #include "phys.h"
                     12: #include "mbuf.h"
                     13: #include "ngfunc.h"
                     14: #include "pptp.h"
                     15: #include "pptp_ctrl.h"
                     16: #include "log.h"
                     17: #include "util.h"
                     18: 
                     19: #include <netgraph/ng_message.h>
                     20: #include <netgraph/ng_socket.h>
                     21: #include <netgraph/ng_ksocket.h>
                     22: #include <netgraph/ng_pptpgre.h>
                     23: #include <netgraph.h>
                     24: 
                     25: /*
                     26:  * DEFINITIONS
                     27:  */
                     28: 
                     29:   #define PPTP_MRU             PPTP_MTU
                     30: 
                     31:   #define PPTP_CALL_MIN_BPS    56000
                     32:   #define PPTP_CALL_MAX_BPS    64000
                     33: 
                     34:   struct pptptun {
                     35:     struct u_addr      self_addr;      /* Current self IP address */
                     36:     struct u_addr      peer_addr;      /* Current peer IP address */
                     37:     ng_ID_t            node_id;
                     38:     int                        refs;
                     39:   };
                     40:   typedef struct pptptun       *PptpTun;
                     41: 
                     42:   struct pptpinfo {
                     43:     struct {
                     44:        struct u_addr   self_addr;      /* self IP address */
                     45:        struct u_range  peer_addr;      /* Peer IP addresses allowed */
                     46:        in_port_t       self_port;      /* self port */
                     47:        in_port_t       peer_port;      /* Peer port required (or zero) */
                     48:        struct optinfo  options;
                     49:        char            callingnum[64]; /* PPTP phone number to use */
                     50:        char            callednum[64];  /* PPTP phone number to use */
                     51:        char            *fqdn_peer_addr;        /* FQDN Peer address */
                     52:     } conf;
                     53:     void               *listener;      /* Listener pointer */
                     54:     struct u_addr      self_addr;      /* Current self IP address */
                     55:     struct u_addr      peer_addr;      /* Current peer IP address */
                     56:     char                peer_iface[IFNAMSIZ];  /* Peer iface */
                     57:     u_char             peer_mac_addr[6];       /* Peer MAC address */
                     58:     in_port_t          peer_port;      /* Current peer port */
                     59:     u_char             originate;      /* Call originated locally */
                     60:     u_char             outcall;        /* Call is outgoing vs. incoming */
                     61:     u_char             sync;           /* Call is sync vs. async */
                     62:     u_int16_t          cid;            /* call id */
                     63:     PptpTun            tun;
                     64:     struct pptpctrlinfo        cinfo;
                     65:     char               callingnum[64]; /* PPTP phone number to use */
                     66:     char               callednum[64];  /* PPTP phone number to use */
                     67:   };
                     68:   typedef struct pptpinfo      *PptpInfo;
                     69: 
                     70:   /* Set menu options */
                     71:   enum {
                     72:     SET_SELFADDR,
                     73:     SET_PEERADDR,
                     74:     SET_CALLINGNUM,
                     75:     SET_CALLEDNUM,
                     76:     SET_ENABLE,
                     77:     SET_DISABLE
                     78:   };
                     79: 
                     80:   /* Binary options */
                     81:   enum {
                     82:     PPTP_CONF_OUTCALL,         /* when originating, calls are "outgoing" */
                     83:     PPTP_CONF_DELAYED_ACK,     /* enable delayed receive ack algorithm */
                     84:     PPTP_CONF_ALWAYS_ACK,      /* include ack with all outgoing data packets */
                     85:     PPTP_CONF_RESOLVE_ONCE,    /* Only once resolve peer_addr */
                     86: #if NGM_PPTPGRE_COOKIE >= 1082548365
                     87:     PPTP_CONF_WINDOWING                /* control (stupid) windowing algorithm */
                     88: #endif
                     89:   };
                     90: 
                     91: /*
                     92:  * INTERNAL FUNCTIONS
                     93:  */
                     94: 
                     95:   static int   PptpTInit(void);
                     96:   static void  PptpTShutdown(void);
                     97:   static int   PptpInit(Link l);
                     98:   static int   PptpInst(Link l, Link lt);
                     99:   static void  PptpOpen(Link l);
                    100:   static void  PptpClose(Link l);
                    101:   static void  PptpShutdown(Link l);
                    102:   static void  PptpStat(Context ctx);
                    103:   static int   PptpOriginated(Link l);
                    104:   static int   PptpIsSync(Link l);
                    105:   static int   PptpSetAccm(Link l, u_int32_t xmit, u_int32_t recv);
                    106:   static int   PptpSetCallingNum(Link l, void *buf);
                    107:   static int   PptpSetCalledNum(Link l, void *buf);
                    108:   static int   PptpSelfName(Link l, void *buf, size_t buf_len);
                    109:   static int   PptpPeerName(Link l, void *buf, size_t buf_len);
                    110:   static int   PptpSelfAddr(Link l, void *buf, size_t buf_len);
                    111:   static int   PptpPeerAddr(Link l, void *buf, size_t buf_len);
                    112:   static int   PptpPeerPort(Link l, void *buf, size_t buf_len);
                    113:   static int   PptpPeerMacAddr(Link l, void *buf, size_t buf_len);
                    114:   static int   PptpPeerIface(Link l, void *buf, size_t buf_len);
                    115:   static int   PptpCallingNum(Link l, void *buf, size_t buf_len);
                    116:   static int   PptpCalledNum(Link l, void *buf, size_t buf_len);
                    117: 
                    118:   static int   PptpOriginate(Link l);
                    119:   static void  PptpDoClose(Link l);
                    120:   static void  PptpUnhook(Link l);
                    121:   static void  PptpResult(void *cookie, const char *errmsg, int frameType);
                    122:   static void  PptpSetLinkInfo(void *cookie, u_int32_t sa, u_int32_t ra);
                    123:   static void  PptpCancel(void *cookie);
                    124:   static int   PptpHookUp(Link l);
                    125:   static void  PptpListenUpdate(Link l);
                    126: 
                    127:   static struct pptplinkinfo   PptpIncoming(struct pptpctrlinfo *cinfo,
                    128:                                  struct u_addr *self, struct u_addr *peer, in_port_t port, int bearType,
                    129:                                  const char *callingNum,
                    130:                                  const char *calledNum,
                    131:                                  const char *subAddress);
                    132: 
                    133:   static struct pptplinkinfo   PptpOutgoing(struct pptpctrlinfo *cinfo,
                    134:                                  struct u_addr *self, struct u_addr *peer, in_port_t port, int bearType,
                    135:                                  int frameType, int minBps, int maxBps,
                    136:                                  const char *calledNum,
                    137:                                  const char *subAddress);
                    138: 
                    139:   static struct pptplinkinfo   PptpPeerCall(struct pptpctrlinfo *cinfo,
                    140:                                  struct u_addr *self, struct u_addr *peer, in_port_t port, int incoming,
                    141:                                  const char *callingNum,
                    142:                                  const char *calledNum,
                    143:                                  const char *subAddress);
                    144: 
                    145:   static int   PptpSetCommand(Context ctx, int ac, char *av[], void *arg);
                    146:   static int   PptpTunEQ(struct ghash *g, const void *item1, const void *item2);
                    147:   static u_int32_t     PptpTunHash(struct ghash *g, const void *item);
                    148: 
                    149: 
                    150: /*
                    151:  * GLOBAL VARIABLES
                    152:  */
                    153: 
                    154:   const struct phystype        gPptpPhysType = {
                    155:     .name              = "pptp",
                    156:     .descr             = "Point-to-Point Tunneling Protocol",
                    157:     .mtu               = PPTP_MTU,
                    158:     .mru               = PPTP_MRU,
                    159:     .tmpl              = 1,
                    160:     .tinit             = PptpTInit,
                    161:     .tshutdown         = PptpTShutdown,
                    162:     .init              = PptpInit,
                    163:     .inst              = PptpInst,
                    164:     .open              = PptpOpen,
                    165:     .close             = PptpClose,
                    166:     .update            = PptpListenUpdate,
                    167:     .shutdown          = PptpShutdown,
                    168:     .showstat          = PptpStat,
                    169:     .originate         = PptpOriginated,
                    170:     .issync            = PptpIsSync,
                    171:     .setaccm            = PptpSetAccm,
                    172:     .setcallingnum     = PptpSetCallingNum,
                    173:     .setcallednum      = PptpSetCalledNum,
                    174:     .selfname          = PptpSelfName,
                    175:     .peername          = PptpPeerName,
                    176:     .selfaddr          = PptpSelfAddr,
                    177:     .peeraddr          = PptpPeerAddr,
                    178:     .peerport          = PptpPeerPort,
                    179:     .peermacaddr       = PptpPeerMacAddr,
                    180:     .peeriface         = PptpPeerIface,
                    181:     .callingnum                = PptpCallingNum,
                    182:     .callednum         = PptpCalledNum,
                    183:   };
                    184: 
                    185:   const struct cmdtab  PptpSetCmds[] = {
                    186:     { "self {ip} [{port}]",            "Set local IP address",
                    187:        PptpSetCommand, NULL, 2, (void *) SET_SELFADDR },
                    188:     { "peer {ip} [{port}]",            "Set remote IP address",
                    189:        PptpSetCommand, NULL, 2, (void *) SET_PEERADDR },
                    190:     { "callingnum {number}",           "Set calling PPTP telephone number",
                    191:        PptpSetCommand, NULL, 2, (void *) SET_CALLINGNUM },
                    192:     { "callednum {number}",            "Set called PPTP telephone number",
                    193:        PptpSetCommand, NULL, 2, (void *) SET_CALLEDNUM },
                    194:     { "enable [opt ...]",              "Enable option",
                    195:        PptpSetCommand, NULL, 2, (void *) SET_ENABLE },
                    196:     { "disable [opt ...]",             "Disable option",
                    197:        PptpSetCommand, NULL, 2, (void *) SET_DISABLE },
                    198:     { NULL },
                    199:   };
                    200: 
                    201: /*
                    202:  * INTERNAL VARIABLES
                    203:  */
                    204: 
                    205:   static struct confinfo       gConfList[] = {
                    206:     { 0,       PPTP_CONF_OUTCALL,      "outcall"       },
                    207:     { 0,       PPTP_CONF_DELAYED_ACK,  "delayed-ack"   },
                    208:     { 0,       PPTP_CONF_ALWAYS_ACK,   "always-ack"    },
                    209:     { 0,       PPTP_CONF_RESOLVE_ONCE, "resolve-once"  },
                    210: #if NGM_PPTPGRE_COOKIE >= 1082548365
                    211:     { 0,       PPTP_CONF_WINDOWING,    "windowing"     },
                    212: #endif
                    213:     { 0,       0,                      NULL            },
                    214:   };
                    215: 
                    216: struct ghash    *gPptpTuns;
                    217: 
                    218: /*
                    219:  * PptpTInit()
                    220:  */
                    221: 
                    222: static int
                    223: PptpTInit(void)
                    224: {
                    225:     if ((gPptpTuns = ghash_create(NULL, 0, 0, MB_PHYS, PptpTunHash, PptpTunEQ, NULL, NULL))
                    226:          == NULL)
                    227:        return(-1);
                    228:     return (PptpCtrlInit(PptpIncoming, PptpOutgoing));
                    229: }
                    230: 
                    231: /*
                    232:  * PptpTShutdown()
                    233:  */
                    234: 
                    235: static void
                    236: PptpTShutdown(void)
                    237: {
                    238:     Log(LG_PHYS2, ("PPTP: Total shutdown"));
                    239:     ghash_destroy(&gPptpTuns);
                    240: }
                    241: 
                    242: /*
                    243:  * PptpInit()
                    244:  */
                    245: 
                    246: static int
                    247: PptpInit(Link l)
                    248: {
                    249:     PptpInfo   pptp;
                    250: 
                    251:     /* Initialize this link */
                    252:     pptp = (PptpInfo) (l->info = Malloc(MB_PHYS, sizeof(*pptp)));
                    253: 
                    254:     pptp->conf.self_addr.family = AF_INET;
                    255:     pptp->conf.fqdn_peer_addr = NULL;
                    256:     Enable(&pptp->conf.options, PPTP_CONF_OUTCALL);
                    257:     Enable(&pptp->conf.options, PPTP_CONF_DELAYED_ACK);
                    258:     Enable(&pptp->conf.options, PPTP_CONF_RESOLVE_ONCE);
                    259: 
                    260:     return(0);
                    261: }
                    262: 
                    263: /*
                    264:  * PptpInst()
                    265:  */
                    266: 
                    267: static int
                    268: PptpInst(Link l, Link lt)
                    269: {
                    270:     PptpInfo   pptp;
                    271:     PptpInfo   const pptpt = (PptpInfo) lt->info;
                    272: 
                    273:     /* Initialize this link */
                    274:     pptp = (PptpInfo) (l->info = Mdup(MB_PHYS, lt->info, sizeof(*pptp)));
                    275:     if (pptpt->conf.fqdn_peer_addr != NULL)
                    276:         pptp->conf.fqdn_peer_addr =
                    277:             Mstrdup(MB_PHYS, pptpt->conf.fqdn_peer_addr);
                    278:     pptp->listener = NULL;
                    279: 
                    280:     return(0);
                    281: }
                    282: 
                    283: /*
                    284:  * PptpOpen()
                    285:  */
                    286: 
                    287: static void
                    288: PptpOpen(Link l)
                    289: {
                    290:     PptpInfo           const pptp = (PptpInfo) l->info;
                    291:     struct sockaddr_dl  hwa;
                    292: 
                    293:     /* Check state */
                    294:     switch (l->state) {
                    295:        case PHYS_STATE_DOWN:
                    296:            if (PptpOriginate(l) < 0) {
                    297:                Log(LG_PHYS, ("[%s] PPTP call failed", l->name));
                    298:                PhysDown(l, STR_ERROR, NULL);
                    299:                return;
                    300:            }
                    301:            l->state = PHYS_STATE_CONNECTING;
                    302:            break;
                    303: 
                    304:        case PHYS_STATE_CONNECTING:
                    305:            if (pptp->originate)        /* our call to peer is already in progress */
                    306:                break;
                    307:            if (pptp->outcall) {
                    308: 
                    309:                /* Hook up nodes */
                    310:                Log(LG_PHYS, ("[%s] PPTP: attaching to peer's outgoing call", l->name));
                    311:                if (PptpHookUp(l) < 0) {
                    312:                    PptpDoClose(l);
                    313:                    /* We should not set state=DOWN as PptpResult() will be called once more */
                    314:                    break;
                    315:                }
                    316: 
                    317:                if (GetPeerEther(&pptp->peer_addr, &hwa)) {
                    318:                    if_indextoname(hwa.sdl_index, pptp->peer_iface);
                    319:                    memcpy(pptp->peer_mac_addr, LLADDR(&hwa), sizeof(pptp->peer_mac_addr));
                    320:                };
                    321: 
                    322:                (*pptp->cinfo.answer)(pptp->cinfo.cookie,
                    323:                    PPTP_OCR_RESL_OK, 0, 0, 64000 /*XXX*/ );
                    324: 
                    325:                /* Report UP if there was no error. */
                    326:                if (l->state == PHYS_STATE_CONNECTING) {
                    327:                    l->state = PHYS_STATE_UP;
                    328:                    PhysUp(l);
                    329:                }
                    330:                return;
                    331:            }
                    332:            return;     /* wait for peer's incoming pptp call to complete */
                    333: 
                    334:        case PHYS_STATE_UP:
                    335:            PhysUp(l);
                    336:            return;
                    337: 
                    338:        default:
                    339:            assert(0);
                    340:     }
                    341: }
                    342: 
                    343: /*
                    344:  * PptpOriginate()
                    345:  *
                    346:  * Initiate an "incoming" or an "outgoing" call to the remote site
                    347:  */
                    348: 
                    349: static int
                    350: PptpOriginate(Link l)
                    351: {
                    352:     PptpInfo           const pptp = (PptpInfo) l->info;
                    353:     struct pptplinkinfo        linfo;
                    354:     const u_short      port = pptp->conf.peer_port ?
                    355:                            pptp->conf.peer_port : PPTP_PORT;
                    356: 
                    357:     pptp->originate = TRUE;
                    358:     pptp->outcall = Enabled(&pptp->conf.options, PPTP_CONF_OUTCALL);
                    359:     memset(&linfo, 0, sizeof(linfo));
                    360:     linfo.cookie = l;
                    361:     linfo.result = PptpResult;
                    362:     linfo.setLinkInfo = PptpSetLinkInfo;
                    363:     linfo.cancel = PptpCancel;
                    364:     strlcpy(pptp->callingnum, pptp->conf.callingnum, sizeof(pptp->callingnum));
                    365:     strlcpy(pptp->callednum, pptp->conf.callednum, sizeof(pptp->callednum));
                    366:     if ((!Enabled(&pptp->conf.options, PPTP_CONF_RESOLVE_ONCE)) &&
                    367:        (pptp->conf.fqdn_peer_addr != NULL)) {
                    368:        struct u_range  rng;
                    369:        if (ParseRange(pptp->conf.fqdn_peer_addr, &rng, ALLOW_IPV4|ALLOW_IPV6))
                    370:            pptp->conf.peer_addr = rng;
                    371:     }
                    372:     if (!pptp->outcall) {
                    373:        int frameType = PPTP_FRAMECAP_SYNC;
                    374:        if (l->rep && !RepIsSync(l))
                    375:            frameType = PPTP_FRAMECAP_ASYNC;
                    376:        PptpCtrlInCall(&pptp->cinfo, &linfo, 
                    377:            &pptp->conf.self_addr, &pptp->conf.peer_addr.addr, port,
                    378:            PPTP_BEARCAP_ANY, frameType,
                    379:            PPTP_CALL_MIN_BPS, PPTP_CALL_MAX_BPS, 
                    380:            pptp->callingnum, pptp->callednum, "");
                    381:     } else {
                    382:        PptpCtrlOutCall(&pptp->cinfo, &linfo, 
                    383:            &pptp->conf.self_addr, &pptp->conf.peer_addr.addr, port,
                    384:            PPTP_BEARCAP_ANY, PPTP_FRAMECAP_ANY,
                    385:            PPTP_CALL_MIN_BPS, PPTP_CALL_MAX_BPS,
                    386:            pptp->callednum, "");
                    387:     }
                    388:     if (pptp->cinfo.cookie == NULL)
                    389:        return(-1);
                    390:     pptp->self_addr = pptp->conf.self_addr;
                    391:     pptp->peer_addr = pptp->conf.peer_addr.addr;
                    392:     pptp->peer_port = port;
                    393:     return(0);
                    394: }
                    395: 
                    396: /*
                    397:  * PptpClose()
                    398:  */
                    399: 
                    400: static void
                    401: PptpClose(Link l)
                    402: {
                    403:     PptpDoClose(l);
                    404: }
                    405: 
                    406: /*
                    407:  * PptpShutdown()
                    408:  */
                    409: 
                    410: static void
                    411: PptpShutdown(Link l)
                    412: {
                    413:     PptpInfo      const pptp = (PptpInfo) l->info;
                    414: 
                    415: 
                    416:     if (pptp->conf.fqdn_peer_addr)
                    417:         Freee(pptp->conf.fqdn_peer_addr);
                    418:     if (pptp->listener) {
                    419:        PptpCtrlUnListen(pptp->listener);
                    420:        pptp->listener = NULL;
                    421:     }
                    422:     PptpUnhook(l);
                    423:     Freee(l->info);
                    424: }
                    425: 
                    426: /*
                    427:  * PptpDoClose()
                    428:  */
                    429: 
                    430: static void
                    431: PptpDoClose(Link l)
                    432: {
                    433:     PptpInfo      const pptp = (PptpInfo) l->info;
                    434: 
                    435:     if (l->state != PHYS_STATE_DOWN)           /* avoid double close */
                    436:        (*pptp->cinfo.close)(pptp->cinfo.cookie, PPTP_CDN_RESL_ADMIN, 0, 0);
                    437: }
                    438: 
                    439: /*
                    440:  * PptpUnhook()
                    441:  */
                    442: 
                    443: static void
                    444: PptpUnhook(Link l)
                    445: {
                    446:        PptpInfo const  pptp = (PptpInfo) l->info;
                    447:        char            path[NG_PATHSIZ];
                    448:        int             csock = -1;
                    449: 
                    450:        if (pptp->tun == NULL)
                    451:                return;
                    452: 
                    453:        /* Get a temporary netgraph socket node */
                    454:        if (NgMkSockNode(NULL, &csock, NULL) == -1) {
                    455:                Perror("PPTP: NgMkSockNode");
                    456:                return;
                    457:        }
                    458:        
                    459:        pptp->tun->refs--;
                    460:        snprintf(path, sizeof(path), "[%lx]:", (u_long)pptp->tun->node_id);
                    461:        if (pptp->tun->refs == 0) {
                    462:            /* Disconnect session hook. */
                    463:            NgFuncShutdownNode(csock, l->name, path);
                    464:            ghash_remove(gPptpTuns, pptp->tun);
                    465:            Freee(pptp->tun);
                    466: #ifdef NG_PPTPGRE_HOOK_SESSION_F
                    467:        } else {
                    468:            char        hook[NG_HOOKSIZ];
                    469:            snprintf(hook, sizeof(hook), NG_PPTPGRE_HOOK_SESSION_F, pptp->cid);
                    470:            NgFuncDisconnect(csock, l->name, path, hook);
                    471: #endif
                    472:        }
                    473:        
                    474:        close(csock);
                    475:        
                    476:        pptp->tun = NULL;
                    477: }
                    478: 
                    479: /*
                    480:  * PptpOriginated()
                    481:  */
                    482: 
                    483: static int
                    484: PptpOriginated(Link l)
                    485: {
                    486:     PptpInfo   const pptp = (PptpInfo) l->info;
                    487: 
                    488:     return(pptp->originate ? LINK_ORIGINATE_LOCAL : LINK_ORIGINATE_REMOTE);
                    489: }
                    490: 
                    491: /*
                    492:  * PptpIsSync()
                    493:  */
                    494: 
                    495: static int
                    496: PptpIsSync(Link l)
                    497: {
                    498:     PptpInfo   const pptp = (PptpInfo) l->info;
                    499: 
                    500:     return (pptp->sync);
                    501: }
                    502: 
                    503: static int
                    504: PptpSetAccm(Link l, u_int32_t xmit, u_int32_t recv)
                    505: {
                    506:     PptpInfo   const pptp = (PptpInfo) l->info;
                    507:     
                    508:     if (!pptp->cinfo.close || !pptp->cinfo.cookie)
                    509:            return (-1);
                    510: 
                    511:     (*pptp->cinfo.setLinkInfo)(pptp->cinfo.cookie, xmit, recv);
                    512:     return (0);
                    513: }
                    514: 
                    515: static int
                    516: PptpSetCallingNum(Link l, void *buf)
                    517: {
                    518:     PptpInfo   const pptp = (PptpInfo) l->info;
                    519: 
                    520:     strlcpy(pptp->conf.callingnum, buf, sizeof(pptp->conf.callingnum));
                    521:     return(0);
                    522: }
                    523: 
                    524: static int
                    525: PptpSetCalledNum(Link l, void *buf)
                    526: {
                    527:     PptpInfo   const pptp = (PptpInfo) l->info;
                    528: 
                    529:     strlcpy(pptp->conf.callednum, buf, sizeof(pptp->conf.callednum));
                    530:     return(0);
                    531: }
                    532: 
                    533: static int
                    534: PptpSelfName(Link l, void *buf, size_t buf_len)
                    535: {
                    536:     PptpInfo   const pptp = (PptpInfo) l->info;
                    537: 
                    538:     if (pptp->cinfo.cookie)
                    539:        return(PptpCtrlGetSelfName(&pptp->cinfo, buf, buf_len));
                    540:     ((char*)buf)[0]=0;
                    541:     return (0);
                    542: }
                    543: 
                    544: static int
                    545: PptpPeerName(Link l, void *buf, size_t buf_len)
                    546: {
                    547:     PptpInfo   const pptp = (PptpInfo) l->info;
                    548: 
                    549:     if (pptp->cinfo.cookie)
                    550:        return(PptpCtrlGetPeerName(&pptp->cinfo, buf, buf_len));
                    551:     ((char*)buf)[0]=0;
                    552:     return (0);
                    553: }
                    554: 
                    555: static int
                    556: PptpSelfAddr(Link l, void *buf, size_t buf_len)
                    557: {
                    558:     PptpInfo   const pptp = (PptpInfo) l->info;
                    559: 
                    560:     if (u_addrtoa(&pptp->self_addr, buf, buf_len))
                    561:        return(0);
                    562:     else
                    563:        return(-1);
                    564: }
                    565: 
                    566: static int
                    567: PptpPeerAddr(Link l, void *buf, size_t buf_len)
                    568: {
                    569:     PptpInfo   const pptp = (PptpInfo) l->info;
                    570: 
                    571:     if (u_addrtoa(&pptp->peer_addr, buf, buf_len))
                    572:        return(0);
                    573:     else
                    574:        return(-1);
                    575: }
                    576: 
                    577: static int
                    578: PptpPeerPort(Link l, void *buf, size_t buf_len)
                    579: {
                    580:     PptpInfo   const pptp = (PptpInfo) l->info;
                    581: 
                    582:     if (snprintf(buf, buf_len, "%d", pptp->peer_port))
                    583:        return(0);
                    584:     else
                    585:        return(-1);
                    586: }
                    587: 
                    588: static int
                    589: PptpPeerMacAddr(Link l, void *buf, size_t buf_len)
                    590: {
                    591:     PptpInfo   const pptp = (PptpInfo) l->info;
                    592: 
                    593:     if (pptp->peer_iface[0]) {
                    594:        snprintf(buf, buf_len, "%02x:%02x:%02x:%02x:%02x:%02x",
                    595:            pptp->peer_mac_addr[0], pptp->peer_mac_addr[1],
                    596:            pptp->peer_mac_addr[2], pptp->peer_mac_addr[3],
                    597:            pptp->peer_mac_addr[4], pptp->peer_mac_addr[5]);
                    598:        return (0);
                    599:     }
                    600:     ((char*)buf)[0]=0;
                    601:     return(0);
                    602: }
                    603: 
                    604: static int
                    605: PptpPeerIface(Link l, void *buf, size_t buf_len)
                    606: {
                    607:     PptpInfo   const pptp = (PptpInfo) l->info;
                    608: 
                    609:     if (pptp->peer_iface[0]) {
                    610:        strlcpy(buf, pptp->peer_iface, buf_len);
                    611:        return (0);
                    612:     }
                    613:     ((char*)buf)[0]=0;
                    614:     return(0);
                    615: }
                    616: 
                    617: static int
                    618: PptpCallingNum(Link l, void *buf, size_t buf_len)
                    619: {
                    620:     PptpInfo   const pptp = (PptpInfo) l->info;
                    621: 
                    622:     strlcpy((char*)buf, pptp->callingnum, buf_len);
                    623:     return(0);
                    624: }
                    625: 
                    626: static int
                    627: PptpCalledNum(Link l, void *buf, size_t buf_len)
                    628: {
                    629:     PptpInfo   const pptp = (PptpInfo) l->info;
                    630: 
                    631:     strlcpy((char*)buf, pptp->callednum, buf_len);
                    632:     return(0);
                    633: }
                    634: 
                    635: /*
                    636:  * PptpStat()
                    637:  */
                    638: 
                    639: void
                    640: PptpStat(Context ctx)
                    641: {
                    642:     PptpInfo   const pptp = (PptpInfo) ctx->lnk->info;
                    643:     char       buf[32];
                    644: 
                    645:     Printf("PPTP configuration:\r\n");
                    646:     Printf("\tSelf addr    : %s",
                    647:        u_addrtoa(&pptp->conf.self_addr, buf, sizeof(buf)));
                    648:     if (pptp->conf.self_port)
                    649:        Printf(", port %u", pptp->conf.self_port);
                    650:     Printf("\r\n");
                    651:     Printf("\tPeer FQDN    : %s\r\n", pptp->conf.fqdn_peer_addr);
                    652:     Printf("\tPeer range   : %s",
                    653:        u_rangetoa(&pptp->conf.peer_addr, buf, sizeof(buf)));
                    654:     if (pptp->conf.peer_port)
                    655:        Printf(", port %u", pptp->conf.peer_port);
                    656:     Printf("\r\n");
                    657:     Printf("\tCalling number: %s\r\n", pptp->conf.callingnum);
                    658:     Printf("\tCalled number: %s\r\n", pptp->conf.callednum);
                    659:     Printf("PPTP options:\r\n");
                    660:     OptStat(ctx, &pptp->conf.options, gConfList);
                    661:     Printf("PPTP status:\r\n");
                    662:     if (ctx->lnk->state != PHYS_STATE_DOWN) {
                    663:        Printf("\tIncoming     : %s\r\n", (pptp->originate?"NO":"YES"));
                    664:        Printf("\tCurrent self : %s",
                    665:            u_addrtoa(&pptp->self_addr, buf, sizeof(buf)));
                    666:        PptpSelfName(ctx->lnk, buf, sizeof(buf));
                    667:        Printf(" (%s)\r\n", buf);
                    668:        Printf("\tCurrent peer : %s, port %u",
                    669:            u_addrtoa(&pptp->peer_addr, buf, sizeof(buf)), pptp->peer_port);
                    670:        PptpPeerName(ctx->lnk, buf, sizeof(buf));
                    671:        Printf(" (%s)\r\n", buf);
                    672:        if (pptp->peer_iface[0]) {
                    673:            Printf("\tCurrent peer : %02x:%02x:%02x:%02x:%02x:%02x at %s\r\n",
                    674:                pptp->peer_mac_addr[0], pptp->peer_mac_addr[1],
                    675:                pptp->peer_mac_addr[2], pptp->peer_mac_addr[3],
                    676:                pptp->peer_mac_addr[4], pptp->peer_mac_addr[5],
                    677:                pptp->peer_iface);
                    678:        }
                    679:        Printf("\tFraming      : %s\r\n", (pptp->sync?"Sync":"Async"));
                    680:        Printf("\tCalling number: %s\r\n", pptp->callingnum);
                    681:        Printf("\tCalled number: %s\r\n", pptp->callednum);
                    682:     }
                    683: }
                    684: 
                    685: /*
                    686:  * PptpResult()
                    687:  *
                    688:  * The control code calls this function to report a PPTP link
                    689:  * being connected, disconnected, or failing to connect.
                    690:  */
                    691: 
                    692: static void
                    693: PptpResult(void *cookie, const char *errmsg, int frameType)
                    694: {
                    695:     PptpInfo   pptp;
                    696:     Link       l;
                    697:     struct sockaddr_dl  hwa;
                    698: 
                    699:     /* It this fake call? */
                    700:     if (!cookie)
                    701:        return;
                    702: 
                    703:     l = (Link)cookie;
                    704:     pptp = (PptpInfo) l->info;
                    705: 
                    706:     switch (l->state) {
                    707:        case PHYS_STATE_CONNECTING:
                    708:            if (!errmsg) {
                    709: 
                    710:                /* Hook up nodes */
                    711:                Log(LG_PHYS, ("[%s] PPTP call successful", l->name));
                    712:                if (PptpHookUp(l) < 0) {
                    713:                    PptpDoClose(l);
                    714:                    /* We should not set state=DOWN as PptpResult() will be called once more */
                    715:                    break;
                    716:                }
                    717: 
                    718:                if (pptp->originate && !pptp->outcall)
                    719:                    (*pptp->cinfo.connected)(pptp->cinfo.cookie, 64000 /*XXX*/ );
                    720: 
                    721:                /* Report UP if there was no error. */
                    722:                if (l->state == PHYS_STATE_CONNECTING) {
                    723:                    if (GetPeerEther(&pptp->peer_addr, &hwa)) {
                    724:                        if_indextoname(hwa.sdl_index, pptp->peer_iface);
                    725:                        memcpy(pptp->peer_mac_addr, LLADDR(&hwa), sizeof(pptp->peer_mac_addr));
                    726:                    };
                    727: 
                    728:                    /* OK */
                    729:                    l->state = PHYS_STATE_UP;
                    730:                    pptp->sync = (frameType&PPTP_FRAMECAP_ASYNC)?0:1;
                    731:                    PhysUp(l);
                    732:                }
                    733:            } else {
                    734:                Log(LG_PHYS, ("[%s] PPTP call failed", l->name));
                    735:                PptpUnhook(l);          /* For the (*connected)() error. */
                    736:                l->state = PHYS_STATE_DOWN;
                    737:                u_addrclear(&pptp->self_addr);
                    738:                u_addrclear(&pptp->peer_addr);
                    739:                pptp->peer_port = 0;
                    740:                pptp->callingnum[0]=0;
                    741:                pptp->callednum[0]=0;
                    742:                pptp->peer_iface[0] = 0;
                    743:                PhysDown(l, STR_CON_FAILED, errmsg);
                    744:            }
                    745:            break;
                    746:        case PHYS_STATE_UP:
                    747:            assert(errmsg);
                    748:            Log(LG_PHYS, ("[%s] PPTP call terminated", l->name));
                    749:            PptpUnhook(l);
                    750:            l->state = PHYS_STATE_DOWN;
                    751:             u_addrclear(&pptp->self_addr);
                    752:            u_addrclear(&pptp->peer_addr);
                    753:            pptp->peer_port = 0;
                    754:            pptp->callingnum[0]=0;
                    755:            pptp->callednum[0]=0;
                    756:            pptp->peer_iface[0] = 0;
                    757:            PhysDown(l, STR_DROPPED, NULL);
                    758:            break;
                    759:        case PHYS_STATE_DOWN:
                    760:            return;
                    761:        default:
                    762:            assert(0);
                    763:     }
                    764: }
                    765: 
                    766: /*
                    767:  * PptpSetLinkInfo()
                    768:  *
                    769:  * Received LinkInfo from peer;
                    770:  */
                    771: 
                    772: void
                    773: PptpSetLinkInfo(void *cookie, u_int32_t sa, u_int32_t ra)
                    774: {
                    775:     Link       l;
                    776: 
                    777:     /* It this fake call? */
                    778:     if (!cookie)
                    779:            return;
                    780: 
                    781:     l = (Link)cookie;
                    782: 
                    783:     if (l->rep != NULL)
                    784:            RepSetAccm(l, sa, ra);
                    785: }
                    786: 
                    787: static int
                    788: PptpTunEQ(struct ghash *g, const void *item1, const void *item2)
                    789: {
                    790:     const struct pptptun *tun1 = item1;
                    791:     const struct pptptun *tun2 = item2;
                    792:     if (u_addrcompare(&tun1->self_addr, &tun2->self_addr) == 0 &&
                    793:        u_addrcompare(&tun1->peer_addr, &tun2->peer_addr) == 0)
                    794:            return (1);
                    795:     return (0);
                    796: }
                    797: 
                    798: static u_int32_t
                    799: PptpTunHash(struct ghash *g, const void *item)
                    800: {
                    801:     const struct pptptun *tun = item;
                    802:     return (u_addrtoid(&tun->self_addr) + u_addrtoid(&tun->peer_addr));
                    803: }
                    804: 
                    805: /*
                    806:  * PptpHookUp()
                    807:  *
                    808:  * Connect the PPTP/GRE node to the PPP node
                    809:  */
                    810: 
                    811: static int
                    812: PptpHookUp(Link l)
                    813: {
                    814:     const PptpInfo             pi = (PptpInfo)l->info;
                    815:     char                       ksockpath[NG_PATHSIZ];
                    816:     char                       pptppath[NG_PATHSIZ];
                    817:     struct ngm_mkpeer          mkp;
                    818:     struct ng_pptpgre_conf     gc;
                    819:     struct sockaddr_storage    self_addr, peer_addr;
                    820:     struct u_addr              u_self_addr, u_peer_addr;
                    821:     union {
                    822:        u_char buf[sizeof(struct ng_ksocket_sockopt) + sizeof(int)];
                    823:        struct ng_ksocket_sockopt ksso;
                    824:     } u;
                    825:     struct ng_ksocket_sockopt *const ksso = &u.ksso;
                    826:     int                csock = -1;
                    827:     char        path[NG_PATHSIZ];
                    828:     char       hook[NG_HOOKSIZ];
                    829:     PptpTun    tun = NULL;
                    830: 
                    831:     /* Get session info */
                    832:     memset(&gc, 0, sizeof(gc));
                    833:     PptpCtrlGetSessionInfo(&pi->cinfo, &u_self_addr,
                    834:        &u_peer_addr, &gc.cid, &gc.peerCid, &gc.recvWin, &gc.peerPpd);
                    835:     pi->cid = gc.cid;
                    836:     
                    837:     u_addrtosockaddr(&u_self_addr, 0, &self_addr);
                    838:     u_addrtosockaddr(&u_peer_addr, 0, &peer_addr);
                    839: 
                    840:     if (!PhysGetUpperHook(l, path, hook)) {
                    841:         Log(LG_PHYS, ("[%s] PPTP: can't get upper hook", l->name));
                    842:         return(-1);
                    843:     }
                    844:     
                    845:     /* Get a temporary netgraph socket node */
                    846:     if (NgMkSockNode(NULL, &csock, NULL) == -1) {
                    847:        Perror("PPTP: NgMkSockNode");
                    848:        return(-1);
                    849:     }
                    850: 
                    851: #ifdef NG_PPTPGRE_HOOK_SESSION_F
                    852:     {
                    853:        struct pptptun tmptun;
                    854:        tmptun.self_addr = u_self_addr;
                    855:        tmptun.peer_addr = u_peer_addr;
                    856:        tun = ghash_get(gPptpTuns, &tmptun);
                    857:     }
                    858: #endif
                    859: 
                    860:     snprintf(pptppath, sizeof(pptppath), "%s.%s", path, hook);
                    861:     if (tun == NULL) {
                    862:        tun = (PptpTun)Malloc(MB_PHYS, sizeof(*tun));
                    863:        tun->self_addr = u_self_addr;
                    864:        tun->peer_addr = u_peer_addr;
                    865:        if (ghash_put(gPptpTuns, tun) == -1) {
                    866:            Perror("[%s] PPTP: ghash_put", l->name);
                    867:            Freee(tun);
                    868:            close(csock);
                    869:            return(-1);
                    870:        }
                    871:     
                    872:        /* Attach PPTP/GRE node to PPP node */
                    873:        strcpy(mkp.type, NG_PPTPGRE_NODE_TYPE);
                    874:        strlcpy(mkp.ourhook, hook, sizeof(mkp.ourhook));
                    875: #ifdef NG_PPTPGRE_HOOK_SESSION_F
                    876:        snprintf(mkp.peerhook, sizeof(mkp.peerhook), NG_PPTPGRE_HOOK_SESSION_F, pi->cid);
                    877: #else
                    878:        strcpy(mkp.peerhook, NG_PPTPGRE_HOOK_UPPER);
                    879: #endif
                    880:        if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
                    881:           NGM_MKPEER, &mkp, sizeof(mkp)) < 0) {
                    882:            Perror("[%s] PPTP: can't attach %s node", l->name, NG_PPTPGRE_NODE_TYPE);
                    883:            ghash_remove(gPptpTuns, tun);
                    884:            Freee(tun);
                    885:            close(csock);
                    886:            return(-1);
                    887:        }
                    888: 
                    889:        /* Get pptpgre node ID */
                    890:        if ((tun->node_id = NgGetNodeID(csock, pptppath)) == 0) {
                    891:            Perror("[%s] Cannot get %s node id", l->name, NG_PPTPGRE_NODE_TYPE);
                    892:            ghash_remove(gPptpTuns, tun);
                    893:            Freee(tun);
                    894:            close(csock);
                    895:            return(-1);
                    896:        };
                    897:        tun->refs++;
                    898:        pi->tun = tun;
                    899: 
                    900:        /* Attach ksocket node to PPTP/GRE node */
                    901:        strcpy(mkp.type, NG_KSOCKET_NODE_TYPE);
                    902:        strcpy(mkp.ourhook, NG_PPTPGRE_HOOK_LOWER);
                    903:        if (u_self_addr.family==AF_INET6) {
                    904:            //ng_ksocket doesn't support inet6 name
                    905:            snprintf(mkp.peerhook, sizeof(mkp.peerhook), "%d/%d/%d", PF_INET6, SOCK_RAW, IPPROTO_GRE); 
                    906:        } else {
                    907:            snprintf(mkp.peerhook, sizeof(mkp.peerhook), "inet/raw/gre");
                    908:        }
                    909:        if (NgSendMsg(csock, pptppath, NGM_GENERIC_COOKIE,
                    910:          NGM_MKPEER, &mkp, sizeof(mkp)) < 0) {
                    911:            Perror("[%s] PPTP: can't attach %s node", l->name, NG_KSOCKET_NODE_TYPE);
                    912:            close(csock);
                    913:            return(-1);
                    914:        }
                    915:        snprintf(ksockpath, sizeof(ksockpath),
                    916:            "%s.%s", pptppath, NG_PPTPGRE_HOOK_LOWER);
                    917: 
                    918:        /* increase recvspace to avoid packet loss due to very small GRE recv buffer. */
                    919:        ksso->level=SOL_SOCKET;
                    920:        ksso->name=SO_RCVBUF;
                    921:        ((int *)(ksso->value))[0]=48*1024;
                    922:        if (NgSendMsg(csock, ksockpath, NGM_KSOCKET_COOKIE,
                    923:            NGM_KSOCKET_SETOPT, &u, sizeof(u)) < 0) {
                    924:                Perror("[%s] PPTP: can't setsockopt %s node",
                    925:                    l->name, NG_KSOCKET_NODE_TYPE);
                    926:        }
                    927: 
                    928:        /* Bind ksocket socket to local IP address */
                    929:        if (NgSendMsg(csock, ksockpath, NGM_KSOCKET_COOKIE,
                    930:           NGM_KSOCKET_BIND, &self_addr, self_addr.ss_len) < 0) {
                    931:            Perror("[%s] PPTP: can't bind() %s node", l->name, NG_KSOCKET_NODE_TYPE);
                    932:            close(csock);
                    933:            return(-1);
                    934:        }
                    935: 
                    936:        /* Connect ksocket socket to remote IP address */
                    937:        if (NgSendMsg(csock, ksockpath, NGM_KSOCKET_COOKIE,
                    938:          NGM_KSOCKET_CONNECT, &peer_addr, peer_addr.ss_len) < 0 &&
                    939:          errno != EINPROGRESS) {       /* happens in -current (weird) */
                    940:            Perror("[%s] PPTP: can't connect() %s node",
                    941:                l->name, NG_KSOCKET_NODE_TYPE);
                    942:            close(csock);
                    943:            return(-1);
                    944:         }
                    945: #ifdef NG_PPTPGRE_HOOK_SESSION_F
                    946:     } else {
                    947:        struct ngm_connect      cn;
                    948:        snprintf(cn.path, sizeof(cn.path), "[%x]:", tun->node_id);
                    949:        strlcpy(cn.ourhook, hook, sizeof(mkp.ourhook));
                    950:        snprintf(cn.peerhook, sizeof(mkp.peerhook), NG_PPTPGRE_HOOK_SESSION_F, pi->cid);
                    951:        if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
                    952:           NGM_CONNECT, &cn, sizeof(cn)) < 0) {
                    953:            Perror("[%s] PPTP: can't connect to %s node",
                    954:                l->name, NG_PPTPGRE_NODE_TYPE);
                    955:            close(csock);
                    956:            return(-1);
                    957:        }
                    958:        tun->refs++;
                    959:        pi->tun = tun;
                    960: #endif
                    961:     }
                    962: 
                    963:     /* Configure PPTP/GRE node */
                    964:     gc.enabled = 1;
                    965:     gc.enableDelayedAck = Enabled(&pi->conf.options, PPTP_CONF_DELAYED_ACK);
                    966:     gc.enableAlwaysAck = Enabled(&pi->conf.options, PPTP_CONF_ALWAYS_ACK);
                    967: #if NGM_PPTPGRE_COOKIE >= 1082548365
                    968:     gc.enableWindowing = Enabled(&pi->conf.options, PPTP_CONF_WINDOWING);
                    969: #endif
                    970: 
                    971:     if (NgSendMsg(csock, pptppath, NGM_PPTPGRE_COOKIE,
                    972:       NGM_PPTPGRE_SET_CONFIG, &gc, sizeof(gc)) < 0) {
                    973:        Perror("[%s] PPTP: can't config %s node", l->name, NG_PPTPGRE_NODE_TYPE);
                    974:        close(csock);
                    975:        return(-1);
                    976:     }
                    977:   
                    978:     close(csock);
                    979: 
                    980:     return(0);
                    981: }
                    982: 
                    983: /*
                    984:  * PptpIncoming()
                    985:  *
                    986:  * The control code calls this function to report that some
                    987:  * remote PPTP client has asked us if we will accept an incoming
                    988:  * call relayed over PPTP.
                    989:  */
                    990: 
                    991: static struct pptplinkinfo
                    992: PptpIncoming(struct pptpctrlinfo *cinfo,
                    993:        struct u_addr *self, struct u_addr *peer, in_port_t port, int bearType,
                    994:        const char *callingNum,
                    995:        const char *calledNum,
                    996:        const char *subAddress)
                    997: {
                    998:     return(PptpPeerCall(cinfo, self, peer, port, TRUE, callingNum, calledNum, subAddress));
                    999: }
                   1000: 
                   1001: /*
                   1002:  * PptpOutgoing()
                   1003:  *
                   1004:  * The control code calls this function to report that some
                   1005:  * remote PPTP client has asked us if we will dial out to some
                   1006:  * phone number. We don't actually do this, but some clients
                   1007:  * initiate their connections as outgoing calls for some reason.
                   1008:  */
                   1009: 
                   1010: static struct pptplinkinfo
                   1011: PptpOutgoing(struct pptpctrlinfo *cinfo,
                   1012:        struct u_addr *self, struct u_addr *peer, in_port_t port, int bearType,
                   1013:        int frameType, int minBps, int maxBps,
                   1014:        const char *calledNum, const char *subAddress)
                   1015: {
                   1016:     return(PptpPeerCall(cinfo, self, peer, port, FALSE, "", calledNum, subAddress));
                   1017: }
                   1018: 
                   1019: /*
                   1020:  * PptpPeerCall()
                   1021:  *
                   1022:  * Peer has initiated a call (either incoming or outgoing; either
                   1023:  * way it's the same to us). If we have an available link that may
                   1024:  * accept calls from the peer's IP addresss and port, then say yes.
                   1025:  */
                   1026: 
                   1027: static struct pptplinkinfo
                   1028: PptpPeerCall(struct pptpctrlinfo *cinfo,
                   1029:        struct u_addr *self, struct u_addr *peer, in_port_t port, int incoming,
                   1030:        const char *callingNum,
                   1031:        const char *calledNum,
                   1032:        const char *subAddress)
                   1033: {
                   1034:     struct pptplinkinfo        linfo;
                   1035:     Link               l = NULL;
                   1036:     PptpInfo           pi = NULL;
                   1037:     int                        k;
                   1038: 
                   1039:     memset(&linfo, 0, sizeof(linfo));
                   1040: 
                   1041:     linfo.cookie = NULL;
                   1042:     linfo.result = PptpResult;
                   1043:     linfo.setLinkInfo = PptpSetLinkInfo;
                   1044:     linfo.cancel = PptpCancel;
                   1045: 
                   1046:     if (gShutdownInProgress) {
                   1047:        Log(LG_PHYS, ("Shutdown sequence in progress, ignoring request."));
                   1048:        return(linfo);
                   1049:     }
                   1050: 
                   1051:     if (OVERLOAD()) {
                   1052:        Log(LG_PHYS, ("Daemon overloaded, ignoring request."));
                   1053:        return(linfo);
                   1054:     }
                   1055: 
                   1056:     /* Find a suitable link; prefer the link best matching peer's IP address */
                   1057:     for (k = 0; k < gNumLinks; k++) {
                   1058:        Link l2;
                   1059:        PptpInfo pi2;
                   1060: 
                   1061:        if (!gLinks[k] || gLinks[k]->type != &gPptpPhysType)
                   1062:                continue;
                   1063: 
                   1064:        l2 = gLinks[k];
                   1065:        pi2 = (PptpInfo)l2->info;
                   1066: 
                   1067:        /* See if link is feasible */
                   1068:        if ((!PhysIsBusy(l2)) &&
                   1069:            Enabled(&l2->conf.options, LINK_CONF_INCOMING) &&
                   1070:            (u_addrempty(&pi2->conf.self_addr) || (u_addrcompare(&pi2->conf.self_addr, self) == 0)) &&
                   1071:            IpAddrInRange(&pi2->conf.peer_addr, peer) &&
                   1072:            (!pi2->conf.peer_port || pi2->conf.peer_port == port)) {
                   1073: 
                   1074:                /* Link is feasible; now see if it's preferable */
                   1075:                if (!pi || pi2->conf.peer_addr.width > pi->conf.peer_addr.width) {
                   1076:                        l = l2;
                   1077:                        pi = pi2;
                   1078:                        if (u_rangehost(&pi->conf.peer_addr)) {
                   1079:                                break;  /* Nothing could be better */
                   1080:                        }
                   1081:                }
                   1082:        }
                   1083:     }
                   1084: 
                   1085:     if (l != NULL && l->tmpl)
                   1086:         l = LinkInst(l, NULL, 0, 0);
                   1087: 
                   1088:     /* If no link is suitable, can't take the call */
                   1089:     if (l == NULL) {
                   1090:        Log(LG_PHYS, ("No free PPTP link with requested parameters "
                   1091:            "was found"));
                   1092:        return(linfo);
                   1093:     }
                   1094:     pi = (PptpInfo)l->info;
                   1095: 
                   1096:     Log(LG_PHYS, ("[%s] Accepting PPTP connection", l->name));
                   1097: 
                   1098:     /* Got one */
                   1099:     linfo.cookie = l;
                   1100:     l->state = PHYS_STATE_CONNECTING;
                   1101:     pi->cinfo = *cinfo;
                   1102:     pi->originate = FALSE;
                   1103:     pi->outcall = !incoming;
                   1104:     pi->sync = 1;
                   1105:     pi->self_addr = *self;
                   1106:     pi->peer_addr = *peer;
                   1107:     pi->peer_port = port;
                   1108:     strlcpy(pi->callingnum, callingNum, sizeof(pi->callingnum));
                   1109:     strlcpy(pi->callednum, calledNum, sizeof(pi->callednum));
                   1110: 
                   1111:     PhysIncoming(l);
                   1112:     return(linfo);
                   1113: }
                   1114: 
                   1115: /*
                   1116:  * PptpCancel()
                   1117:  *
                   1118:  * The control code calls this function to cancel a
                   1119:  * local outgoing call in progress.
                   1120:  */
                   1121: 
                   1122: static void
                   1123: PptpCancel(void *cookie)
                   1124: {
                   1125:     PptpInfo   pi;
                   1126:     Link       l;
                   1127: 
                   1128:     /* It this fake call? */
                   1129:     if (!cookie)
                   1130:        return;
                   1131: 
                   1132:     l = (Link)cookie;
                   1133:     pi = (PptpInfo) l->info;
                   1134: 
                   1135:     Log(LG_PHYS, ("[%s] PPTP call cancelled in state %s",
                   1136:        l->name, gPhysStateNames[l->state]));
                   1137:     if (l->state == PHYS_STATE_DOWN)
                   1138:        return;
                   1139:     l->state = PHYS_STATE_DOWN;
                   1140:     u_addrclear(&pi->peer_addr);
                   1141:     pi->peer_port = 0;
                   1142:     pi->callingnum[0]=0;
                   1143:     pi->callednum[0]=0;
                   1144:     pi->peer_iface[0] = 0;
                   1145:     PhysDown(l, STR_CON_FAILED0, NULL);
                   1146: }
                   1147: 
                   1148: /*
                   1149:  * PptpListenUpdate()
                   1150:  */
                   1151: 
                   1152: static void
                   1153: PptpListenUpdate(Link l)
                   1154: {
                   1155:     PptpInfo   pi = (PptpInfo) l->info;
                   1156: 
                   1157:     if (pi->listener == NULL) {
                   1158:        if (Enabled(&l->conf.options, LINK_CONF_INCOMING)) {
                   1159:            /* Set up listening for incoming connections */
                   1160:            if ((pi->listener = 
                   1161:                PptpCtrlListen(&pi->conf.self_addr, pi->conf.self_port))
                   1162:                    == NULL) {
                   1163:                Log(LG_ERR, ("PPTP: Error, can't listen for connection!"));
                   1164:            }
                   1165:        }
                   1166:     } else {
                   1167:        if (!Enabled(&l->conf.options, LINK_CONF_INCOMING)) {
                   1168:            PptpCtrlUnListen(pi->listener);
                   1169:            pi->listener = NULL;
                   1170:        }
                   1171:     }
                   1172: }
                   1173: 
                   1174: /*
                   1175:  * PptpSetCommand()
                   1176:  */
                   1177: 
                   1178: static int
                   1179: PptpSetCommand(Context ctx, int ac, char *av[], void *arg)
                   1180: {
                   1181:     PptpInfo           const pi = (PptpInfo) ctx->lnk->info;
                   1182:     char               **fqdn_peer_addr = &pi->conf.fqdn_peer_addr;
                   1183:     struct u_range     rng;
                   1184:     int                        port;
                   1185: 
                   1186:     switch ((intptr_t)arg) {
                   1187:        case SET_SELFADDR:
                   1188:        case SET_PEERADDR:
                   1189:            if ((ac == 1 || ac == 2) && (intptr_t)arg == SET_PEERADDR) {
                   1190:                if (*fqdn_peer_addr)
                   1191:                    Freee(*fqdn_peer_addr);
                   1192:                *fqdn_peer_addr = Mstrdup(MB_PHYS, av[0]);
                   1193:            }
                   1194:            if (ac < 1 || ac > 2 || !ParseRange(av[0], &rng, ALLOW_IPV4|ALLOW_IPV6))
                   1195:                return(-1);
                   1196:            if (ac > 1) {
                   1197:                if ((port = atoi(av[1])) < 0 || port > 0xffff)
                   1198:                    return(-1);
                   1199:            } else {
                   1200:                port = 0;
                   1201:            }
                   1202:            if ((intptr_t)arg == SET_SELFADDR) {
                   1203:                pi->conf.self_addr = rng.addr;
                   1204:                pi->conf.self_port = port;
                   1205:            } else {
                   1206:                pi->conf.peer_addr = rng;
                   1207:                pi->conf.peer_port = port;
                   1208:            }
                   1209:            break;
                   1210:        case SET_CALLINGNUM:
                   1211:            if (ac != 1)
                   1212:                return(-1);
                   1213:            strlcpy(pi->conf.callingnum, av[0], sizeof(pi->conf.callingnum));
                   1214:            break;
                   1215:        case SET_CALLEDNUM:
                   1216:            if (ac != 1)
                   1217:                return(-1);
                   1218:            strlcpy(pi->conf.callednum, av[0], sizeof(pi->conf.callednum));
                   1219:            break;
                   1220:        case SET_ENABLE:
                   1221:            EnableCommand(ac, av, &pi->conf.options, gConfList);
                   1222:            PptpListenUpdate(ctx->lnk);
                   1223:            break;
                   1224:        case SET_DISABLE:
                   1225:            DisableCommand(ac, av, &pi->conf.options, gConfList);
                   1226:            PptpListenUpdate(ctx->lnk);
                   1227:            break;
                   1228:        default:
                   1229:            assert(0);
                   1230:     }
                   1231:     return(0);
                   1232: }
                   1233: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>