PPP, SERVER: added PPPoS server support

New function: ppp_listen(), listen for an incoming PPP connection.
This commit is contained in:
Sylvain Rochet 2015-02-28 22:41:18 +01:00
parent 89771de6d0
commit 371bc91d73
9 changed files with 166 additions and 1 deletions

View File

@ -261,6 +261,34 @@ pppapi_open(ppp_pcb *pcb, u16_t holdoff)
}
#if PPP_SERVER
/**
* Call ppp_listen() inside the tcpip_thread context.
*/
static void
pppapi_do_ppp_listen(struct pppapi_msg_msg *msg)
{
msg->err = ppp_listen(msg->ppp, msg->msg.listen.addrs);
TCPIP_PPPAPI_ACK(msg);
}
/**
* Call ppp_listen() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
err_t
pppapi_listen(ppp_pcb *pcb, struct ppp_addrs *addrs)
{
struct pppapi_msg msg;
msg.function = pppapi_do_ppp_listen;
msg.msg.ppp = pcb;
msg.msg.msg.listen.addrs = addrs;
TCPIP_PPPAPI(&msg);
return msg.msg.err;
}
#endif /* PPP_SERVER */
/**
* Call ppp_close() inside the tcpip_thread context.
*/

View File

@ -2049,7 +2049,9 @@
#endif
/**
* PPP_SERVER==1: Enable PPP server support (waiting for incoming PPP session). CURRENTLY NOT SUPPORTED! DO NOT SET!
* PPP_SERVER==1: Enable PPP server support (waiting for incoming PPP session).
*
* Currently only supported for PPPoS.
*/
#ifndef PPP_SERVER
#define PPP_SERVER 0

View File

@ -92,6 +92,11 @@ struct pppapi_msg_msg {
struct {
u16_t holdoff;
} open;
#if PPP_SERVER
struct {
struct ppp_addrs *addrs;
} listen;
#endif /* PPP_SERVER */
struct {
u8_t nocarrier;
} close;
@ -127,6 +132,9 @@ ppp_pcb *pppapi_pppol2tp_create(struct netif *pppif, struct netif *netif, ip_add
ppp_link_status_cb_fn link_status_cb, void *ctx_cb);
#endif /* PPPOL2TP_SUPPORT */
err_t pppapi_open(ppp_pcb *pcb, u16_t holdoff);
#if PPP_SERVER
err_t pppapi_listen(ppp_pcb *pcb, struct ppp_addrs *addrs);
#endif /* PPP_SERVER */
err_t pppapi_close(ppp_pcb *pcb, u8_t nocarrier);
err_t pppapi_free(ppp_pcb *pcb);
err_t pppapi_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg);

View File

@ -463,6 +463,21 @@ void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_p
*/
err_t ppp_open(ppp_pcb *pcb, u16_t holdoff);
#if PPP_SERVER
/*
* Listen for an incoming PPP connection.
*
* This can only be called if PPP is in the dead phase.
*
* Local and remote interface IP addresses, as well as DNS are
* provided through a previously filled struct ppp_addrs.
*
* If this port connects to a modem, the modem connection must be
* established before calling this.
*/
err_t ppp_listen(ppp_pcb *pcb, struct ppp_addrs *addrs);
#endif /* PPP_SERVER */
/*
* Initiate the end of a PPP connection.
* Any outstanding packets in the queues are dropped.

View File

@ -143,6 +143,10 @@
struct link_callbacks {
/* Start a connection (e.g. Initiate discovery phase) */
err_t (*connect) (ppp_pcb *pcb, void *ctx);
#if PPP_SERVER
/* Listen for an incoming connection (Passive mode) */
err_t (*listen) (ppp_pcb *pcb, void *ctx, struct ppp_addrs *addrs);
#endif /* PPP_SERVER */
/* End a connection (i.e. initiate disconnect phase) */
void (*disconnect) (ppp_pcb *pcb, void *ctx);
/* Free lower protocol control block */

View File

@ -247,6 +247,32 @@ err_t ppp_open(ppp_pcb *pcb, u16_t holdoff) {
return ERR_OK;
}
#if PPP_SERVER
/*
* Listen for an incoming PPP connection.
*
* This can only be called if PPP is in the dead phase.
*
* Local and remote interface IP addresses, as well as DNS are
* provided through a previously filled struct ppp_addrs.
*
* If this port connects to a modem, the modem connection must be
* established before calling this.
*/
err_t ppp_listen(ppp_pcb *pcb, struct ppp_addrs *addrs) {
if (pcb->phase != PPP_PHASE_DEAD) {
return ERR_ALREADY;
}
PPPDEBUG(LOG_DEBUG, ("ppp_listen() called\n"));
if (pcb->link_cb->listen) {
return pcb->link_cb->listen(pcb, pcb->link_ctx_cb, addrs);
}
return ERR_IF;
}
#endif /* PPP_SERVER */
/*
* Initiate the end of a PPP connection.
* Any outstanding packets in the queues are dropped.

View File

@ -150,6 +150,9 @@ static struct pppoe_softc *pppoe_softc_list;
/* Callbacks structure for PPP core */
static const struct link_callbacks pppoe_callbacks = {
pppoe_connect,
#if PPP_SERVER
NULL,
#endif /* PPP_SERVER */
pppoe_disconnect,
pppoe_destroy,
pppoe_write,

View File

@ -99,6 +99,9 @@ static err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb);
/* Callbacks structure for PPP core */
static const struct link_callbacks pppol2tp_callbacks = {
pppol2tp_connect,
#if PPP_SERVER
NULL,
#endif /* PPP_SERVER */
pppol2tp_disconnect,
pppol2tp_destroy,
pppol2tp_write,

View File

@ -54,6 +54,9 @@
static err_t pppos_write(ppp_pcb *ppp, void *ctx, struct pbuf *p);
static err_t pppos_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *pb, u_short protocol);
static err_t pppos_connect(ppp_pcb *ppp, void *ctx);
#if PPP_SERVER
static err_t pppos_listen(ppp_pcb *ppp, void *ctx, struct ppp_addrs *addrs);
#endif /* PPP_SERVER */
static void pppos_disconnect(ppp_pcb *ppp, void *ctx);
static err_t pppos_destroy(ppp_pcb *ppp, void *ctx);
static void pppos_send_config(ppp_pcb *ppp, void *ctx, u32_t accm);
@ -76,6 +79,9 @@ static void pppos_drop(pppos_pcb *pppos);
/* Callbacks structure for PPP core */
static const struct link_callbacks pppos_callbacks = {
pppos_connect,
#if PPP_SERVER
pppos_listen,
#endif /* PPP_SERVER */
pppos_disconnect,
pppos_destroy,
pppos_write,
@ -418,6 +424,76 @@ pppos_connect(ppp_pcb *ppp, void *ctx)
return ERR_OK;
}
#if PPP_SERVER
static err_t
pppos_listen(ppp_pcb *ppp, void *ctx, struct ppp_addrs *addrs)
{
pppos_pcb *pppos = (pppos_pcb *)ctx;
#if PPP_IPV4_SUPPORT
ipcp_options *ipcp_wo;
#if !VJ_SUPPORT
ipcp_options *ipcp_ao;
#endif /* !VJ_SUPPORT */
#endif /* PPP_IPV4_SUPPORT */
lcp_options *lcp_wo;
/* input pbuf left over from last session? */
pppos_free_current_input_packet(pppos);
ppp_clear(ppp);
/* reset PPPoS control block to its initial state */
memset(&pppos->out_accm, 0, sizeof(pppos_pcb) - ( (char*)&((pppos_pcb*)0)->out_accm - (char*)0 ) );
/* Wait passively */
lcp_wo = &ppp->lcp_wantoptions;
lcp_wo->silent = 1;
#if PPP_AUTH_SUPPORT
if (ppp->settings.user && ppp->settings.passwd) {
ppp->settings.auth_required = 1;
}
#endif /* PPP_AUTH_SUPPORT */
#if PPP_IPV4_SUPPORT
ipcp_wo = &ppp->ipcp_wantoptions;
ipcp_wo->ouraddr = ip4_addr_get_u32(&addrs->our_ipaddr);
ipcp_wo->hisaddr = ip4_addr_get_u32(&addrs->his_ipaddr);
ipcp_wo->dnsaddr[0] = ip4_addr_get_u32(&addrs->dns1);
ipcp_wo->dnsaddr[1] = ip4_addr_get_u32(&addrs->dns2);
#if VJ_SUPPORT
vj_compress_init(&pppos->vj_comp);
#else /* VJ_SUPPORT */
/* Don't even try to negotiate VJ if VJ is disabled */
ipcp_wo = &ppp->ipcp_wantoptions;
ipcp_wo->neg_vj = 0;
ipcp_wo->old_vj = 0;
ipcp_ao = &ppp->ipcp_allowoptions;
ipcp_ao->neg_vj = 0;
ipcp_ao->old_vj = 0;
#endif /* VJ_SUPPORT */
#else /* PPP_IPV4_SUPPORT */
LWIP_UNUSED_ARG(addrs);
#endif /* PPP_IPV4_SUPPORT */
/*
* Default the in and out accm so that escape and flag characters
* are always escaped.
*/
pppos->in_accm[15] = 0x60; /* no need to protect since RX is not running */
pppos->out_accm[15] = 0x60;
/*
* Wait for something to happen.
*/
PPPDEBUG(LOG_INFO, ("pppos_listen: unit %d: listening\n", ppp->netif->num));
ppp_start(ppp); /* notify upper layers */
return ERR_OK;
}
#endif /* PPP_SERVER */
static void
pppos_disconnect(ppp_pcb *ppp, void *ctx)
{