Add "set server" to control the server socket.

Catch SIGUSR1 to re-init listening socket.
Document signal behaviour.

Add missing '\n's to LogPrintf(LogWARN,...)
Main() returns int not void.

AF_LOCAL ideal suggested a long time ago by: joerg
This commit is contained in:
Brian Somers 1997-06-25 19:30:05 +00:00
parent 7a1d27b301
commit 4ef16f24f2
10 changed files with 361 additions and 74 deletions

View File

@ -1,10 +1,10 @@
# $Id: Makefile,v 1.20 1997/05/26 00:43:54 brian Exp $
# $Id: Makefile,v 1.21 1997/06/09 03:27:10 brian Exp $
PROG= ppp
SRCS= alias_cmd.c arp.c async.c auth.c ccp.c chap.c chat.c command.c \
filter.c fsm.c hdlc.c ip.c ipcp.c lcp.c loadalias.c log.c lqr.c \
main.c mbuf.c modem.c os.c pap.c passwdauth.c pred.c route.c sig.c \
slcompress.c systems.c timer.c vars.c vjcomp.c
main.c mbuf.c modem.c os.c pap.c passwdauth.c pred.c route.c \
server.c sig.c slcompress.c systems.c timer.c vars.c vjcomp.c
CFLAGS+=-Wall
LDADD+= -lmd -lcrypt -lutil
DPADD+= ${LIBMD} ${LIBCRYPT} ${LIBUTIL}

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: command.c,v 1.61 1997/06/23 23:10:07 brian Exp $
* $Id: command.c,v 1.62 1997/06/25 02:04:35 brian Exp $
*
*/
#include <sys/types.h>
@ -49,6 +49,7 @@
#include "chat.h"
#include "os.h"
#include "timeout.h"
#include "server.h"
extern void Cleanup(), TtyTermMode(), PacketMode();
extern int EnableCommand(), DisableCommand(), DisplayCommand();
@ -842,6 +843,27 @@ char **argv;
return -1;
}
static int
SetServer(list, argc, argv)
struct cmdtab *list;
int argc;
char **argv;
{
int res = -1;
if (argc == 1)
if (strcasecmp(argv[0], "none") == 0) {
ServerClose();
LogPrintf(LogPHASE, "Disabling server port.\n");
res = 0;
} else if (*argv[0] == '/')
res = ServerLocalOpen(argv[0]);
else if (strspn(argv[0], "0123456789") == strlen(argv[0]))
res = ServerTcpOpen(atoi(argv[0]));
return res;
}
static int
SetModemParity(list, argc, argv)
struct cmdtab *list;
@ -1245,6 +1267,8 @@ struct cmdtab const SetCommands[] = {
"Set Reconnect timeout", "set reconnect value ntries"},
{ "redial", NULL, SetRedialTimeout, LOCAL_AUTH,
"Set Redial timeout", "set redial value|random[.value|random] [dial_attempts]"},
{ "server", "socket", SetServer, LOCAL_AUTH,
"Set server port", "set server|socket TcpPort|LocalName|none"},
{ "speed", NULL, SetModemSpeed, LOCAL_AUTH,
"Set modem speed", "set speed value"},
{ "timeout", NULL, SetIdleTimeout, LOCAL_AUTH,

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ipcp.c,v 1.20 1997/05/26 00:44:01 brian Exp $
* $Id: ipcp.c,v 1.21 1997/06/09 03:27:24 brian Exp $
*
* TODO:
* o More RFC1772 backwoard compatibility
@ -394,7 +394,7 @@ int mode;
switch (length) {
case 4: /* RFC1172 */
if (ntohs(pcomp->proto) == PROTO_VJCOMP) {
LogPrintf(LogWARN, "Peer is speaking RFC1172 compression protocol !n");
LogPrintf(LogWARN, "Peer is speaking RFC1172 compression protocol !\n");
IpcpInfo.heis1172 = 1;
IpcpInfo.his_compproto = compproto;
bcopy(cp, ackp, length);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: main.c,v 1.65 1997/06/23 23:10:11 brian Exp $
* $Id: main.c,v 1.66 1997/06/24 21:25:06 brian Exp $
*
* TODO:
* o Add commands for traffic summary, version display, etc.
@ -50,6 +50,7 @@
#include "systems.h"
#include "ip.h"
#include "sig.h"
#include "server.h"
#define LAUTH_M1 "Warning: No password entry for this host in ppp.secret\n"
#define LAUTH_M2 "Warning: Manipulation is allowed by anyone\n"
@ -74,9 +75,7 @@ static char *ex_desc();
static struct termios oldtio; /* Original tty mode */
static struct termios comtio; /* Command level tty mode */
int TermMode;
static int server;
static pid_t BGPid = 0;
struct sockaddr_in ifsin;
static char pid_filename[MAXPATHLEN];
static char if_filename[MAXPATHLEN];
int tunno;
@ -185,11 +184,7 @@ int excode;
}
LogPrintf(LogPHASE, "PPP Terminated (%s).\n",ex_desc(excode));
LogClose();
if (server >= 0) {
close(server);
server = -1;
}
ServerClose();
TtyOldMode();
exit(excode);
@ -236,6 +231,15 @@ int signo;
kill(getpid(), signo);
}
static void
SetUpServer(signo)
int signo;
{
int res;
if ((res = ServerTcpOpen(SERVER_PORT+tunno)) != 0)
LogPrintf(LogERROR, "Failed %d to open port %d\n", res, SERVER_PORT+tunno);
}
static char *
ex_desc(int ex)
{
@ -310,7 +314,7 @@ Greetings()
}
}
void
int
main(argc, argv)
int argc;
char **argv;
@ -324,7 +328,8 @@ char **argv;
argc--; argv++;
mode = MODE_INTER; /* default operation is interactive mode */
netfd = server = modem = tun_in = -1;
netfd = modem = tun_in = -1;
server = -2;
ProcessArgs(argc, argv);
if (!(mode & MODE_DIRECT))
VarTerm = stdout;
@ -335,24 +340,9 @@ char **argv;
if (SelectSystem("default", CONFFILE) < 0 && VarTerm)
fprintf(VarTerm, "Warning: No default entry is given in config file.\n");
switch ( LocalAuthInit() ) {
case NOT_FOUND:
if (VarTerm) {
fprintf(VarTerm,LAUTH_M1);
fprintf(VarTerm,LAUTH_M2);
fflush(VarTerm);
}
/* Fall down */
case VALID:
VarLocalAuth = LOCAL_AUTH;
break;
default:
break;
}
if (OpenTunnel(&tunno) < 0) {
LogPrintf(LogWARN, "open_tun: %s", strerror(errno));
exit(EX_START);
LogPrintf(LogWARN, "open_tun: %s\n", strerror(errno));
return EX_START;
}
if (mode & (MODE_AUTO|MODE_DIRECT|MODE_DEDICATED))
@ -366,7 +356,7 @@ char **argv;
if (VarTerm)
fprintf(VarTerm, "Destination system must be specified in"
" auto, background or ddial mode.\n");
exit(EX_START);
return EX_START;
}
}
@ -382,18 +372,21 @@ char **argv;
#ifdef SIGALRM
pending_signal(SIGALRM, SIG_IGN);
#endif
if(mode & MODE_INTER)
{
if(mode & MODE_INTER) {
#ifdef SIGTSTP
pending_signal(SIGTSTP, TerminalStop);
pending_signal(SIGTSTP, TerminalStop);
#endif
#ifdef SIGTTIN
pending_signal(SIGTTIN, TerminalStop);
pending_signal(SIGTTIN, TerminalStop);
#endif
#ifdef SIGTTOU
pending_signal(SIGTTOU, SIG_IGN);
pending_signal(SIGTTOU, SIG_IGN);
#endif
}
#ifdef SIGUSR1
if (mode != MODE_INTER)
pending_signal(SIGUSR1, SetUpServer);
#endif
}
if (dstsystem) {
if (SelectSystem(dstsystem, CONFFILE) < 0) {
@ -407,9 +400,23 @@ char **argv;
}
}
if (!(mode & MODE_INTER)) {
int port = SERVER_PORT + tunno;
if (ServerType() != NO_SERVER)
switch ( LocalAuthInit() ) {
case NOT_FOUND:
if (VarTerm) {
fprintf(VarTerm,LAUTH_M1);
fprintf(VarTerm,LAUTH_M2);
fflush(VarTerm);
}
/* Fall down */
case VALID:
VarLocalAuth = LOCAL_AUTH;
break;
default:
break;
}
if (!(mode & MODE_INTER)) {
if (mode & MODE_BACKGROUND) {
if (pipe (BGFiledes)) {
LogPrintf(LogERROR, "pipe: %s", strerror(errno));
@ -417,26 +424,9 @@ char **argv;
}
}
/* Create server socket and listen at there. */
server = socket(PF_INET, SOCK_STREAM, 0);
if (server < 0) {
LogPrintf(LogERROR, "socket: %s", strerror(errno));
Cleanup(EX_SOCK);
}
ifsin.sin_family = AF_INET;
ifsin.sin_addr.s_addr = INADDR_ANY;
ifsin.sin_port = htons(port);
setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &server, sizeof server);
if (bind(server, (struct sockaddr *) &ifsin, sizeof(ifsin)) < 0) {
LogPrintf(LogERROR, "bind: %s", strerror(errno));
if (errno == EADDRINUSE && VarTerm)
fprintf(VarTerm, "Wait for a while, then try again.\n");
Cleanup(EX_SOCK);
}
if (listen(server, 5) != 0) {
LogPrintf(LogERROR, "Unable to listen to socket - OS overload?\n");
Cleanup(EX_SOCK);
}
/* Create server socket and listen. */
if (server == -2 && ServerTcpOpen(SERVER_PORT + tunno) != 0)
Cleanup(EX_SOCK);
if (!(mode & MODE_DIRECT)) {
pid_t bgpid;
@ -466,7 +456,7 @@ char **argv;
}
close(BGFiledes[0]);
}
exit(c);
return c;
} else if (mode & MODE_BACKGROUND)
close(BGFiledes[0]);
}
@ -493,9 +483,6 @@ char **argv;
LogPrintf(LogALERT, "Warning: Can't create %s: %s\n",
if_filename, strerror(errno));
if (server >= 0)
LogPrintf(LogPHASE, "Listening at %d.\n", port);
VarTerm = 0; /* We know it's currently stdout */
close(0);
close(2);
@ -522,6 +509,7 @@ char **argv;
while (mode & MODE_DEDICATED);
Cleanup(EX_DONE);
return 0;
}
/*

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: mbuf.c,v 1.6 1997/05/10 01:22:15 brian Exp $
* $Id: mbuf.c,v 1.7 1997/06/09 03:27:29 brian Exp $
*
*/
#include <sys/types.h>
@ -27,6 +27,7 @@
#include "defs.h"
#include "loadalias.h"
#include "vars.h"
#include "server.h"
struct memmap {
struct mbuf *queue;
@ -59,12 +60,14 @@ int type;
bp = (struct mbuf *)malloc(sizeof(struct mbuf));
if (bp == NULL) {
LogPrintf(LogALERT, "failed to allocate memory: %u\n", sizeof(struct mbuf));
ServerClose();
exit(1);
}
bzero(bp, sizeof(struct mbuf));
p = (u_char *)malloc(cnt);
if (p == NULL) {
LogPrintf(LogALERT, "failed to allocate memory: %d\n", cnt);
ServerClose();
exit(1);
}
MemMap[type].count += cnt;

View File

@ -1,4 +1,4 @@
.\" $Id: ppp.8,v 1.40 1997/06/16 13:52:10 brian Exp $
.\" $Id: ppp.8,v 1.41 1997/06/20 23:43:34 brian Exp $
.Dd 20 September 1995
.Os FreeBSD
.Dt PPP 8
@ -637,8 +637,9 @@ Direct mode (
.Fl direct
) lets
.Nm
work with stdin and stdout. You can also telnet to port 3000 to get
command mode control in the same manner as client-side
work with stdin and stdout. You can also telnet to port 3000 plus
the current tunnel device number to get command mode control in the
same manner as client-side
.Nm.
.It
@ -1260,6 +1261,52 @@ Log messages of level Warning, Error and Alert are not controlable
using
.Dq set log .
.Sh SIGNAL HANDLING
.Nm Ppp
deals with the following signals:
.Bl -tag -width 20
.It HUP
Receipt of this signal causes the termination of the current connection
(if any). This will cause
.Nm
to exit unless it is in
.Fl auto
or
.Fl ddial
mode. It should be noted that unless in
.Fl direct
mode,
.Nm
does not have a controlling terminal and therefore doesn't receive
this signal on loss of carrier. Instead, it monitors the line
directly for loss of carrier.
.It INT
This signal will normally terminate
.Nm ppp .
If, however,
.Nm
is in interactive mode this signal will be ignored except when dialing.
When dialing, the signal causes
.Nm
to abort dialing and return to the command prompt.
.It TERM & QUIT
These signals tell
.Nm
to exit.
.It USR1
This signal, when not in interactive mode, tells
.Nm
to close any existing server socket and open an internet socket using
the default rules for choosing a port number - that is, using port
3000 plus the current tunnel device number.
.El
.Sh PPP COMMAND LIST
This section lists the available commands and their effect. They are
@ -1617,6 +1664,26 @@ is taken before starting at the first number again. A value of
.Dq random
may be used here too.
.It set server|socket TcpPort|LocalName|none
Normally, when not in interactive mode,
.Nm
listens to a tcp socket for incoming command connections. The
socket number is calculated as 3000 plus the number of the
tunnel device that
.Nm
opened. So, for example, if
.Nm
opened tun2, socket 3002 would be used.
.Pp
Using this command, you can specify your own port number, a
local domain socket (specified as an absolute file name), or
you can tell
.Nm
not to accept any command connections. See also the use of
the
.Dv USR1
signal.
.It set speed value
This sets the speed of the serial device.

View File

@ -1,4 +1,4 @@
.\" $Id: ppp.8,v 1.40 1997/06/16 13:52:10 brian Exp $
.\" $Id: ppp.8,v 1.41 1997/06/20 23:43:34 brian Exp $
.Dd 20 September 1995
.Os FreeBSD
.Dt PPP 8
@ -637,8 +637,9 @@ Direct mode (
.Fl direct
) lets
.Nm
work with stdin and stdout. You can also telnet to port 3000 to get
command mode control in the same manner as client-side
work with stdin and stdout. You can also telnet to port 3000 plus
the current tunnel device number to get command mode control in the
same manner as client-side
.Nm.
.It
@ -1260,6 +1261,52 @@ Log messages of level Warning, Error and Alert are not controlable
using
.Dq set log .
.Sh SIGNAL HANDLING
.Nm Ppp
deals with the following signals:
.Bl -tag -width 20
.It HUP
Receipt of this signal causes the termination of the current connection
(if any). This will cause
.Nm
to exit unless it is in
.Fl auto
or
.Fl ddial
mode. It should be noted that unless in
.Fl direct
mode,
.Nm
does not have a controlling terminal and therefore doesn't receive
this signal on loss of carrier. Instead, it monitors the line
directly for loss of carrier.
.It INT
This signal will normally terminate
.Nm ppp .
If, however,
.Nm
is in interactive mode this signal will be ignored except when dialing.
When dialing, the signal causes
.Nm
to abort dialing and return to the command prompt.
.It TERM & QUIT
These signals tell
.Nm
to exit.
.It USR1
This signal, when not in interactive mode, tells
.Nm
to close any existing server socket and open an internet socket using
the default rules for choosing a port number - that is, using port
3000 plus the current tunnel device number.
.El
.Sh PPP COMMAND LIST
This section lists the available commands and their effect. They are
@ -1617,6 +1664,26 @@ is taken before starting at the first number again. A value of
.Dq random
may be used here too.
.It set server|socket TcpPort|LocalName|none
Normally, when not in interactive mode,
.Nm
listens to a tcp socket for incoming command connections. The
socket number is calculated as 3000 plus the number of the
tunnel device that
.Nm
opened. So, for example, if
.Nm
opened tun2, socket 3002 would be used.
.Pp
Using this command, you can specify your own port number, a
local domain socket (specified as an absolute file name), or
you can tell
.Nm
not to accept any command connections. See also the use of
the
.Dv USR1
signal.
.It set speed value
This sets the speed of the serial device.

120
usr.sbin/ppp/server.c Normal file
View File

@ -0,0 +1,120 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include "mbuf.h"
#include "log.h"
#include "loadalias.h"
#include "vars.h"
#include "server.h"
int server = UNKNOWN_SERVER;
static struct sockaddr_un ifsun;
static char *rm;
int
ServerLocalOpen(const char *name)
{
int s;
ifsun.sun_len = strlen(name);
if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
LogPrintf(LogERROR, "Local: %s: Path too long\n", name);
return 1;
}
ifsun.sun_family = AF_LOCAL;
strcpy(ifsun.sun_path, name);
s = socket(PF_LOCAL, SOCK_STREAM, 0);
if (s < 0) {
LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno));
return 2;
}
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
if (bind(s, (struct sockaddr *) &ifsun, sizeof(ifsun)) < 0) {
LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno));
if (errno == EADDRINUSE && VarTerm)
fprintf(VarTerm, "Wait for a while, then try again.\n");
close(s);
unlink(name);
return 3;
}
if (listen(s, 5) != 0) {
LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n");
close(s);
unlink(name);
return 4;
}
ServerClose();
server = s;
rm = ifsun.sun_path;
LogPrintf(LogPHASE, "Listening at local socket %s.\n", name);
return 0;
}
int
ServerTcpOpen(int port)
{
struct sockaddr_in ifsin;
int s;
s = socket(PF_INET, SOCK_STREAM, 0);
if (s < 0) {
LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno));
return 5;
}
ifsin.sin_family = AF_INET;
ifsin.sin_addr.s_addr = INADDR_ANY;
ifsin.sin_port = htons(port);
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
if (bind(s, (struct sockaddr *) &ifsin, sizeof(ifsin)) < 0) {
LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno));
if (errno == EADDRINUSE && VarTerm)
fprintf(VarTerm, "Wait for a while, then try again.\n");
close(s);
return 6;
}
if (listen(s, 5) != 0) {
LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n");
close(s);
return 7;
}
ServerClose();
server = s;
LogPrintf(LogPHASE, "Listening at port %d.\n", port);
return 0;
}
void
ServerClose()
{
if (server >= 0) {
close(server);
if (rm) {
unlink(rm);
rm = 0;
}
}
server = -1;
}
int
ServerType()
{
if (server == UNKNOWN_SERVER)
return UNKNOWN_SERVER;
else if (server == NO_SERVER)
return NO_SERVER;
else if (rm)
return LOCAL_SERVER;
else
return INET_SERVER;
}

12
usr.sbin/ppp/server.h Normal file
View File

@ -0,0 +1,12 @@
extern int server;
extern int ServerLocalOpen(const char *name);
extern int ServerTcpOpen(int);
extern void ServerClose(void);
#define UNKNOWN_SERVER (-2)
#define NO_SERVER (-1)
#define LOCAL_SERVER (1)
#define INET_SERVER (2)
extern int ServerType(void);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: systems.c,v 1.11 1997/05/26 00:44:09 brian Exp $
* $Id: systems.c,v 1.12 1997/06/09 03:27:38 brian Exp $
*
* TODO:
*/
@ -27,6 +27,7 @@
#include "ipcp.h"
#include "pathnames.h"
#include "vars.h"
#include "server.h"
extern void DecodeCommand();
@ -56,10 +57,12 @@ SetUserId()
if (!usermode) {
if (setreuid(euid, uid) == -1) {
LogPrintf(LogERROR, "unable to setreuid!\n");
ServerClose();
exit(1);
}
if (setregid(egid, gid) == -1) {
LogPrintf(LogERROR, "unable to setregid!\n");
ServerClose();
exit(1);
}
usermode = 1;
@ -72,10 +75,12 @@ SetPppId()
if (usermode) {
if (setreuid(uid, euid) == -1) {
LogPrintf(LogERROR, "unable to setreuid!\n");
ServerClose();
exit(1);
}
if (setregid(gid, egid) == -1) {
LogPrintf(LogERROR, "unable to setregid!\n");
ServerClose();
exit(1);
}
usermode = 0;
@ -165,6 +170,7 @@ char *file;
if (wp == NULL) {
LogPrintf(LogWARN, "Bad rule in %s (line %d) - missing colon.\n",
filename, linenum);
ServerClose();
exit(1);
}
*wp = '\0';