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