server.c revision 31962
1193326Sed/*-
2193326Sed * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org>
3193326Sed * All rights reserved.
4193326Sed *
5193326Sed * Redistribution and use in source and binary forms, with or without
6193326Sed * modification, are permitted provided that the following conditions
7193326Sed * are met:
8193326Sed * 1. Redistributions of source code must retain the above copyright
9193326Sed *    notice, this list of conditions and the following disclaimer.
10193326Sed * 2. Redistributions in binary form must reproduce the above copyright
11193326Sed *    notice, this list of conditions and the following disclaimer in the
12193326Sed *    documentation and/or other materials provided with the distribution.
13193326Sed *
14193326Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15193326Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16202379Srdivacky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17198092Srdivacky * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18203955Srdivacky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19199482Srdivacky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20193326Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21193326Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22203955Srdivacky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23193326Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24193326Sed * SUCH DAMAGE.
25193326Sed *
26198092Srdivacky *	$Id: server.c,v 1.14 1997/12/21 12:11:08 brian Exp $
27193326Sed */
28193326Sed
29204643Srdivacky#include <sys/param.h>
30204643Srdivacky#include <sys/socket.h>
31204643Srdivacky#include <netinet/in.h>
32204643Srdivacky#include <arpa/inet.h>
33204643Srdivacky#include <netinet/in_systm.h>
34204643Srdivacky#include <netinet/ip.h>
35204643Srdivacky
36204643Srdivacky#include <errno.h>
37204643Srdivacky#include <stdio.h>
38204643Srdivacky#include <string.h>
39204643Srdivacky#include <sys/stat.h>
40204643Srdivacky#include <sys/un.h>
41193326Sed#include <unistd.h>
42193326Sed
43198092Srdivacky#include "command.h"
44193326Sed#include "mbuf.h"
45193326Sed#include "log.h"
46193326Sed#include "loadalias.h"
47198092Srdivacky#include "defs.h"
48193326Sed#include "vars.h"
49193326Sed#include "server.h"
50193326Sed#include "id.h"
51193326Sed
52193326Sedint server = -1;
53193326Sed
54193326Sedstatic struct sockaddr_un ifsun;
55198092Srdivackystatic char *rm;
56193326Sed
57200583Srdivackyint
58198893SrdivackyServerLocalOpen(const char *name, mode_t mask)
59193326Sed{
60200583Srdivacky  int s;
61193326Sed
62193326Sed  if (VarLocalAuth == LOCAL_DENY) {
63193326Sed    LogPrintf(LogERROR, "Local: Can't open socket %s: No password "
64200583Srdivacky	      "in ppp.secret\n", name);
65198893Srdivacky    return 1;
66200583Srdivacky  }
67193326Sed
68193326Sed  if (mode & MODE_INTER) {
69193326Sed    LogPrintf(LogERROR, "Local: Can't open socket in interactive mode\n");
70200583Srdivacky    return 1;
71193326Sed  }
72198092Srdivacky
73198092Srdivacky  memset(&ifsun, '\0', sizeof ifsun);
74193326Sed  ifsun.sun_len = strlen(name);
75198092Srdivacky  if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
76194613Sed    LogPrintf(LogERROR, "Local: %s: Path too long\n", name);
77193326Sed    return 2;
78199990Srdivacky  }
79199990Srdivacky  ifsun.sun_family = AF_LOCAL;
80200583Srdivacky  strcpy(ifsun.sun_path, name);
81198893Srdivacky
82198893Srdivacky  s = ID0socket(PF_LOCAL, SOCK_STREAM, 0);
83198893Srdivacky  if (s < 0) {
84193326Sed    LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno));
85193326Sed    return 3;
86199990Srdivacky  }
87193326Sed  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
88193326Sed  if (mask != (mode_t)-1)
89193326Sed    mask = umask(mask);
90193326Sed  if (bind(s, (struct sockaddr *)&ifsun, sizeof ifsun) < 0) {
91193326Sed    if (mask != (mode_t)-1)
92193326Sed      umask(mask);
93198092Srdivacky    LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno));
94193326Sed    if (errno == EADDRINUSE && VarTerm)
95193326Sed      fprintf(VarTerm, "Wait for a while, then try again.\n");
96199512Srdivacky    close(s);
97193326Sed    return 4;
98198092Srdivacky  }
99193326Sed  if (mask != (mode_t)-1)
100198893Srdivacky    umask(mask);
101200583Srdivacky  if (listen(s, 5) != 0) {
102198893Srdivacky    LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n");
103198893Srdivacky    close(s);
104198893Srdivacky    ID0unlink(name);
105193326Sed    return 5;
106193326Sed  }
107198092Srdivacky  ServerClose();
108193326Sed  server = s;
109198092Srdivacky  rm = ifsun.sun_path;
110198092Srdivacky  LogPrintf(LogPHASE, "Listening at local socket %s.\n", name);
111198893Srdivacky  return 0;
112198893Srdivacky}
113200583Srdivacky
114198893Srdivackyint
115198893SrdivackyServerTcpOpen(int port)
116198893Srdivacky{
117198092Srdivacky  struct sockaddr_in ifsin;
118198092Srdivacky  int s;
119198092Srdivacky
120198092Srdivacky  if (VarLocalAuth == LOCAL_DENY) {
121193326Sed    LogPrintf(LogERROR, "Tcp: Can't open socket %d: No password "
122193326Sed	      "in ppp.secret\n", port);
123193326Sed    return 6;
124199482Srdivacky  }
125199482Srdivacky
126202379Srdivacky  if (mode & MODE_INTER) {
127202379Srdivacky    LogPrintf(LogERROR, "Tcp: Can't open socket in interactive mode\n");
128198092Srdivacky    return 6;
129199482Srdivacky  }
130204643Srdivacky
131198092Srdivacky  s = ID0socket(PF_INET, SOCK_STREAM, 0);
132199990Srdivacky  if (s < 0) {
133193326Sed    LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno));
134199482Srdivacky    return 7;
135206084Srdivacky  }
136206084Srdivacky  memset(&ifsin, '\0', sizeof ifsin);
137199482Srdivacky  ifsin.sin_family = AF_INET;
138193326Sed  ifsin.sin_addr.s_addr = INADDR_ANY;
139193326Sed  ifsin.sin_port = htons(port);
140193326Sed  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
141198092Srdivacky  if (bind(s, (struct sockaddr *)&ifsin, sizeof ifsin) < 0) {
142193326Sed    LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno));
143203955Srdivacky    if (errno == EADDRINUSE && VarTerm)
144203955Srdivacky      fprintf(VarTerm, "Wait for a while, then try again.\n");
145199990Srdivacky    close(s);
146199990Srdivacky    return 8;
147199990Srdivacky  }
148193326Sed  if (listen(s, 5) != 0) {
149193326Sed    LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n");
150202379Srdivacky    close(s);
151202379Srdivacky    return 9;
152202379Srdivacky  }
153204643Srdivacky  ServerClose();
154204643Srdivacky  server = s;
155199482Srdivacky  LogPrintf(LogPHASE, "Listening at port %d.\n", port);
156199482Srdivacky  return 0;
157198092Srdivacky}
158193326Sed
159193326Sedvoid
160198092SrdivackyServerClose()
161207619Srdivacky{
162207619Srdivacky  if (server >= 0) {
163193326Sed    close(server);
164193326Sed    if (rm) {
165198092Srdivacky      ID0unlink(rm);
166193326Sed      rm = 0;
167193326Sed    }
168198092Srdivacky  }
169199482Srdivacky  server = -1;
170199482Srdivacky}
171199482Srdivacky