⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ifppp.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 
 * 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 + -