📄 ifppp.c
字号:
/*
* FILENAME: ifppp.c
*
* Copyright 2001 By InterNiche Technologies Inc. All rights reserved
*
* The entry points which map PPP to the Interniche MAC (iface)
* structure. This allows IP to treat PPP links as an ordinary
* MAC device.
*
* MODULE: PPP
*
* ROUTINES: new_lcp(), new_ppp(), del_ppp(), prep_ppp(),
* ROUTINES: ppp_create(), ppp_ifopen(), ppp_pkt_send(), ppp_ifclose(),
* ROUTINES: ppp_mstats(), ppp_stats(), ppp_pktdemux(), ppp_timeisup(),
* ROUTINES: ppp_settimer(), ppp_cleartimer(), ppp_auth_fail
*
* PORTABLE: yes
*/
#include "ipport.h"
#ifdef USE_PPP
#include "ppp_port.h"
#include "mppp.h"
#include "ip.h"
#ifdef MINI_TCP
#include "../mtcp/mtcp.h"
#else
#include "tcp.h"
#endif
#include "udp.h"
#ifdef USE_PPPOE
#include "ether.h"
#include "pppoe.h"
#endif /* USE_PPPOE */
#ifdef PPP_PACKETS
struct queue ppp_rcvdq;
#endif /* PPP_PACKETS */
#ifdef PPP_MENU
#ifndef IN_MENUS
#error PPP_MENU requires IN_MENUS to be set
#endif /* IN_MENUS */
#include "menu.h"
/* (yaxon modify) */
/*extern struct menu_op ppp_menu[99]; in pppmenu.c */
extern struct menu_op ppp_menu[]; /* in pppmenu.c */
#endif /* PPP_MENU */
/* Internal PPP interface routines */
int ppp_ifopen(int iface);
int ppp_pkt_send(struct netbuf *);
int ppp_ifclose(int iface);
void ppp_stats(void * pio, int iface);
u_char ppp_phys_addr = 'p';
extern int dialer_status(void * pio);
/* number of static PPP connections. This can be changed by the
* port application prior to calling ip_startup();
*/
int ppp_static = 1;
/* FUNCTION: new_lcp()
*
* allocate basic PPP connection object. This constructor is shared
* between a full ICMP/LCP object and a multilink "slave" LCP only
* object.
*
* PARAM1: none
*
* RETURNS: new M_PPP object, or NULL if alloc fails
*/
M_PPP
new_lcp()
{
M_PPP mppp;
/* allocate the PPP struct */
mppp = (M_PPP)MPPP_ALLOC( sizeof(*mppp) );
if(mppp == NULL)
return NULL;
/* add new struct to master list */
mppp->next = ppp_list;
ppp_list = mppp;
/* set mppp's line pointer to mppp itself. This is so routines passed
* a line struct can find the relarted mppp if they need to.
*/
mppp->line.upper_unit = (void*)mppp;
/* set the magic number once when we create the LCP object. Only
* change it if he NAKs this value.
*/
mppp->lcp_wantoptions.magicnumber = ppp_magic(mppp);
return mppp;
}
/* FUNCTION: new_ppp()
*
* Constructor for the main (master) PPP link object.
* This should not be used for multilink "slave" LCP only
* objects; use "new_lcp()" for those.
*
* PARAM1: NET ifp
*
* RETURNS:
*/
M_PPP
new_ppp(NET ifp)
{
M_PPP mppp;
IFMIB mib;
mppp = new_lcp();
if(mppp == NULL)
return NULL;
/* set cross pointers with iface struct */
mppp->ifp = ifp;
ifp->n_local = (void*)mppp;
/* fill in ppp routines for each iface */
ifp->n_init = ppp_ifopen;
ifp->n_close = ppp_ifclose;
ifp->raw_send = NULL;
ifp->pkt_send = ppp_pkt_send;
ifp->n_reg_type = NULL;
ifp->n_stats = ppp_stats;
/* set header and max frame lengths for PPP */
#ifdef USE_PPPOE
/* If we're allowing PPPoE we have to assume this link could end up a PPPoE
* link and thus assume the PPPoE (worst case) sizes. Among other things, this
* will force MaxLnh to have the correct value to support PPPoE.
*/
ifp->n_lnh = ETHHDR_SIZE + POEHDR_SIZE + 2; /* add 2 byte PPP type field */
ifp->n_mtu = 1492;
#else
ifp->n_lnh = 4;
ifp->n_mtu = ppp_mtu;
#endif
/* fake up a little MAC address */
ifp->n_hal = 1;
ifp->n_haddr = (char*)&ppp_phys_addr;
ifp->n_flags |= NF_NBPROT; /* we set nb_prot fields in driver */
/* search the NV parameters for iface setup for our name. If this
* fails we just default to what's already in the ifp.
*/
/* Set up iface MIB */
mib = ifp->n_mib;
mib->ifPhysAddress = &ppp_phys_addr;
mib->ifDescr = (u_char*)"PPP link";
mib->ifType = PPP;
mib->ifAdminStatus = 2; /* start as down, establish() in ppp will fix */
mib->ifOperStatus = 2;
mib->ifLastChange = cticks * (100/TPS);
return mppp;
}
/* FUNCTION: del_ppp()
*
* Destructorfor M_PPP objects.
*
* PARAM1: M_PPP mppp
*
* RETURNS:
*/
void
del_ppp(M_PPP mppp)
{
M_PPP tmp;
M_PPP last = NULL;
/* search master list for object to delete */
for(tmp = ppp_list; tmp; tmp = tmp->next)
{
if(tmp == mppp) /* found it, unlink: */
{
if(last == NULL)
ppp_list = tmp->next;
else
last->next = tmp->next;
break;
}
}
if(tmp == NULL)
{
dtrap("ifppp 0\n"); /* not found? tell programmer */
return;
}
#ifdef PPP_MULTILINK /* remove from Multilink bundle */
if(mppp->pppflags & ALLOW_ML)
{
tmp = mppp->ml_ipcp;
if(tmp != NULL)
{
if(tmp == mppp) /* link to delete is bundle master */
{
/* delete all sublinks */
tmp = mppp->ml_links;
while(tmp) /* loop through sublink list */
{
last = tmp;
tmp = tmp->ml_next; /* may be NULL */
last->ml_next = tmp; /* unlink last */
/* kill ML flag so recursive call does simple delete */
last->pppflags &= ~ALLOW_ML;
if(last != mppp) /* don't delete master yet */
del_ppp(last);
}
}
else /* link to delete is a sublink */
{
last = NULL;
tmp = tmp->ml_links; /* get first sublink in list */
while(tmp)
{
if(tmp == mppp) /* found mppp in sublink list */
{
if(last)
last->ml_next = tmp->ml_next;
else
mppp->ml_ipcp->ml_links = tmp->ml_next;
break;
}
last = tmp;
tmp = tmp->ml_next;
}
}
}
}
#endif /* PPP_MULTILINK */
#ifdef LB_XOVER
/* If this is a crossover-loopback line then clean up the
* internal arrays
*/
if(mppp->line.lower_type == LN_LBXOVER)
{
int lp_index;
lp_index = pl_lookup(mppp);
if(lp_index >= 0)
{
lb_mppps[lp_index] = NULL;
lb_otherend[lp_index] = NULL;
}
}
#endif /* LB_XOVER */
/* if it's attached to an iface, delete iface's back pointer */
if(mppp->ifp &&
(mppp->ifp->n_local == (void*)mppp))
{
mppp->ifp->n_local = NULL;
}
MPPP_FREE(mppp);
return;
}
/* FUNCTION: prep_ppp()
*
* The MAC "prep" routine for all PPP ifaces
*
* PARAM1: int iface - nets[] index for first ppp interface
*
* RETURNS: index of last static PPP iface
*/
int
prep_ppp(int iface)
{
int i;
M_PPP mppp;
NET ifp;
/* Initialize PPP's Configuration global variables directly or if
* INCLUDE_NVPARMS is used then read these from NVRAM values.
*/
#ifndef INCLUDE_NVPARMS
pppcfg.ppp_ConsoleLog = PPP_CONSOLE_LOG_STAT;
pppcfg.ppp_FileLog = PPP_FILE_LOG_STAT;
pppcfg.ppp_keepalive = PPP_KEEP_ALIVE_SECS;
pppcfg.ppp_client_tmo = PPP_CLIENT_TMO_SECS;
#ifdef PPP_VJC
pppcfg.ppp_request_vj = PPP_REQUEST_VJ_STAT;
#endif /* PPP_VJC */
#ifdef CHAP_SUPPORT
strcpy(pppcfg.secret, CHAP_SECRET_STRING);
pppcfg.require_chap = REQURE_CHAP_STAT;
#endif /* CHAP_SUPPORT */
#ifdef PAP_SUPPORT
pppcfg.require_pap = REQUIRE_PAP_STAT;
#endif /* PAP_SUPPORT */
strcpy(pppcfg.username, PPP_USERNAME);
strcpy(pppcfg.password, PPP_PASSWORD);
pppcfg.line_tmo = PPP_LINE_TMO_SECS;
strcpy(pppcfg.loginfile, PPP_LOGIN_FILE_NAME );
strcpy(pppcfg.logservefile, PPP_SERVE_FILE_NAME);
#else
pppcfg.ppp_ConsoleLog = ppp_nvparms.ppp_ConsoleLog;
pppcfg.ppp_FileLog = ppp_nvparms.ppp_FileLog;
pppcfg.ppp_keepalive = ppp_nvparms.ppp_keepalive;
pppcfg.ppp_client_tmo = ppp_nvparms.ppp_client_tmo;
#ifdef PPP_VJC
pppcfg.ppp_request_vj = ppp_nvparms.ppp_request_vj;
#endif /* PPP_VJC */
#ifdef CHAP_SUPPORT
strcpy(pppcfg.secret, ppp_nvparms.secret);
pppcfg.require_chap = ppp_nvparms.require_chap;
#endif /* CHAP_SUPPORT */
#ifdef PAP_SUPPORT
pppcfg.require_pap = ppp_nvparms.require_pap;
#endif /* PAP_SUPPORT */
strcpy(pppcfg.username, ppp_nvparms.username);
strcpy(pppcfg.password, ppp_nvparms.password);
pppcfg.line_tmo = ppp_nvparms.line_tmo;
strcpy(pppcfg.loginfile, ppp_nvparms.loginfile);
strcpy(pppcfg.logservefile, ppp_nvparms.logservefile);
#endif /* INCLUDE_NVPARMS is used */
#ifdef PPP_MENU
/* install the PPP debug routines */
if(install_menu(ppp_menu))
{
dprintf("Error: Unable to install PPP menu\n");
/* This is not fatal (probably just out of menu slots), so fall
* through to rest of prep code.
*/
}
#endif /* PPP_MENU */
for(i = 0; i < ppp_static; i++)
{
#ifdef NPDEBUG
if(iface > STATIC_NETS)
{
dprintf("prep_ppp: STATIC_NETS exceeded\n");
dtrap("ifppp 1\n");
return iface;
}
#endif /* NPDEBUG */
ifp = nets[iface];
mppp = new_ppp(ifp);
/* make a 3 char name based on net number, eg "pp0" or "p21" */
/* later: need longer names!! */
ifp->name[0] = 'p';
ifp->name[1] = 'p';
ifp->name[2] = (char)(iface + '0');
ifp->name[3] = 0;
if(mppp == NULL)
{
#ifdef NPDEBUG
dprintf("prep_ppp: new_ppp failed, out of memory?\n");
dtrap("ifppp 2\n");
#endif /* NPDEBUG */
return iface;
}
iface++;
}
return iface;
}
/* FUNCTION: ppp_create()
*
* Create a new PPP link and attach it to the passed net struct. This
* is used by the dynamic iface API
*
* PARAM1: struct net * ifp - pointer to NET for new link
* PARAM2: void * bindinfo - pointer to binding information for device
*
* RETURNS: 0 if OK, else ENP_ error code.
*/
#ifdef DYNAMIC_IFACES
int
ppp_create(struct net * ifp, void * bindinfo)
{
M_PPP mppp;
int err;
mppp = new_ppp(ifp);
if(mppp == NULL)
return ENP_NOMEM;
err = ppp_line_init(mppp, ppp_default_type);
USE_VOID(bindinfo);
return err;
}
#endif /* DYNAMIC_IFACES */
/* FUNCTION: ppp_ifopen()
*
* The MAC interface open routine for PPP ifaces.
*
* PARAM1: int iface
*
* RETURNS:
*/
int
ppp_ifopen(int iface)
{
int err;
M_PPP mppp;
mppp = (M_PPP)nets[iface]->n_local;
#ifdef NPDEBUG
if(mppp == NULL)
{
dprintf("ppp_ifopen: no line\n");
dtrap("ifppp 3\n");
return ENP_LOGIC;
}
#endif /* NPDEBUG */
/* call per-line initialization */
err = ppp_line_init(mppp, ppp_default_type);
return err;
}
/* FUNCTION: ppp_pkt_send()
*
* The MAC interface packet send routine for PPP ifaces.
*
* PARAM1: struct netbuf * pkt
*
* RETURNS:
*/
int
ppp_pkt_send(struct netbuf * pkt)
{
int err;
M_PPP mppp;
qp qtmp;
mppp = (M_PPP)pkt->net->n_local;
/* make sure we got a valid iface with a PPP object */
if((mppp == NULL) || (mppp->ifp != pkt->net))
{
dtrap("ifppp 4\n");
return ENP_LOGIC;
}
/* make sure the packet is not already in the queue. This can happen
* if it's a TCP retry and the original try is still stilling
* in the queue.
*/
for(qtmp = mppp->dataq.q_head; qtmp; qtmp = qtmp->qe_next)
{
if(qtmp == (qp)pkt)
{
/* punt the packet and log this... */
//ConPrintf("ppp_PKT_SEND: retry dropped\n");
LOCK_NET_RESOURCE(FREEQ_RESID);
pk_free(pkt);
UNLOCK_NET_RESOURCE(FREEQ_RESID);
/* see if we can start the send anyway. The TCP retry may
* be the only thing driving the send logic.
*/
ppp_allpktsend(mppp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -