ppp: get rid of ppp_enter_phase

This function simply didn't have the context of why the phase was being
entered.  Instead have each protocol notify GAtPPP as to what is
happening.  We already had this more or less for IPCP and AUTH events,
this just now formalizes it for LCP as well.
This commit is contained in:
Denis Kenzior 2010-04-30 14:37:17 -05:00
parent c7ef06f91e
commit 9ae0dcb47d
4 changed files with 85 additions and 57 deletions

View File

@ -43,6 +43,15 @@
#define DEFAULT_MRU 1500
#define DEFAULT_MTU 1500
enum ppp_phase {
PPP_PHASE_DEAD = 0, /* Link dead */
PPP_PHASE_ESTABLISHMENT, /* LCP started */
PPP_PHASE_AUTHENTICATION, /* Auth started */
PPP_PHASE_NETWORK, /* IPCP started */
PPP_PHASE_LINK_UP, /* IPCP negotiation succeded, link up */
PPP_PHASE_TERMINATION, /* LCP Terminate phase */
};
struct _GAtPPP {
gint ref_count;
enum ppp_phase phase;
@ -89,9 +98,12 @@ static inline gboolean ppp_drop_packet(GAtPPP *ppp, guint16 protocol)
case PPP_PHASE_DEAD:
return TRUE;
case PPP_PHASE_NETWORK:
if (ppp->net == NULL && protocol == PPP_IP_PROTO)
if (protocol != LCP_PROTOCOL && protocol != CHAP_PROTOCOL &&
protocol != IPCP_PROTO)
return TRUE;
break;
case PPP_PHASE_LINK_UP:
break;
}
return FALSE;
@ -168,43 +180,13 @@ static void ppp_dead(GAtPPP *ppp)
ppp->disconnect_cb(ppp->disconnect_data);
}
void ppp_enter_phase(GAtPPP *ppp, enum ppp_phase phase)
static inline void ppp_enter_phase(GAtPPP *ppp, enum ppp_phase phase)
{
/* don't do anything if we're already there */
if (ppp->phase == phase)
return;
/* set new phase */
g_print("Entering new phase: %d\n", phase);
ppp->phase = phase;
g_print("Entering new phase: %d\n", phase);
switch (phase) {
case PPP_PHASE_ESTABLISHMENT:
/* send an UP & OPEN events to the lcp layer */
pppcp_signal_up(ppp->lcp);
pppcp_signal_open(ppp->lcp);
break;
case PPP_PHASE_AUTHENTICATION:
/* If we don't expect auth, move on to network phase */
if (ppp->chap == NULL)
ppp_enter_phase(ppp, PPP_PHASE_NETWORK);
/* otherwise wait for the peer to send us a challenge */
break;
case PPP_PHASE_NETWORK:
/* Send UP & OPEN events to the IPCP layer */
pppcp_signal_open(ppp->ipcp);
pppcp_signal_up(ppp->ipcp);
break;
case PPP_PHASE_TERMINATION:
pppcp_signal_down(ppp->ipcp);
pppcp_signal_close(ppp->ipcp);
break;
case PPP_PHASE_DEAD:
if (phase == PPP_PHASE_DEAD)
ppp_dead(ppp);
break;
}
}
void ppp_set_auth(GAtPPP *ppp, const guint8* auth_data)
@ -226,13 +208,19 @@ void ppp_set_auth(GAtPPP *ppp, const guint8* auth_data)
void ppp_auth_notify(GAtPPP *ppp, gboolean success)
{
if (success)
ppp_enter_phase(ppp, PPP_PHASE_NETWORK);
else
ppp_enter_phase(ppp, PPP_PHASE_TERMINATION);
if (success == FALSE) {
pppcp_signal_close(ppp->lcp);
return;
}
ppp_enter_phase(ppp, PPP_PHASE_NETWORK);
/* Send UP & OPEN events to the IPCP layer */
pppcp_signal_open(ppp->ipcp);
pppcp_signal_up(ppp->ipcp);
}
void ppp_net_up_notify(GAtPPP *ppp, const char *ip,
void ppp_ipcp_up_notify(GAtPPP *ppp, const char *ip,
const char *dns1, const char *dns2)
{
ppp->net = ppp_net_new(ppp);
@ -240,6 +228,8 @@ void ppp_net_up_notify(GAtPPP *ppp, const char *ip,
if (ppp_net_set_mtu(ppp->net, ppp->mtu) == FALSE)
g_printerr("Unable to set MTU\n");
ppp_enter_phase(ppp, PPP_PHASE_LINK_UP);
if (ppp->connect_cb == NULL)
return;
@ -252,7 +242,7 @@ void ppp_net_up_notify(GAtPPP *ppp, const char *ip,
ip, dns1, dns2, ppp->connect_data);
}
void ppp_net_down_notify(GAtPPP *ppp)
void ppp_ipcp_down_notify(GAtPPP *ppp)
{
/* Most likely we failed to create the interface */
if (ppp->net == NULL)
@ -262,6 +252,41 @@ void ppp_net_down_notify(GAtPPP *ppp)
ppp->net = NULL;
}
void ppp_ipcp_finished_notify(GAtPPP *ppp)
{
if (ppp->phase != PPP_PHASE_NETWORK)
return;
/* Our IPCP parameter negotiation failed */
pppcp_signal_close(ppp->ipcp);
pppcp_signal_close(ppp->lcp);
}
void ppp_lcp_up_notify(GAtPPP *ppp)
{
/* Wait for the peer to send us a challenge if we expect auth */
if (ppp->chap != NULL) {
ppp_enter_phase(ppp, PPP_PHASE_AUTHENTICATION);
return;
}
/* Otherwise proceed as if auth succeeded */
ppp_auth_notify(ppp, TRUE);
}
void ppp_lcp_down_notify(GAtPPP *ppp)
{
if (ppp->phase == PPP_PHASE_NETWORK || ppp->phase == PPP_PHASE_LINK_UP)
pppcp_signal_down(ppp->ipcp);
ppp_enter_phase(ppp, PPP_PHASE_TERMINATION);
}
void ppp_lcp_finished_notify(GAtPPP *ppp)
{
ppp_dead(ppp);
}
void ppp_set_recv_accm(GAtPPP *ppp, guint32 accm)
{
g_at_hdlc_set_recv_accm(ppp->hdlc, accm);
@ -288,13 +313,17 @@ static void io_disconnect(gpointer user_data)
GAtPPP *ppp = user_data;
pppcp_signal_down(ppp->lcp);
ppp_enter_phase(ppp, PPP_PHASE_DEAD);
pppcp_signal_close(ppp->lcp);
}
/* Administrative Open */
void g_at_ppp_open(GAtPPP *ppp)
{
ppp_enter_phase(ppp, PPP_PHASE_ESTABLISHMENT);
/* send an UP & OPEN events to the lcp layer */
pppcp_signal_up(ppp->lcp);
pppcp_signal_open(ppp->lcp);
}
gboolean g_at_ppp_set_credentials(GAtPPP *ppp, const char *username,
@ -367,6 +396,9 @@ void g_at_ppp_set_debug(GAtPPP *ppp, GAtDebugFunc func, gpointer user_data)
void g_at_ppp_shutdown(GAtPPP *ppp)
{
if (ppp->phase == PPP_PHASE_DEAD || ppp->phase == PPP_PHASE_TERMINATION)
return;
pppcp_signal_close(ppp->lcp);
}

View File

@ -27,14 +27,6 @@
#define PPP_IP_PROTO 0x0021
#define MD5 5
enum ppp_phase {
PPP_PHASE_DEAD = 0, /* Link dead */
PPP_PHASE_ESTABLISHMENT, /* LCP started */
PPP_PHASE_AUTHENTICATION, /* Auth started */
PPP_PHASE_NETWORK, /* IPCP started */
PPP_PHASE_TERMINATION, /* LCP Terminate phase */
};
struct ppp_chap;
struct ppp_net;
@ -107,13 +99,16 @@ gboolean ppp_net_set_mtu(struct ppp_net *net, guint16 mtu);
/* PPP functions related to main GAtPPP object */
void ppp_debug(GAtPPP *ppp, const char *str);
void ppp_enter_phase(GAtPPP *ppp, enum ppp_phase phase);
void ppp_transmit(GAtPPP *ppp, guint8 *packet, guint infolen);
void ppp_set_auth(GAtPPP *ppp, const guint8 *auth_data);
void ppp_auth_notify(GAtPPP *ppp, gboolean success);
void ppp_net_up_notify(GAtPPP *ppp, const char *ip,
void ppp_ipcp_up_notify(GAtPPP *ppp, const char *ip,
const char *dns1, const char *dns2);
void ppp_net_down_notify(GAtPPP *ppp);
void ppp_ipcp_down_notify(GAtPPP *ppp);
void ppp_ipcp_finished_notify(GAtPPP *ppp);
void ppp_lcp_up_notify(GAtPPP *ppp);
void ppp_lcp_down_notify(GAtPPP *ppp);
void ppp_lcp_finished_notify(GAtPPP *ppp);
void ppp_set_recv_accm(GAtPPP *ppp, guint32 accm);
void ppp_set_xmit_accm(GAtPPP *ppp, guint32 accm);
void ppp_set_mtu(GAtPPP *ppp, const guint8 *data);

View File

@ -135,7 +135,7 @@ static void ipcp_up(struct pppcp_data *pppcp)
addr.s_addr = ipcp->dns2;
inet_ntop(AF_INET, &addr, dns2, INET_ADDRSTRLEN);
ppp_net_up_notify(pppcp_get_ppp(pppcp), ip[0] ? ip : NULL,
ppp_ipcp_up_notify(pppcp_get_ppp(pppcp), ip[0] ? ip : NULL,
dns1[0] ? dns1 : NULL,
dns2[0] ? dns2 : NULL);
}
@ -146,11 +146,12 @@ static void ipcp_down(struct pppcp_data *pppcp)
ipcp_reset_config_options(ipcp);
pppcp_set_local_options(pppcp, ipcp->options, ipcp->options_len);
ppp_net_down_notify(pppcp_get_ppp(pppcp));
ppp_ipcp_down_notify(pppcp_get_ppp(pppcp));
}
static void ipcp_finished(struct pppcp_data *pppcp)
{
ppp_ipcp_finished_notify(pppcp_get_ppp(pppcp));
}
static void ipcp_rca(struct pppcp_data *pppcp,

View File

@ -116,7 +116,7 @@ static void lcp_reset_config_options(struct lcp_data *lcp)
*/
static void lcp_up(struct pppcp_data *pppcp)
{
ppp_enter_phase(pppcp_get_ppp(pppcp), PPP_PHASE_AUTHENTICATION);
ppp_lcp_up_notify(pppcp_get_ppp(pppcp));
}
/*
@ -128,7 +128,7 @@ static void lcp_down(struct pppcp_data *pppcp)
lcp_reset_config_options(lcp);
pppcp_set_local_options(pppcp, lcp->options, lcp->options_len);
ppp_enter_phase(pppcp_get_ppp(pppcp), PPP_PHASE_TERMINATION);
ppp_lcp_down_notify(pppcp_get_ppp(pppcp));
}
/*
@ -137,7 +137,7 @@ static void lcp_down(struct pppcp_data *pppcp)
*/
static void lcp_finished(struct pppcp_data *pppcp)
{
ppp_enter_phase(pppcp_get_ppp(pppcp), PPP_PHASE_DEAD);
ppp_lcp_finished_notify(pppcp_get_ppp(pppcp));
}
static void lcp_rca(struct pppcp_data *pppcp, const struct pppcp_packet *packet)