xref: /freebsd/usr.sbin/ppp/server.c (revision 4ef16f24f2988b98735ee55ba3927d36f15650a9)
14ef16f24SBrian Somers #include <sys/types.h>
24ef16f24SBrian Somers #include <sys/socket.h>
34ef16f24SBrian Somers #include <netinet/in.h>
44ef16f24SBrian Somers #include <sys/un.h>
54ef16f24SBrian Somers #include <arpa/inet.h>
64ef16f24SBrian Somers #include <netinet/in_systm.h>
74ef16f24SBrian Somers #include <netinet/ip.h>
84ef16f24SBrian Somers #include <string.h>
94ef16f24SBrian Somers #include <stdio.h>
104ef16f24SBrian Somers #include <errno.h>
114ef16f24SBrian Somers #include <unistd.h>
124ef16f24SBrian Somers #include "mbuf.h"
134ef16f24SBrian Somers #include "log.h"
144ef16f24SBrian Somers #include "loadalias.h"
154ef16f24SBrian Somers #include "vars.h"
164ef16f24SBrian Somers #include "server.h"
174ef16f24SBrian Somers 
184ef16f24SBrian Somers int server = UNKNOWN_SERVER;
194ef16f24SBrian Somers static struct sockaddr_un ifsun;
204ef16f24SBrian Somers static char *rm;
214ef16f24SBrian Somers 
224ef16f24SBrian Somers int
234ef16f24SBrian Somers ServerLocalOpen(const char *name)
244ef16f24SBrian Somers {
254ef16f24SBrian Somers     int s;
264ef16f24SBrian Somers 
274ef16f24SBrian Somers     ifsun.sun_len = strlen(name);
284ef16f24SBrian Somers     if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
294ef16f24SBrian Somers       LogPrintf(LogERROR, "Local: %s: Path too long\n", name);
304ef16f24SBrian Somers       return 1;
314ef16f24SBrian Somers     }
324ef16f24SBrian Somers     ifsun.sun_family = AF_LOCAL;
334ef16f24SBrian Somers     strcpy(ifsun.sun_path, name);
344ef16f24SBrian Somers 
354ef16f24SBrian Somers     s = socket(PF_LOCAL, SOCK_STREAM, 0);
364ef16f24SBrian Somers     if (s < 0) {
374ef16f24SBrian Somers       LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno));
384ef16f24SBrian Somers       return 2;
394ef16f24SBrian Somers     }
404ef16f24SBrian Somers 
414ef16f24SBrian Somers     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
424ef16f24SBrian Somers     if (bind(s, (struct sockaddr *) &ifsun, sizeof(ifsun)) < 0) {
434ef16f24SBrian Somers       LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno));
444ef16f24SBrian Somers       if (errno == EADDRINUSE && VarTerm)
454ef16f24SBrian Somers         fprintf(VarTerm, "Wait for a while, then try again.\n");
464ef16f24SBrian Somers       close(s);
474ef16f24SBrian Somers       unlink(name);
484ef16f24SBrian Somers       return 3;
494ef16f24SBrian Somers     }
504ef16f24SBrian Somers     if (listen(s, 5) != 0) {
514ef16f24SBrian Somers       LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n");
524ef16f24SBrian Somers       close(s);
534ef16f24SBrian Somers       unlink(name);
544ef16f24SBrian Somers       return 4;
554ef16f24SBrian Somers     }
564ef16f24SBrian Somers     ServerClose();
574ef16f24SBrian Somers     server = s;
584ef16f24SBrian Somers     rm = ifsun.sun_path;
594ef16f24SBrian Somers     LogPrintf(LogPHASE, "Listening at local socket %s.\n", name);
604ef16f24SBrian Somers     return 0;
614ef16f24SBrian Somers }
624ef16f24SBrian Somers 
634ef16f24SBrian Somers int
644ef16f24SBrian Somers ServerTcpOpen(int port)
654ef16f24SBrian Somers {
664ef16f24SBrian Somers     struct sockaddr_in ifsin;
674ef16f24SBrian Somers     int s;
684ef16f24SBrian Somers 
694ef16f24SBrian Somers     s = socket(PF_INET, SOCK_STREAM, 0);
704ef16f24SBrian Somers     if (s < 0) {
714ef16f24SBrian Somers       LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno));
724ef16f24SBrian Somers       return 5;
734ef16f24SBrian Somers     }
744ef16f24SBrian Somers     ifsin.sin_family = AF_INET;
754ef16f24SBrian Somers     ifsin.sin_addr.s_addr = INADDR_ANY;
764ef16f24SBrian Somers     ifsin.sin_port = htons(port);
774ef16f24SBrian Somers     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
784ef16f24SBrian Somers     if (bind(s, (struct sockaddr *) &ifsin, sizeof(ifsin)) < 0) {
794ef16f24SBrian Somers       LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno));
804ef16f24SBrian Somers       if (errno == EADDRINUSE && VarTerm)
814ef16f24SBrian Somers         fprintf(VarTerm, "Wait for a while, then try again.\n");
824ef16f24SBrian Somers       close(s);
834ef16f24SBrian Somers       return 6;
844ef16f24SBrian Somers     }
854ef16f24SBrian Somers     if (listen(s, 5) != 0) {
864ef16f24SBrian Somers       LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n");
874ef16f24SBrian Somers       close(s);
884ef16f24SBrian Somers       return 7;
894ef16f24SBrian Somers     }
904ef16f24SBrian Somers     ServerClose();
914ef16f24SBrian Somers     server = s;
924ef16f24SBrian Somers     LogPrintf(LogPHASE, "Listening at port %d.\n", port);
934ef16f24SBrian Somers     return 0;
944ef16f24SBrian Somers }
954ef16f24SBrian Somers 
964ef16f24SBrian Somers void
974ef16f24SBrian Somers ServerClose()
984ef16f24SBrian Somers {
994ef16f24SBrian Somers   if (server >= 0) {
1004ef16f24SBrian Somers     close(server);
1014ef16f24SBrian Somers     if (rm) {
1024ef16f24SBrian Somers       unlink(rm);
1034ef16f24SBrian Somers       rm = 0;
1044ef16f24SBrian Somers     }
1054ef16f24SBrian Somers   }
1064ef16f24SBrian Somers   server = -1;
1074ef16f24SBrian Somers }
1084ef16f24SBrian Somers 
1094ef16f24SBrian Somers int
1104ef16f24SBrian Somers ServerType()
1114ef16f24SBrian Somers {
1124ef16f24SBrian Somers   if (server == UNKNOWN_SERVER)
1134ef16f24SBrian Somers     return UNKNOWN_SERVER;
1144ef16f24SBrian Somers   else if (server == NO_SERVER)
1154ef16f24SBrian Somers     return NO_SERVER;
1164ef16f24SBrian Somers   else if (rm)
1174ef16f24SBrian Somers     return LOCAL_SERVER;
1184ef16f24SBrian Somers   else
1194ef16f24SBrian Somers     return INET_SERVER;
1204ef16f24SBrian Somers }
121