version 1.1.1.1, 2012/02/21 23:32:47
|
version 1.1.1.3, 2021/03/17 00:39:23
|
Line 63
|
Line 63
|
#define PPTP_FIND_CHAN_PNS_CID 3 /* match field vs. PNS cid */ |
#define PPTP_FIND_CHAN_PNS_CID 3 /* match field vs. PNS cid */ |
#define PPTP_FIND_CHAN_PAC_CID 4 /* match field vs. PAC cid */ |
#define PPTP_FIND_CHAN_PAC_CID 4 /* match field vs. PAC cid */ |
|
|
/* Total info about a message type (except field layout) */ |
|
struct pptpmsginfo { |
|
const char *name; /* name for this message type */ |
|
void (*handler)(); /* message handler function */ |
|
u_char isReply; /* this is always a reply message */ |
|
u_char length; /* length of message (sans header) */ |
|
u_short states; /* states which admit this message */ |
|
struct pptpchanid match; /* how to find corresponding channel */ |
|
struct pptpreqrep reqrep; /* what kind of reply we expect */ |
|
}; |
|
typedef const struct pptpmsginfo *PptpMsgInfo; |
|
|
|
/* Receive window size XXX */ |
/* Receive window size XXX */ |
#define PPTP_RECV_WIN 16 |
#define PPTP_RECV_WIN 16 |
Line 135
|
Line 124
|
char peer_name[MAXHOSTNAMELEN]; /* remote hostname */ |
char peer_name[MAXHOSTNAMELEN]; /* remote hostname */ |
}; |
}; |
typedef struct pptpctrl *PptpCtrl; |
typedef struct pptpctrl *PptpCtrl; |
|
typedef void (*PptpHandler)(PptpCtrl, void *); |
|
|
|
/* Total info about a message type (except field layout) */ |
|
struct pptpmsginfo { |
|
const char *name; /* name for this message type */ |
|
PptpHandler handler; /* message handler function */ |
|
u_char isReply; /* this is always a reply message */ |
|
u_char length; /* length of message (sans header) */ |
|
u_short states; /* states which admit this message */ |
|
struct pptpchanid match; /* how to find corresponding channel */ |
|
struct pptpreqrep reqrep; /* what kind of reply we expect */ |
|
}; |
|
typedef const struct pptpmsginfo *PptpMsgInfo; |
|
|
struct pptplis { |
struct pptplis { |
struct u_addr self_addr; /* local IP address */ |
struct u_addr self_addr; /* local IP address */ |
in_port_t self_port; |
in_port_t self_port; |
Line 149
|
Line 151
|
/* Our physical channel ID */ |
/* Our physical channel ID */ |
#define PHYS_CHAN(ch) (((ch)->ctrl->id << 16) | (ch)->id) |
#define PHYS_CHAN(ch) (((ch)->ctrl->id << 16) | (ch)->id) |
|
|
int PptpsStat(Context ctx, int ac, char *av[], void *arg); | int PptpsStat(Context ctx, int ac, const char *const av[], const void *arg); |
|
|
/* |
/* |
* INTERNAL FUNCTIONS |
* INTERNAL FUNCTIONS |
Line 303
|
Line 305
|
static const struct pptpmsginfo gPptpMsgInfo[PPTP_MAX_CTRL_TYPE] = { |
static const struct pptpmsginfo gPptpMsgInfo[PPTP_MAX_CTRL_TYPE] = { |
{ "PptpMsgHead", NULL, /* placeholder */ |
{ "PptpMsgHead", NULL, /* placeholder */ |
FALSE, sizeof(struct pptpMsgHead), |
FALSE, sizeof(struct pptpMsgHead), |
|
0, { 0, 0, NULL, NULL }, { 0, 0, 0 }, |
}, |
}, |
{ "StartCtrlConnRequest", PptpStartCtrlConnRequest, | { "StartCtrlConnRequest", (PptpHandler) PptpStartCtrlConnRequest, |
FALSE, sizeof(struct pptpStartCtrlConnRequest), |
FALSE, sizeof(struct pptpStartCtrlConnRequest), |
CL(IDLE), |
CL(IDLE), |
{ 0, 0 }, /* no associated channel */ | { 0, 0, NULL, NULL }, /* no associated channel */ |
{ PPTP_StartCtrlConnReply, TRUE, PPTP_DFL_REPLY_TIME }, |
{ PPTP_StartCtrlConnReply, TRUE, PPTP_DFL_REPLY_TIME }, |
}, |
}, |
{ "StartCtrlConnReply", PptpStartCtrlConnReply, | { "StartCtrlConnReply", (PptpHandler) PptpStartCtrlConnReply, |
TRUE, sizeof(struct pptpStartCtrlConnReply), |
TRUE, sizeof(struct pptpStartCtrlConnReply), |
CL(WAIT_CTL_REPLY), |
CL(WAIT_CTL_REPLY), |
{ 0, 0 }, /* no associated channel */ | { 0, 0, NULL, NULL }, /* no associated channel */ |
{ 0 }, /* no reply expected */ | { 0, 0, 0 }, /* no reply expected */ |
}, |
}, |
{ "StopCtrlConnRequest", PptpStopCtrlConnRequest, | { "StopCtrlConnRequest", (PptpHandler) PptpStopCtrlConnRequest, |
FALSE, sizeof(struct pptpStopCtrlConnRequest), |
FALSE, sizeof(struct pptpStopCtrlConnRequest), |
CL(WAIT_CTL_REPLY)|CL(WAIT_STOP_REPLY)|CL(ESTABLISHED), |
CL(WAIT_CTL_REPLY)|CL(WAIT_STOP_REPLY)|CL(ESTABLISHED), |
{ 0, 0 }, /* no associated channel */ | { 0, 0, NULL, NULL }, /* no associated channel */ |
{ PPTP_StopCtrlConnReply, TRUE, PPTP_STOPCCR_REPLY_TIME }, |
{ PPTP_StopCtrlConnReply, TRUE, PPTP_STOPCCR_REPLY_TIME }, |
}, |
}, |
{ "StopCtrlConnReply", PptpStopCtrlConnReply, | { "StopCtrlConnReply", (PptpHandler) PptpStopCtrlConnReply, |
TRUE, sizeof(struct pptpStopCtrlConnReply), |
TRUE, sizeof(struct pptpStopCtrlConnReply), |
CL(WAIT_STOP_REPLY), |
CL(WAIT_STOP_REPLY), |
{ 0, 0 }, /* no associated channel */ | { 0, 0, NULL, NULL }, /* no associated channel */ |
{ 0 }, /* no reply expected */ | { 0, 0, 0 }, /* no reply expected */ |
}, |
}, |
{ "EchoRequest", PptpEchoRequest, | { "EchoRequest", (PptpHandler) PptpEchoRequest, |
FALSE, sizeof(struct pptpEchoRequest), |
FALSE, sizeof(struct pptpEchoRequest), |
CL(ESTABLISHED), |
CL(ESTABLISHED), |
{ 0, 0 }, /* no associated channel */ | { 0, 0, NULL, NULL }, /* no associated channel */ |
{ PPTP_EchoReply, TRUE, PPTP_DFL_REPLY_TIME }, |
{ PPTP_EchoReply, TRUE, PPTP_DFL_REPLY_TIME }, |
}, |
}, |
{ "EchoReply", PptpEchoReply, | { "EchoReply", (PptpHandler) PptpEchoReply, |
TRUE, sizeof(struct pptpEchoReply), |
TRUE, sizeof(struct pptpEchoReply), |
CL(ESTABLISHED), |
CL(ESTABLISHED), |
{ 0, 0 }, /* no associated channel */ | { 0, 0, NULL, NULL }, /* no associated channel */ |
{ 0 }, /* no reply expected */ | { 0, 0, 0 }, /* no reply expected */ |
}, |
}, |
{ "OutCallRequest", PptpOutCallRequest, | { "OutCallRequest", (PptpHandler) PptpOutCallRequest, |
FALSE, sizeof(struct pptpOutCallRequest), |
FALSE, sizeof(struct pptpOutCallRequest), |
CL(ESTABLISHED), |
CL(ESTABLISHED), |
{ 0, PPTP_FIND_CHAN_MY_CID, NULL, "cid" }, |
{ 0, PPTP_FIND_CHAN_MY_CID, NULL, "cid" }, |
{ PPTP_OutCallReply, TRUE, PPTP_OUTCALLREQ_REPLY_TIME }, |
{ PPTP_OutCallReply, TRUE, PPTP_OUTCALLREQ_REPLY_TIME }, |
}, |
}, |
{ "OutCallReply", PptpOutCallReply, | { "OutCallReply", (PptpHandler) PptpOutCallReply, |
TRUE, sizeof(struct pptpOutCallReply), |
TRUE, sizeof(struct pptpOutCallReply), |
CH(WAIT_OUT_REPLY), |
CH(WAIT_OUT_REPLY), |
{ PPTP_FIND_CHAN_MY_CID, PPTP_FIND_CHAN_MY_CID, "peerCid", "cid" }, |
{ PPTP_FIND_CHAN_MY_CID, PPTP_FIND_CHAN_MY_CID, "peerCid", "cid" }, |
{ 0 }, /* no reply expected */ | { 0, 0, 0 }, /* no reply expected */ |
}, |
}, |
{ "InCallRequest", PptpInCallRequest, | { "InCallRequest", (PptpHandler) PptpInCallRequest, |
FALSE, sizeof(struct pptpInCallRequest), |
FALSE, sizeof(struct pptpInCallRequest), |
CL(ESTABLISHED), |
CL(ESTABLISHED), |
{ 0, PPTP_FIND_CHAN_MY_CID, NULL, "cid" }, |
{ 0, PPTP_FIND_CHAN_MY_CID, NULL, "cid" }, |
{ PPTP_InCallReply, FALSE, PPTP_DFL_REPLY_TIME }, |
{ PPTP_InCallReply, FALSE, PPTP_DFL_REPLY_TIME }, |
}, |
}, |
{ "InCallReply", PptpInCallReply, | { "InCallReply", (PptpHandler) PptpInCallReply, |
TRUE, sizeof(struct pptpInCallReply), |
TRUE, sizeof(struct pptpInCallReply), |
CH(WAIT_IN_REPLY), |
CH(WAIT_IN_REPLY), |
{ PPTP_FIND_CHAN_MY_CID, PPTP_FIND_CHAN_MY_CID, "peerCid", "cid" }, |
{ PPTP_FIND_CHAN_MY_CID, PPTP_FIND_CHAN_MY_CID, "peerCid", "cid" }, |
{ PPTP_InCallConn, FALSE, PPTP_INCALLREP_REPLY_TIME }, |
{ PPTP_InCallConn, FALSE, PPTP_INCALLREP_REPLY_TIME }, |
}, |
}, |
{ "InCallConn", PptpInCallConn, | { "InCallConn", (PptpHandler) PptpInCallConn, |
TRUE, sizeof(struct pptpInCallConn), |
TRUE, sizeof(struct pptpInCallConn), |
CH(WAIT_CONNECT), |
CH(WAIT_CONNECT), |
{ PPTP_FIND_CHAN_MY_CID, PPTP_FIND_CHAN_PEER_CID, "peerCid", "peerCid" }, |
{ PPTP_FIND_CHAN_MY_CID, PPTP_FIND_CHAN_PEER_CID, "peerCid", "peerCid" }, |
{ 0 }, /* no reply expected */ | { 0, 0, 0 }, /* no reply expected */ |
}, |
}, |
{ "CallClearRequest", PptpCallClearRequest, | { "CallClearRequest", (PptpHandler) PptpCallClearRequest, |
FALSE, sizeof(struct pptpCallClearRequest), |
FALSE, sizeof(struct pptpCallClearRequest), |
CH(WAIT_IN_REPLY)|CH(WAIT_ANSWER)|CH(ESTABLISHED), |
CH(WAIT_IN_REPLY)|CH(WAIT_ANSWER)|CH(ESTABLISHED), |
{ PPTP_FIND_CHAN_PNS_CID, PPTP_FIND_CHAN_PNS_CID, "cid", "cid" }, |
{ PPTP_FIND_CHAN_PNS_CID, PPTP_FIND_CHAN_PNS_CID, "cid", "cid" }, |
{ PPTP_CallDiscNotify, TRUE, PPTP_DFL_REPLY_TIME }, |
{ PPTP_CallDiscNotify, TRUE, PPTP_DFL_REPLY_TIME }, |
}, |
}, |
{ "CallDiscNotify", PptpCallDiscNotify, | { "CallDiscNotify", (PptpHandler) PptpCallDiscNotify, |
FALSE, sizeof(struct pptpCallDiscNotify), |
FALSE, sizeof(struct pptpCallDiscNotify), |
CH(WAIT_OUT_REPLY)|CH(WAIT_CONNECT)|CH(WAIT_DISCONNECT)|CH(ESTABLISHED), |
CH(WAIT_OUT_REPLY)|CH(WAIT_CONNECT)|CH(WAIT_DISCONNECT)|CH(ESTABLISHED), |
{ PPTP_FIND_CHAN_PAC_CID, PPTP_FIND_CHAN_PAC_CID, "cid", "cid" }, |
{ PPTP_FIND_CHAN_PAC_CID, PPTP_FIND_CHAN_PAC_CID, "cid", "cid" }, |
{ 0 }, /* no reply expected */ | { 0, 0, 0 }, /* no reply expected */ |
}, |
}, |
{ "WanErrorNotify", PptpWanErrorNotify, | { "WanErrorNotify", (PptpHandler) PptpWanErrorNotify, |
FALSE, sizeof(struct pptpWanErrorNotify), |
FALSE, sizeof(struct pptpWanErrorNotify), |
CH(ESTABLISHED), |
CH(ESTABLISHED), |
{ PPTP_FIND_CHAN_PNS_CID, PPTP_FIND_CHAN_PNS_CID, "cid", "cid" }, |
{ PPTP_FIND_CHAN_PNS_CID, PPTP_FIND_CHAN_PNS_CID, "cid", "cid" }, |
{ 0 }, /* no reply expected */ | { 0, 0, 0 }, /* no reply expected */ |
}, |
}, |
{ "SetLinkInfo", PptpSetLinkInfo, | { "SetLinkInfo", (PptpHandler) PptpSetLinkInfo, |
FALSE, sizeof(struct pptpSetLinkInfo), |
FALSE, sizeof(struct pptpSetLinkInfo), |
CH(ESTABLISHED), |
CH(ESTABLISHED), |
{ PPTP_FIND_CHAN_PAC_CID, PPTP_FIND_CHAN_PAC_CID, "cid", "cid" }, |
{ PPTP_FIND_CHAN_PAC_CID, PPTP_FIND_CHAN_PAC_CID, "cid", "cid" }, |
{ 0 }, /* no reply expected */ | { 0, 0, 0 }, /* no reply expected */ |
}, |
}, |
}; |
}; |
|
|
Line 542 PptpCtrlListen(struct u_addr *ip, in_port_t port)
|
Line 545 PptpCtrlListen(struct u_addr *ip, in_port_t port)
|
|
|
/* See if we're already have a listener matching this address and port */ |
/* See if we're already have a listener matching this address and port */ |
for (k = 0; k < gNumPptpLis; k++) { |
for (k = 0; k < gNumPptpLis; k++) { |
PptpLis const l = gPptpLis[k]; | PptpLis const m = gPptpLis[k]; |
|
|
if (l != NULL | if (m != NULL |
&& (!u_addrcompare (&l->self_addr, ip)) | && (!u_addrcompare (&m->self_addr, ip)) |
&& l->self_port == port) { | && m->self_port == port) { |
l->ref++; | m->ref++; |
return(l); | return(m); |
} |
} |
} |
} |
|
|
Line 623 PptpCtrlListenRetry(int type, void *cookie)
|
Line 626 PptpCtrlListenRetry(int type, void *cookie)
|
{ |
{ |
PptpLis const l = (PptpLis)cookie; |
PptpLis const l = (PptpLis)cookie; |
|
|
|
(void)type; |
if ((l->sock = TcpGetListenPort(&l->self_addr, l->self_port, FALSE)) < 0) { |
if ((l->sock = TcpGetListenPort(&l->self_addr, l->self_port, FALSE)) < 0) { |
EventRegister(&l->retry, EVENT_TIMEOUT, PPTP_LISTEN_RETRY * 1000, |
EventRegister(&l->retry, EVENT_TIMEOUT, PPTP_LISTEN_RETRY * 1000, |
0, PptpCtrlListenRetry, l); |
0, PptpCtrlListenRetry, l); |
Line 690 PptpCtrlOrigCall(int incoming, struct pptpctrlinfo *ci
|
Line 694 PptpCtrlOrigCall(int incoming, struct pptpctrlinfo *ci
|
/* Init */ |
/* Init */ |
assert(gInitialized); |
assert(gInitialized); |
port = port ? port : PPTP_PORT; |
port = port ? port : PPTP_PORT; |
memset(cinfo, 0, sizeof(cinfo)); | memset(cinfo, 0, sizeof(*cinfo)); |
|
|
/* Find/create control block */ |
/* Find/create control block */ |
if ((c = PptpCtrlGetCtrl(TRUE, locip, ip, port, |
if ((c = PptpCtrlGetCtrl(TRUE, locip, ip, port, |
Line 805 PptpCtrlListenEvent(int type, void *cookie)
|
Line 809 PptpCtrlListenEvent(int type, void *cookie)
|
char buf[48], buf2[48]; |
char buf[48], buf2[48]; |
socklen_t addrLen; |
socklen_t addrLen; |
|
|
|
(void)type; |
/* Accept connection */ |
/* Accept connection */ |
if ((sock = TcpAcceptConnection(l->sock, &peerst, FALSE)) < 0) |
if ((sock = TcpAcceptConnection(l->sock, &peerst, FALSE)) < 0) |
return; |
return; |
Line 851 PptpCtrlConnEvent(int type, void *cookie)
|
Line 856 PptpCtrlConnEvent(int type, void *cookie)
|
socklen_t addrLen = sizeof(addr); |
socklen_t addrLen = sizeof(addr); |
char buf[48]; |
char buf[48]; |
|
|
|
(void)type; |
|
|
/* Get event */ |
/* Get event */ |
assert(c->state == PPTP_CTRL_ST_IDLE); |
assert(c->state == PPTP_CTRL_ST_IDLE); |
|
|
Line 965 PptpCtrlReadCtrl(int type, void *cookie)
|
Line 972 PptpCtrlReadCtrl(int type, void *cookie)
|
PptpMsgHead const hdr = &c->frame.hdr; |
PptpMsgHead const hdr = &c->frame.hdr; |
int nread; |
int nread; |
|
|
|
(void)type; |
|
|
/* Figure how much to read and read it */ |
/* Figure how much to read and read it */ |
nread = (c->flen < sizeof(*hdr) ? sizeof(*hdr) : hdr->length) - c->flen; |
nread = (c->flen < sizeof(*hdr) ? sizeof(*hdr) : hdr->length) - c->flen; |
if ((nread = read(c->csock, c->frame.buf + c->flen, nread)) <= 0) { |
if ((nread = read(c->csock, c->frame.buf + c->flen, nread)) <= 0) { |
Line 1194 PptpCtrlGetCtrl(int orig, struct u_addr *self_addr,
|
Line 1203 PptpCtrlGetCtrl(int orig, struct u_addr *self_addr,
|
if (orig) { |
if (orig) { |
/* See if we're already have a control block matching this address and port */ |
/* See if we're already have a control block matching this address and port */ |
for (k = 0; k < gNumPptpCtrl; k++) { |
for (k = 0; k < gNumPptpCtrl; k++) { |
PptpCtrl const c = gPptpCtrl[k]; | PptpCtrl const d = gPptpCtrl[k]; |
|
|
if (c != NULL | if (d != NULL |
&& (c->active_sessions < gPPTPtunlimit) | && (d->active_sessions < gPPTPtunlimit) |
&& (u_addrcompare(&c->peer_addr, peer_addr) == 0) | && (u_addrcompare(&d->peer_addr, peer_addr) == 0) |
&& (c->peer_port == peer_port || c->orig != orig) | && (d->peer_port == peer_port || d->orig != orig) |
&& (u_addrempty(self_addr) || |
&& (u_addrempty(self_addr) || |
(u_addrcompare(&c->self_addr, self_addr) == 0))) { | (u_addrcompare(&d->self_addr, self_addr) == 0))) { |
return(c); | return(d); |
} |
} |
} |
} |
} |
} |
Line 2098 PptpStopCtrlConnRequest(PptpCtrl c, struct pptpStopCtr
|
Line 2107 PptpStopCtrlConnRequest(PptpCtrl c, struct pptpStopCtr
|
static void |
static void |
PptpStopCtrlConnReply(PptpCtrl c, struct pptpStopCtrlConnReply *rep) |
PptpStopCtrlConnReply(PptpCtrl c, struct pptpStopCtrlConnReply *rep) |
{ |
{ |
|
(void)rep; |
PptpCtrlKillCtrl(c); |
PptpCtrlKillCtrl(c); |
} |
} |
|
|
Line 2168 PptpOutCallRequest(PptpCtrl c, struct pptpOutCallReque
|
Line 2178 PptpOutCallRequest(PptpCtrl c, struct pptpOutCallReque
|
|
|
/* Ask link layer about making the outgoing call */ |
/* Ask link layer about making the outgoing call */ |
PptpCtrlInitCinfo(ch, &cinfo); |
PptpCtrlInitCinfo(ch, &cinfo); |
linfo = (*gGetOutLink)(&cinfo, &c->self_addr, &c->peer_addr, c->peer_port, req->bearType, | linfo = (*gGetOutLink)(&cinfo, &c->self_addr, &c->peer_addr, c->peer_port, |
req->frameType, req->minBps, req->maxBps, calledNum, subAddress); | calledNum); |
if (linfo.cookie == NULL) |
if (linfo.cookie == NULL) |
goto denied; |
goto denied; |
|
|
Line 2281 PptpInCallRequest(PptpCtrl c, struct pptpInCallRequest
|
Line 2291 PptpInCallRequest(PptpCtrl c, struct pptpInCallRequest
|
linfo.cancel = NULL; |
linfo.cancel = NULL; |
if (gGetInLink) |
if (gGetInLink) |
linfo = (*gGetInLink)(&cinfo, &c->self_addr, &c->peer_addr, c->peer_port, |
linfo = (*gGetInLink)(&cinfo, &c->self_addr, &c->peer_addr, c->peer_port, |
req->bearType, callingNum, calledNum, subAddress); | callingNum, calledNum); |
ch->linfo = linfo; |
ch->linfo = linfo; |
if (linfo.cookie == NULL) { |
if (linfo.cookie == NULL) { |
Log(LG_PHYS2, ("pptp%d: incoming call request denied", c->id)); |
Log(LG_PHYS2, ("pptp%d: incoming call request denied", c->id)); |
Line 2368 PptpCallClearRequest(PptpChan ch, struct pptpCallClear
|
Line 2378 PptpCallClearRequest(PptpChan ch, struct pptpCallClear
|
struct pptpCallDiscNotify notify; |
struct pptpCallDiscNotify notify; |
PptpCtrl const c = ch->ctrl; |
PptpCtrl const c = ch->ctrl; |
|
|
|
(void)req; |
if (PPTP_CHAN_IS_PNS(ch)) { |
if (PPTP_CHAN_IS_PNS(ch)) { |
Log(LG_PHYS2, ("pptp%d-%d: got %s, but we are PNS for this call", |
Log(LG_PHYS2, ("pptp%d-%d: got %s, but we are PNS for this call", |
c->id, ch->id, gPptpMsgInfo[PPTP_CallClearRequest].name)); |
c->id, ch->id, gPptpMsgInfo[PPTP_CallClearRequest].name)); |
Line 2407 PptpWanErrorNotify(PptpChan ch, struct pptpWanErrorNot
|
Line 2418 PptpWanErrorNotify(PptpChan ch, struct pptpWanErrorNot
|
{ |
{ |
PptpCtrl const c = ch->ctrl; |
PptpCtrl const c = ch->ctrl; |
|
|
|
(void)notif; |
Log(LG_PHYS2, ("pptp%d-%d: ignoring %s", |
Log(LG_PHYS2, ("pptp%d-%d: ignoring %s", |
c->id, ch->id, gPptpMsgInfo[PPTP_WanErrorNotify].name)); |
c->id, ch->id, gPptpMsgInfo[PPTP_WanErrorNotify].name)); |
} |
} |
Line 2433 PptpSetLinkInfo(PptpChan ch, struct pptpSetLinkInfo *i
|
Line 2445 PptpSetLinkInfo(PptpChan ch, struct pptpSetLinkInfo *i
|
*/ |
*/ |
|
|
int |
int |
PptpsStat(Context ctx, int ac, char *av[], void *arg) | PptpsStat(Context ctx, int ac, const char *const av[], const void *arg) |
{ |
{ |
int k; |
int k; |
char buf1[48], buf2[48]; |
char buf1[48], buf2[48]; |
|
|
|
(void)ac; |
|
(void)av; |
|
(void)arg; |
|
|
Printf("Active PPTP tunnels:\r\n"); |
Printf("Active PPTP tunnels:\r\n"); |
for (k = 0; k < gNumPptpCtrl; k++) { |
for (k = 0; k < gNumPptpCtrl; k++) { |