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