xref: /freebsd/usr.sbin/ppp/server.c (revision 02f2e93b60c2b91feac8f45c4c889a5a8e40d8a2)
1 /*
2  * $Id: $
3  */
4 
5 #include <sys/param.h>
6 #include <sys/socket.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <netinet/in_systm.h>
10 #include <netinet/ip.h>
11 
12 #include <errno.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <sys/stat.h>
16 #include <sys/un.h>
17 #include <unistd.h>
18 
19 #include "mbuf.h"
20 #include "log.h"
21 #include "loadalias.h"
22 #include "command.h"
23 #include "vars.h"
24 #include "server.h"
25 #include "log.h"
26 #include "defs.h"
27 
28 int server = -2;
29 
30 static struct sockaddr_un ifsun;
31 static char *rm;
32 
33 int
34 ServerLocalOpen(const char *name, mode_t mask)
35 {
36   int s;
37 
38   if (VarLocalAuth == LOCAL_DENY) {
39     LogPrintf(LogERROR, "Local: Can't open socket %s: No password "
40 	      "in ppp.secret\n", name);
41     return 1;
42   }
43 
44   if (!(mode&(MODE_AUTO|MODE_DEDICATED|MODE_DIRECT))) {
45     LogPrintf(LogERROR, "Local: Can't open socket in interactive mode\n");
46     return 1;
47   }
48 
49   ifsun.sun_len = strlen(name);
50   if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
51     LogPrintf(LogERROR, "Local: %s: Path too long\n", name);
52     return 2;
53   }
54   ifsun.sun_family = AF_LOCAL;
55   strcpy(ifsun.sun_path, name);
56 
57   s = socket(PF_LOCAL, SOCK_STREAM, 0);
58   if (s < 0) {
59     LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno));
60     return 3;
61   }
62   setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
63   mask = umask(mask);
64   if (bind(s, (struct sockaddr *) & ifsun, sizeof(ifsun)) < 0) {
65     umask(mask);
66     LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno));
67     if (errno == EADDRINUSE && VarTerm)
68       fprintf(VarTerm, "Wait for a while, then try again.\n");
69     close(s);
70     unlink(name);
71     return 4;
72   }
73   umask(mask);
74   if (listen(s, 5) != 0) {
75     LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n");
76     close(s);
77     unlink(name);
78     return 5;
79   }
80   ServerClose();
81   server = s;
82   rm = ifsun.sun_path;
83   LogPrintf(LogPHASE, "Listening at local socket %s.\n", name);
84   return 0;
85 }
86 
87 int
88 ServerTcpOpen(int port)
89 {
90   struct sockaddr_in ifsin;
91   int s;
92 
93   if (VarLocalAuth == LOCAL_DENY) {
94     LogPrintf(LogERROR, "Tcp: Can't open socket %d: No password "
95 	      "in ppp.secret\n", port);
96     return 6;
97   }
98 
99   if (!(mode&(MODE_AUTO|MODE_DEDICATED|MODE_DIRECT))) {
100     LogPrintf(LogERROR, "Tcp: Can't open socket in interactive mode\n");
101     return 6;
102   }
103 
104   s = socket(PF_INET, SOCK_STREAM, 0);
105   if (s < 0) {
106     LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno));
107     return 7;
108   }
109   ifsin.sin_family = AF_INET;
110   ifsin.sin_addr.s_addr = INADDR_ANY;
111   ifsin.sin_port = htons(port);
112   setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
113   if (bind(s, (struct sockaddr *) & ifsin, sizeof(ifsin)) < 0) {
114     LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno));
115     if (errno == EADDRINUSE && VarTerm)
116       fprintf(VarTerm, "Wait for a while, then try again.\n");
117     close(s);
118     return 8;
119   }
120   if (listen(s, 5) != 0) {
121     LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n");
122     close(s);
123     return 9;
124   }
125   ServerClose();
126   server = s;
127   LogPrintf(LogPHASE, "Listening at port %d.\n", port);
128   return 0;
129 }
130 
131 void
132 ServerClose()
133 {
134   if (server >= 0) {
135     close(server);
136     if (rm) {
137       unlink(rm);
138       rm = 0;
139     }
140   }
141   server = -1;
142 }
143