xref: /freebsd/usr.sbin/ppp/server.c (revision 33b77e2decd50e53798014b70bf7ca3bdc4c0c7e)
1 /*-
2  * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *	$Id: server.c,v 1.14 1997/12/21 12:11:08 brian Exp $
27  */
28 
29 #include <sys/param.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <netinet/in_systm.h>
34 #include <netinet/ip.h>
35 
36 #include <errno.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <sys/stat.h>
40 #include <sys/un.h>
41 #include <unistd.h>
42 
43 #include "command.h"
44 #include "mbuf.h"
45 #include "log.h"
46 #include "loadalias.h"
47 #include "defs.h"
48 #include "vars.h"
49 #include "server.h"
50 #include "id.h"
51 
52 int server = -1;
53 
54 static struct sockaddr_un ifsun;
55 static char *rm;
56 
57 int
58 ServerLocalOpen(const char *name, mode_t mask)
59 {
60   int s;
61 
62   if (VarLocalAuth == LOCAL_DENY) {
63     LogPrintf(LogERROR, "Local: Can't open socket %s: No password "
64 	      "in ppp.secret\n", name);
65     return 1;
66   }
67 
68   if (mode & MODE_INTER) {
69     LogPrintf(LogERROR, "Local: Can't open socket in interactive mode\n");
70     return 1;
71   }
72 
73   memset(&ifsun, '\0', sizeof ifsun);
74   ifsun.sun_len = strlen(name);
75   if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
76     LogPrintf(LogERROR, "Local: %s: Path too long\n", name);
77     return 2;
78   }
79   ifsun.sun_family = AF_LOCAL;
80   strcpy(ifsun.sun_path, name);
81 
82   s = ID0socket(PF_LOCAL, SOCK_STREAM, 0);
83   if (s < 0) {
84     LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno));
85     return 3;
86   }
87   setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
88   if (mask != (mode_t)-1)
89     mask = umask(mask);
90   if (bind(s, (struct sockaddr *)&ifsun, sizeof ifsun) < 0) {
91     if (mask != (mode_t)-1)
92       umask(mask);
93     LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno));
94     if (errno == EADDRINUSE && VarTerm)
95       fprintf(VarTerm, "Wait for a while, then try again.\n");
96     close(s);
97     return 4;
98   }
99   if (mask != (mode_t)-1)
100     umask(mask);
101   if (listen(s, 5) != 0) {
102     LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n");
103     close(s);
104     ID0unlink(name);
105     return 5;
106   }
107   ServerClose();
108   server = s;
109   rm = ifsun.sun_path;
110   LogPrintf(LogPHASE, "Listening at local socket %s.\n", name);
111   return 0;
112 }
113 
114 int
115 ServerTcpOpen(int port)
116 {
117   struct sockaddr_in ifsin;
118   int s;
119 
120   if (VarLocalAuth == LOCAL_DENY) {
121     LogPrintf(LogERROR, "Tcp: Can't open socket %d: No password "
122 	      "in ppp.secret\n", port);
123     return 6;
124   }
125 
126   if (mode & MODE_INTER) {
127     LogPrintf(LogERROR, "Tcp: Can't open socket in interactive mode\n");
128     return 6;
129   }
130 
131   s = ID0socket(PF_INET, SOCK_STREAM, 0);
132   if (s < 0) {
133     LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno));
134     return 7;
135   }
136   memset(&ifsin, '\0', sizeof ifsin);
137   ifsin.sin_family = AF_INET;
138   ifsin.sin_addr.s_addr = INADDR_ANY;
139   ifsin.sin_port = htons(port);
140   setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
141   if (bind(s, (struct sockaddr *)&ifsin, sizeof ifsin) < 0) {
142     LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno));
143     if (errno == EADDRINUSE && VarTerm)
144       fprintf(VarTerm, "Wait for a while, then try again.\n");
145     close(s);
146     return 8;
147   }
148   if (listen(s, 5) != 0) {
149     LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n");
150     close(s);
151     return 9;
152   }
153   ServerClose();
154   server = s;
155   LogPrintf(LogPHASE, "Listening at port %d.\n", port);
156   return 0;
157 }
158 
159 void
160 ServerClose()
161 {
162   if (server >= 0) {
163     close(server);
164     if (rm) {
165       ID0unlink(rm);
166       rm = 0;
167     }
168   }
169   server = -1;
170 }
171