server.c revision 31121
130715Sbrian/*
231121Sbrian * $Id: server.c,v 1.9 1997/11/09 22:07:29 brian Exp $
330715Sbrian */
430715Sbrian
530715Sbrian#include <sys/param.h>
626940Sbrian#include <sys/socket.h>
726940Sbrian#include <netinet/in.h>
826940Sbrian#include <arpa/inet.h>
926940Sbrian#include <netinet/in_systm.h>
1026940Sbrian#include <netinet/ip.h>
1130715Sbrian
1230715Sbrian#include <errno.h>
1330715Sbrian#include <stdio.h>
1426940Sbrian#include <string.h>
1530715Sbrian#include <sys/stat.h>
1630715Sbrian#include <sys/un.h>
1726940Sbrian#include <unistd.h>
1830715Sbrian
1926940Sbrian#include "mbuf.h"
2026940Sbrian#include "log.h"
2126940Sbrian#include "loadalias.h"
2230715Sbrian#include "command.h"
2331070Sbrian#include "defs.h"
2426940Sbrian#include "vars.h"
2526940Sbrian#include "server.h"
2630715Sbrian#include "log.h"
2731061Sbrian#include "id.h"
2826940Sbrian
2931081Sbrianint server = -1;
3030715Sbrian
3126940Sbrianstatic struct sockaddr_un ifsun;
3226940Sbrianstatic char *rm;
3326940Sbrian
3426940Sbrianint
3527089SbrianServerLocalOpen(const char *name, mode_t mask)
3626940Sbrian{
3728679Sbrian  int s;
3826940Sbrian
3929083Sbrian  if (VarLocalAuth == LOCAL_DENY) {
4029083Sbrian    LogPrintf(LogERROR, "Local: Can't open socket %s: No password "
4129083Sbrian	      "in ppp.secret\n", name);
4229083Sbrian    return 1;
4329083Sbrian  }
4429083Sbrian
4531121Sbrian  if (mode & MODE_INTER) {
4629252Sbrian    LogPrintf(LogERROR, "Local: Can't open socket in interactive mode\n");
4729252Sbrian    return 1;
4829252Sbrian  }
4929252Sbrian
5028679Sbrian  ifsun.sun_len = strlen(name);
5128679Sbrian  if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
5228679Sbrian    LogPrintf(LogERROR, "Local: %s: Path too long\n", name);
5329083Sbrian    return 2;
5428679Sbrian  }
5528679Sbrian  ifsun.sun_family = AF_LOCAL;
5628679Sbrian  strcpy(ifsun.sun_path, name);
5726940Sbrian
5831061Sbrian  s = ID0socket(PF_LOCAL, SOCK_STREAM, 0);
5928679Sbrian  if (s < 0) {
6028679Sbrian    LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno));
6129083Sbrian    return 3;
6228679Sbrian  }
6328679Sbrian  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
6431081Sbrian  if (mask != (mode_t)-1)
6531081Sbrian    mask = umask(mask);
6628679Sbrian  if (bind(s, (struct sockaddr *) & ifsun, sizeof(ifsun)) < 0) {
6731081Sbrian    if (mask != (mode_t)-1)
6831081Sbrian      umask(mask);
6928679Sbrian    LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno));
7028679Sbrian    if (errno == EADDRINUSE && VarTerm)
7128679Sbrian      fprintf(VarTerm, "Wait for a while, then try again.\n");
7228679Sbrian    close(s);
7331061Sbrian    ID0unlink(name);
7429083Sbrian    return 4;
7528679Sbrian  }
7631081Sbrian  if (mask != (mode_t)-1)
7731081Sbrian    umask(mask);
7828679Sbrian  if (listen(s, 5) != 0) {
7928679Sbrian    LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n");
8028679Sbrian    close(s);
8131061Sbrian    ID0unlink(name);
8229083Sbrian    return 5;
8328679Sbrian  }
8428679Sbrian  ServerClose();
8528679Sbrian  server = s;
8628679Sbrian  rm = ifsun.sun_path;
8728679Sbrian  LogPrintf(LogPHASE, "Listening at local socket %s.\n", name);
8828679Sbrian  return 0;
8926940Sbrian}
9026940Sbrian
9126940Sbrianint
9226940SbrianServerTcpOpen(int port)
9326940Sbrian{
9428679Sbrian  struct sockaddr_in ifsin;
9528679Sbrian  int s;
9626940Sbrian
9729083Sbrian  if (VarLocalAuth == LOCAL_DENY) {
9829083Sbrian    LogPrintf(LogERROR, "Tcp: Can't open socket %d: No password "
9929083Sbrian	      "in ppp.secret\n", port);
10029083Sbrian    return 6;
10129083Sbrian  }
10229252Sbrian
10331121Sbrian  if (mode & MODE_INTER) {
10429252Sbrian    LogPrintf(LogERROR, "Tcp: Can't open socket in interactive mode\n");
10529252Sbrian    return 6;
10629252Sbrian  }
10729252Sbrian
10831061Sbrian  s = ID0socket(PF_INET, SOCK_STREAM, 0);
10928679Sbrian  if (s < 0) {
11028679Sbrian    LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno));
11129083Sbrian    return 7;
11228679Sbrian  }
11328679Sbrian  ifsin.sin_family = AF_INET;
11428679Sbrian  ifsin.sin_addr.s_addr = INADDR_ANY;
11528679Sbrian  ifsin.sin_port = htons(port);
11628679Sbrian  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
11728679Sbrian  if (bind(s, (struct sockaddr *) & ifsin, sizeof(ifsin)) < 0) {
11828679Sbrian    LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno));
11928679Sbrian    if (errno == EADDRINUSE && VarTerm)
12028679Sbrian      fprintf(VarTerm, "Wait for a while, then try again.\n");
12128679Sbrian    close(s);
12229083Sbrian    return 8;
12328679Sbrian  }
12428679Sbrian  if (listen(s, 5) != 0) {
12528679Sbrian    LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n");
12628679Sbrian    close(s);
12729083Sbrian    return 9;
12828679Sbrian  }
12928679Sbrian  ServerClose();
13028679Sbrian  server = s;
13128679Sbrian  LogPrintf(LogPHASE, "Listening at port %d.\n", port);
13228679Sbrian  return 0;
13326940Sbrian}
13426940Sbrian
13526940Sbrianvoid
13626940SbrianServerClose()
13726940Sbrian{
13826940Sbrian  if (server >= 0) {
13926940Sbrian    close(server);
14026940Sbrian    if (rm) {
14131061Sbrian      ID0unlink(rm);
14226940Sbrian      rm = 0;
14326940Sbrian    }
14426940Sbrian  }
14526940Sbrian  server = -1;
14626940Sbrian}
147