This is pppd_rpc.c in view mode; [Download] [Up]
//*****************************************************************************
//
// GateKeeper.c.
//
// Mach RPC server for IPC between PPPD and GateKeeper
//
// by Felipe A. Rodriguez
//
// This code is supplied "as is" the author makes no warranty as to its
// suitability for any purpose. This code is free and may be distributed
// in accordance with the terms of the:
//
// GNU GENERAL PUBLIC LICENSE
// Version 2, June 1991
// copyright (C) 1989, 1991 Free Software Foundation, Inc.
// 675 Mass Ave, Cambridge, MA 02139, USA
//
//*****************************************************************************
#import <syslog.h>
#import <mach/mach.h>
#import <mach/cthreads.h>
#import <mach/message.h>
#import <mach/mach_error.h>
#import <servers/netname.h>
#import <sys/signal.h>
#import "../../MiG/Library/pppd_rpc_defs.h"
#import "../../MiG/Library/pppd_rpc_types.h"
void server_loop(port_t port);
kern_return_t pppd_status(port_t server, int *c);
kern_return_t set_pppd(port_t server, int a);
kern_return_t die_pppd(port_t server, int a);
// defined by MiG:
boolean_t pppd_rpc_server(msg_header_t *in, msg_header_t *out);
// from Request types in *_User.c
struct message
{
msg_header_t head; /* standard header field */
msg_type_t arg1_type; /* first arg type */
int arg1; /* first arg */
msg_type_t arg2_type; /* second arg type */
int arg2; /* second arg */
};
// pppd defined
extern int phase;
extern int demand;
port_t gk_server = PORT_NULL; // gatekeeper port id
int gk_state; // status reported to gatekeeper
//*****************************************************************************
//
// listen for RPC from GateKeeper
//
//*****************************************************************************
void gk_listen(void)
{
port_t server_port;
kern_return_t r;
// allocate a port for this task, ret in arg 2
r = port_allocate(task_self(), &server_port);
if (r != KERN_SUCCESS)
{
mach_error("port_allocate failed", r);
exit(1);
}
// Register with the Network Name Server.
r = netname_check_in(name_server_port, PPPD_RPC_SERVER_NAME, PORT_NULL,
server_port);
if (r != KERN_SUCCESS)
{
mach_error("netname_check_in failed", r);
exit(1);
}
// create dial on demand server thread and detach it
cthread_detach(cthread_fork((cthread_fn_t)server_loop,(any_t)server_port));
}
//*****************************************************************************
//
// c thread loop which listens for RPC
//
//*****************************************************************************
void server_loop(port_t port)
{
struct message msg, reply;
kern_return_t ret;
while (TRUE)
{
/* Receive a request from a client. */
msg.head.msg_local_port = (port_t)port;
msg.head.msg_size = sizeof(struct message);
ret = msg_receive(&msg.head, MSG_OPTION_NONE, 0);
if (ret != RCV_SUCCESS) /* ignore errors */
continue;
/* Feed the request into the server. */
(void)pppd_rpc_server((msg_header_t *)&msg, (msg_header_t *)&reply);
/* Send a reply to the client. */
reply.head.msg_local_port = (port_t)port;
ret = msg_send(&reply.head, MSG_OPTION_NONE, 0);
if (ret != SEND_SUCCESS) /* ignore errors */
continue;
}
}
//*****************************************************************************
//
// report our state to GateKeeper
//
// This function is called by RPC server which was created by MiG.
// It is NOT directly called by any client process.
//
//*****************************************************************************
kern_return_t pppd_status(port_t server, int *c)
{
kern_return_t ret;
*c = gk_state;
// if queried for status we probably need a new connection to gk
gk_server = gk_rpc_server_look_up(); // Find the GateKeeper server.
syslog(LOG_INFO, "looking up GateKeeper RPC server");
if (gk_server == PORT_NULL)
syslog(LOG_INFO, "unable to find GateKeeper RPC server");
return KERN_SUCCESS;
}
//*****************************************************************************
//
// recieve a message from GateKeeper
//
// This function is called by RPC server which was created by MiG.
// It is NOT directly called by any client process.
//
//*****************************************************************************
kern_return_t set_pppd(port_t server, int a)
{
switch(a)
{
case GK_TERMINATE: // shutdown ppp link
syslog(LOG_INFO, "GateKeeper requested ppp session termination.");
demand = 0; // shutoff demand for the moment
lcp_close(0, "Link inactive");
demand = 1;
break;
default:
break;
}
return KERN_SUCCESS;
}
//*****************************************************************************
//
// recieve a simple async message from GateKeeper
//
// This function is called by RPC server which was created by MiG.
// It is NOT directly called by any client process.
//
//*****************************************************************************
kern_return_t die_pppd(port_t server, int a)
{
syslog(LOG_INFO, "GateKeeper requested ppp daemon termination.");
demand = 0; // shutoff demand
lcp_close(0, "Link inactive");
// demand = 1;
die(REC_TERM_REQ); // die and report reason for death
return KERN_SUCCESS;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.