8.4 Implementing the PPP Daemon

   


As was mentioned repeatedly in previous sections, the largest part of the implementation effort takes place in the PPP daemon, pppd. One of the reasons is that it processes all subprotocols to control the PPP connection. To maintain expandability, utmost care was taken to keep the implementation highly modular, and it has a clearly defined interface for subprotocol implementations.

8.4.1 Managing Subprotocols

struct protent

pppd/pppd.h


The core of the pppd interface for subprotocols is the protent structure, which is defined in the file pppd/pppd.h. It includes mainly entries for callback functions, which are always called whenever pppd receives a packet that it allocates to this subprotocol, given the protocol ID:

 struct protent {     u_short protocol;           /* PPP protocol number */     /* Initialization procedure */     void (*init) ___P((int unit));     /* Process a received packet */     void (*input) ___P((int unit, u_char *pkt, int len));     /* Process a received protocol-reject */     void (*protrej) ___P((int unit));     /* Lower layer has come up  */     void (*lowerup) ___P((int unit));     /* Lower layer has gone down */     void (*lowerdown) ___P((int unit));     /* Open the protocol */     void (*open) ___P((int unit));     /* Close the protocol */     void (*close) ___P((int unit, char *reason));     /* Print a packet in readable form */     int (*printpkt) ___P((u_char *pkt, int len,                           void (*printer) ___P((void *, char *, ...)),                           void *arg));     /* Process a received data packet */     void (*datainput) ___P((int unit, u_char *pkt, int len));     bool enabled_flag;    /* 0 iff protocol is disabled */     char *name;           /* Text name of protocol */     char *data_name;      /* Text name of corresponding data protocol */     option_t *options;    /* List of command-line options */     /* Check requested options, assign defaults */     void (*check_options) ___P((void));     /* Configure interface for demand-dial */     int (*demand_conf) ___P((int unit));     /* Say whether to bring up link for this pkt */     int (*active_pkt) ___P((u_char *pkt, int len)); }; 

Each of the protocols known to pppd has exactly one entry in the global list struct protent protocols[].

Figure 8-6 shows a flow diagram representing a simplified procedure of how a connection is established. The function init() is executed immediately after pppd has started. Shortly after that, the function check_options() is run to handle settings, if applicable, using command-line arguments or options in /etc/ppp/options.

Figure 8-6. Procedure involved when pppd establishes a connection.

graphics/08fig06.gif


The function lowerup() is invoked for each subprotocol as soon as the lower layers are active. For LCP, the lower layer is the TTY device concerned; all other sub-protocols wait for LCP in turn.

Authentication per PAP or CHAP is now triggered in the function link_established() in pppd/auth.c. If the authentication can be completed successfully, then the subprotocols are informed by the function pointer open() in the protent structure, and they all can now start working. As soon as the PPP connection is closed again, all subprotocols are notified accordingly by the function pointer close(). For the authentication protocols PAP and CHAP, the value NULL each is entered for open() and close() as callback function.

8.4.2 States

The protocol logic of most subprotocols can be represented elegantly in the form of a finite state machine (FSM). To save cost and avoid errors, the PPP daemon implements a generic FSM, which handles things like state transitions and timers. It is implemented in pppd/fsm.c and primarily takes care that the correct callback functions are invoked at the right time. Examples for subprotocols with an implementation that accesses this generic finite state machine include LCP and IPCP.

PPP itself, and thus the PPP daemon, also know different states; however, these states have little to do with the states of subprotocols. These so-called phases are listed in Table 8-3. The PPP daemon behaves differently, depending on the state. For example, it would be fatal to admit configuration protocols for the network layer, such as IPCP, before a successful authentication.

Table 8-3. States (phases) of the PPP daemon.

State

Meaning

PHASE_INITIALIZE

Initial state: pppd initialization.

PHASE_DORMANT

Waiting for activity (for dial-on-demand).

PHASE_SERIALCONN

Establish physical connection.

PHASE_ESTABLISH

Physical connection is up and running.

PHASE_AUTHENTICATE

Authentication in progress.

PHASE_CALLBACK

CBCP (see Section 8.2.4) is running.

PHASE_NETWORK

Network protocols are being configured.

PHASE_RUNNING

Higher layers can start working.

PHASE_TERMINATE

LCP requested connection to be torn down.

PHASE_DISCONNECT

Program to tear down connection has started.

PHASE_HOLDOFF

Wait a little before the next connection is established.

PHASE_DEAD

Connection was interrupted.


A callback function can be invoked upon request in each of these state transitions. To this end, the callback function need only be added to the otherwise unused global variable new_phase_hook.


       


    Linux Network Architecture
    Linux Network Architecture
    ISBN: 131777203
    EAN: N/A
    Year: 2004
    Pages: 187

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net