📄 ppp_loop.c
字号:
/*
* FILENAME: ppp_loop.c
*
* Copyright 1997 - 2001 By InterNiche Technologies Inc. All rights reserved
*
* Loopback line driver for InterNiche PPP
*
* MODULE: PPP
*
* ROUTINES: pl_connect(), pl_hangup(), pl_putc(), pl_write(),
* ROUTINES: pl_speed(), pl_state(),
*
* PORTABLE: yes
*/
#include "ipport.h"
#ifdef USE_PPP /* whole file can be ifdeffed out */
#include "ppp_port.h"
#ifdef LB_XOVER /* file can be ifdeffed on this too */
#include "mppp.h"
#include "ppp_loop.h"
#include "ip.h"
/* list of existing loopback devices. Devices are added to the list as
* they are created. When a device initiates a connection (thus becoming
* a client) a disconnected device is selceted from the list to be it's
* server. If there are no free devices then the client open fails.
*/
M_PPP lb_mppps[MAX_LBXOVERS];
/* also keep a list of connected endpoints for the above links. IE if
* lb_mppp[0] is logically connected, it's "other end" will be in
* lb_otherend[0]. These entrys have no meaning if the state of
* the lb_mppp[] entry's line is not LN_CONNECTED.
*/
M_PPP lb_otherend[MAX_LBXOVERS];
/* FUNCTION: pl_lookup()
*
* find the index into lb_mppp table which matchs the passed M_PPP
* pointer.
*
* PARAM1: M_PPP
*
* RETURNS: index of entry from lb_mppp table, or -1 is not found.
*/
int
pl_lookup(M_PPP mppp)
{
int i;
for(i = 0; i < MAX_LBXOVERS; i++)
{
if(lb_mppps[i] == mppp)
return i;
}
return -1;
}
/* FUNCTION: pl_lookup()
*
* Find the loopback mppp connected to a passed mppp.
*
* PARAM1: M_PPP
*
* RETURNS: mppp of other end, or NULL
*/
M_PPP
pl_otherend(M_PPP mppp)
{
int index;
/* passed line MUST be connected */
if(mppp->line.ln_state != LN_CONNECTED)
{
return NULL;
}
index = pl_lookup(mppp);
if(index < 0)
{
dtrap("ppp_loop 0\n");
return NULL;
}
return lb_otherend[index];
}
/* FUNCTION: pl_init()
*
* "init" routine for loopback driver.
*
* PARAM1: struct com_line * lineptr
*
* RETURNS: 0 if OK or ENP error code
*/
int
pl_init(LINEP lineptr)
{
M_PPP mppp;
int free; /* first free entry in table */
int i;
mppp = (M_PPP)(lineptr->upper_unit);
free = -1;
for(i = 0; i < MAX_LBXOVERS; i++)
{
/* If this mppp has already been added then just return */
if(lb_mppps[i] == mppp)
{
dtrap("ppp_loop 1\n"); /* sloppy progamming? */
return ENP_LOGIC;
}
/* remember first free table entry */
if((lb_mppps[i] == NULL) && (free < 0))
free = i;
}
if(free < 0) /* No free entry found? */
return ENP_RESOURCE;
lb_mppps[free] = mppp;
lb_otherend[free] = NULL; /* cleanup... */
mppp->line.ln_state = LN_DISCONNECTED;
return 0;
}
/* FUNCTION: pl_connect()
*
* Comm line "connect" routine for loopback driver.
*
* PARAM1: int unit
* PARAM2: struct com_line * lineptr
*
* RETURNS: LN_CONNECTED if OK, else LN_DISCONNECTED
*/
int
pl_connect(LINEP line)
{
int client_index;
int server_index;
M_PPP server;
M_PPP client = (M_PPP)(line->upper_unit);
/* find a free loopback link to be server for the new connection */
server = NULL;
for(server_index = 0; server_index < MAX_LBXOVERS; server_index++)
{
if(lb_mppps[server_index] == NULL) /* skip empty entries */
continue;
if(lb_mppps[server_index] == client) /* skip self (client) */
continue;
if(lb_mppps[server_index]->ifp == client->ifp) /* skip same iface */
continue;
if(lb_mppps[server_index]->line.ln_state == LN_DISCONNECTED)
{
server = lb_mppps[server_index];
break;
}
}
if(server == NULL)
{
//ConPrintf("lbxover: no server\n");
return LN_DISCONNECTED;
}
client_index = pl_lookup(client);
if(client_index < 0)
{
//ConPrintf("lbxover: no client index\n");
return LN_DISCONNECTED;
}
/* map the client and server links to each other */
lb_otherend[client_index] = server;
lb_otherend[server_index] = client;
/* since there is no actual hardware to connect, the client is
* logically up & connected at this point.
*/
line->ln_state = LN_CONNECTED;
/* Signal the server line that it's lower level just came up. */
server->line.ln_state = LN_CONNECTED; /* server is now connected too */
ppp_lowerup(server, LCP_STATE);
ppp_open(server, LCP_STATE);
ppp_lowerup(client, LCP_STATE); /* Do client lowerup */
return LN_CONNECTED;
}
/* FUNCTION: pl_hangup()
*
* disconnect the line
*
* PARAM1: int unit
*
* RETURNS:
*/
int
pl_hangup(LINEP line)
{
int index;
M_PPP other_ppp;
M_PPP mppp = (M_PPP)(line->upper_unit);
/* if connected, hangup other unit gracfully */
other_ppp = pl_otherend(mppp);
if(other_ppp)
{
ppp_lowerdown(other_ppp, LCP_STATE);
index = pl_lookup(mppp);
lb_otherend[index] = NULL; /* clear our partner entry */
}
/* No actual hardware; just set state */
line->ln_state = LN_DISCONNECTED;
return 0;
}
/* FUNCTION: pl_putc()
*
* PARAM1: int unit
* PARAM2: int byte
*
* RETURNS:
*/
#ifdef PPP_CHARIO
int
pl_putc(LINEP line, int byte)
{
M_PPP rxmp; /* receiveing link */
M_PPP txmp = (M_PPP)(line->upper_unit); /* sending link */
rxmp = pl_otherend(txmp);
if(!rxmp)
{
dtrap("ppp_loop 2\n"); /* line is not a loopback line */
return -1;
}
/* since xover lines are always working, check RX line's logical state */
if(rxmp->line.ln_state != LN_CONNECTED)
{
dtrap("ppp_loop 3\n");
}
ppp_inchar(rxmp, byte);
return 0;
}
#endif /* PPP_CHARIO */
/* FUNCTION: pl_write()
*
* PARAM1: int unit
* PARAM2: char * block
* PARAM3: int length
*
* RETURNS:
*/
#ifdef PPP_PACKETS
int
pl_write(LINEP line, PACKET pkt)
{
M_PPP rxmp;
M_PPP txmp = (M_PPP)(line->upper_unit);
rxmp = pl_otherend(txmp);
if(!rxmp)
{
dtrap("ppp_loop 4\n"); /* bad mppp */
return -1;
}
/* since xover lines are always working, check RX line's logical state */
if(rxmp->line.ln_state != LN_CONNECTED)
{
dtrap("ppp_loop 5\n");
}
pkt->net = rxmp->ifp; /* tag packet for receive network */
putq(&ppp_rcvdq, (qp)pkt); /* put pkt in input queue */
SignalPPPDemux(); /* wake demuxer */
return 0;
}
#endif /* PPP_PACKETS */
/* FUNCTION: ppp_lb_add_routes()
*
* Add static routes in the IP Route table for rthe first two static
* xover ifaces, This pings through PPP in CrossOver mode work without
* the user having to manually configure routes. Find the two PPP
* interfaces and add routes for them. ip_init() in ip_startup()
* initializes the routing table. Hence the routes can only be added
* after ip_init(). Hence ppp_lb_add_routes() is called after
* ip_init() in ip_startup(). Returns 0 if OK, else error code of
* first error encountered.
*
*
* PARAM1: void
*
* RETURNS: 0 if OK, else negative error code.
*/
int
ppp_lb_add_routes(void)
{
void * rtp; /* result of add_route() */
int iface; /* scratch iface index */
M_PPP mp1;
M_PPP mp2;
/* first see of we can find two of these lines */
mp1 = NULL;
for(mp2 = ppp_list; mp2; mp2 = mp2->next)
{
if(mp2->line.lower_type == LN_LBXOVER)
{
if(mp1 == NULL)/* is this first line found? */
mp1 = mp2; /* yes, set it */
else /* else mp1 is already set */
break; /* exit loop with mp2 as second line */
}
}
if(!mp2) /* didn't fiond two lines? */
return ENP_LOGIC;
/* add route to second IP through first iface */
iface = if_netnumber(mp1->ifp);
rtp = add_route(mp2->ifp->n_ipaddr, 0xFFFFFFFF,
mp2->ifp->n_ipaddr, iface, IPRP_LOCAL);
if (!rtp)
{
dprintf("add_route failed, table full?\n");
return -1;
}
/* Now add the route to first IP through second iface */
iface = if_netnumber(mp2->ifp);
rtp = add_route(mp1->ifp->n_ipaddr, 0xFFFFFFFF,
mp1->ifp->n_ipaddr, iface, IPRP_LOCAL);
if (!rtp)
{
dprintf("add_route failed, table full?\n");
return -1;
}
return 0;
}
/* end of file - ppp_loop.c */
#endif /* LB_XOVER */
#endif /* USE_PPP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -