server.c revision 31921
131921Sbrian/*- 231921Sbrian * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org> 331921Sbrian * All rights reserved. 431921Sbrian * 531921Sbrian * Redistribution and use in source and binary forms, with or without 631921Sbrian * modification, are permitted provided that the following conditions 731921Sbrian * are met: 831921Sbrian * 1. Redistributions of source code must retain the above copyright 931921Sbrian * notice, this list of conditions and the following disclaimer. 1031921Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1131921Sbrian * notice, this list of conditions and the following disclaimer in the 1231921Sbrian * documentation and/or other materials provided with the distribution. 1331921Sbrian * 1431921Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1531921Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1631921Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1731921Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1831921Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1931921Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2031921Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2131921Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2231921Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2331921Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2431921Sbrian * SUCH DAMAGE. 2531921Sbrian * 2631921Sbrian * $Id$ 2730715Sbrian */ 2830715Sbrian 2930715Sbrian#include <sys/param.h> 3026940Sbrian#include <sys/socket.h> 3126940Sbrian#include <netinet/in.h> 3226940Sbrian#include <arpa/inet.h> 3326940Sbrian#include <netinet/in_systm.h> 3426940Sbrian#include <netinet/ip.h> 3530715Sbrian 3630715Sbrian#include <errno.h> 3730715Sbrian#include <stdio.h> 3826940Sbrian#include <string.h> 3930715Sbrian#include <sys/stat.h> 4030715Sbrian#include <sys/un.h> 4126940Sbrian#include <unistd.h> 4230715Sbrian 4331343Sbrian#include "command.h" 4426940Sbrian#include "mbuf.h" 4526940Sbrian#include "log.h" 4626940Sbrian#include "loadalias.h" 4731070Sbrian#include "defs.h" 4826940Sbrian#include "vars.h" 4926940Sbrian#include "server.h" 5031061Sbrian#include "id.h" 5126940Sbrian 5231081Sbrianint server = -1; 5330715Sbrian 5426940Sbrianstatic struct sockaddr_un ifsun; 5526940Sbrianstatic char *rm; 5626940Sbrian 5726940Sbrianint 5827089SbrianServerLocalOpen(const char *name, mode_t mask) 5926940Sbrian{ 6028679Sbrian int s; 6126940Sbrian 6229083Sbrian if (VarLocalAuth == LOCAL_DENY) { 6329083Sbrian LogPrintf(LogERROR, "Local: Can't open socket %s: No password " 6429083Sbrian "in ppp.secret\n", name); 6529083Sbrian return 1; 6629083Sbrian } 6729083Sbrian 6831121Sbrian if (mode & MODE_INTER) { 6929252Sbrian LogPrintf(LogERROR, "Local: Can't open socket in interactive mode\n"); 7029252Sbrian return 1; 7129252Sbrian } 7229252Sbrian 7331914Sbrian memset(&ifsun, '\0', sizeof ifsun); 7428679Sbrian ifsun.sun_len = strlen(name); 7528679Sbrian if (ifsun.sun_len > sizeof ifsun.sun_path - 1) { 7628679Sbrian LogPrintf(LogERROR, "Local: %s: Path too long\n", name); 7729083Sbrian return 2; 7828679Sbrian } 7928679Sbrian ifsun.sun_family = AF_LOCAL; 8028679Sbrian strcpy(ifsun.sun_path, name); 8126940Sbrian 8231061Sbrian s = ID0socket(PF_LOCAL, SOCK_STREAM, 0); 8328679Sbrian if (s < 0) { 8428679Sbrian LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno)); 8529083Sbrian return 3; 8628679Sbrian } 8728679Sbrian setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s); 8831081Sbrian if (mask != (mode_t)-1) 8931081Sbrian mask = umask(mask); 9028679Sbrian if (bind(s, (struct sockaddr *) & ifsun, sizeof(ifsun)) < 0) { 9131081Sbrian if (mask != (mode_t)-1) 9231081Sbrian umask(mask); 9328679Sbrian LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno)); 9428679Sbrian if (errno == EADDRINUSE && VarTerm) 9528679Sbrian fprintf(VarTerm, "Wait for a while, then try again.\n"); 9628679Sbrian close(s); 9729083Sbrian return 4; 9828679Sbrian } 9931081Sbrian if (mask != (mode_t)-1) 10031081Sbrian umask(mask); 10128679Sbrian if (listen(s, 5) != 0) { 10228679Sbrian LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n"); 10328679Sbrian close(s); 10431061Sbrian ID0unlink(name); 10529083Sbrian return 5; 10628679Sbrian } 10728679Sbrian ServerClose(); 10828679Sbrian server = s; 10928679Sbrian rm = ifsun.sun_path; 11028679Sbrian LogPrintf(LogPHASE, "Listening at local socket %s.\n", name); 11128679Sbrian return 0; 11226940Sbrian} 11326940Sbrian 11426940Sbrianint 11526940SbrianServerTcpOpen(int port) 11626940Sbrian{ 11728679Sbrian struct sockaddr_in ifsin; 11828679Sbrian int s; 11926940Sbrian 12029083Sbrian if (VarLocalAuth == LOCAL_DENY) { 12129083Sbrian LogPrintf(LogERROR, "Tcp: Can't open socket %d: No password " 12229083Sbrian "in ppp.secret\n", port); 12329083Sbrian return 6; 12429083Sbrian } 12529252Sbrian 12631121Sbrian if (mode & MODE_INTER) { 12729252Sbrian LogPrintf(LogERROR, "Tcp: Can't open socket in interactive mode\n"); 12829252Sbrian return 6; 12929252Sbrian } 13029252Sbrian 13131061Sbrian s = ID0socket(PF_INET, SOCK_STREAM, 0); 13228679Sbrian if (s < 0) { 13328679Sbrian LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno)); 13429083Sbrian return 7; 13528679Sbrian } 13631914Sbrian memset(&ifsin, '\0', sizeof ifsin); 13728679Sbrian ifsin.sin_family = AF_INET; 13828679Sbrian ifsin.sin_addr.s_addr = INADDR_ANY; 13928679Sbrian ifsin.sin_port = htons(port); 14028679Sbrian setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s); 14128679Sbrian if (bind(s, (struct sockaddr *) & ifsin, sizeof(ifsin)) < 0) { 14228679Sbrian LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno)); 14328679Sbrian if (errno == EADDRINUSE && VarTerm) 14428679Sbrian fprintf(VarTerm, "Wait for a while, then try again.\n"); 14528679Sbrian close(s); 14629083Sbrian return 8; 14728679Sbrian } 14828679Sbrian if (listen(s, 5) != 0) { 14928679Sbrian LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n"); 15028679Sbrian close(s); 15129083Sbrian return 9; 15228679Sbrian } 15328679Sbrian ServerClose(); 15428679Sbrian server = s; 15528679Sbrian LogPrintf(LogPHASE, "Listening at port %d.\n", port); 15628679Sbrian return 0; 15726940Sbrian} 15826940Sbrian 15926940Sbrianvoid 16026940SbrianServerClose() 16126940Sbrian{ 16226940Sbrian if (server >= 0) { 16326940Sbrian close(server); 16426940Sbrian if (rm) { 16531061Sbrian ID0unlink(rm); 16626940Sbrian rm = 0; 16726940Sbrian } 16826940Sbrian } 16926940Sbrian server = -1; 17026940Sbrian} 171