131921Sbrian/*- 2330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3330449Seadler * 431921Sbrian * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org> 531921Sbrian * All rights reserved. 631921Sbrian * 731921Sbrian * Redistribution and use in source and binary forms, with or without 831921Sbrian * modification, are permitted provided that the following conditions 931921Sbrian * are met: 1031921Sbrian * 1. Redistributions of source code must retain the above copyright 1131921Sbrian * notice, this list of conditions and the following disclaimer. 1231921Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1331921Sbrian * notice, this list of conditions and the following disclaimer in the 1431921Sbrian * documentation and/or other materials provided with the distribution. 1531921Sbrian * 1631921Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1731921Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1831921Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1931921Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2031921Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2131921Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2231921Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2331921Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2431921Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2531921Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2631921Sbrian * SUCH DAMAGE. 2731921Sbrian * 2850479Speter * $FreeBSD: stable/11/usr.sbin/ppp/defs.c 330449 2018-03-05 07:26:05Z eadler $ 2930715Sbrian */ 3030715Sbrian 3131196Sbrian 3293418Sbrian#include <sys/param.h> 3344279Sbrian#include <netdb.h> 3444279Sbrian#include <netinet/in.h> 3544279Sbrian#include <arpa/inet.h> 3644279Sbrian#include <sys/socket.h> 3744279Sbrian 3844279Sbrian#include <ctype.h> 3946085Sbrian#include <errno.h> 4093418Sbrian#include <stdarg.h> 4158034Sbrian#include <stdio.h> 4230715Sbrian#include <stdlib.h> 4331121Sbrian#include <string.h> 4493418Sbrian#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 4593418Sbrian#include <sys/module.h> 4693418Sbrian#endif 4746686Sbrian#include <termios.h> 48252826Srmh#ifndef __FreeBSD__ 4934539Sbrian#include <time.h> 5037192Sbrian#endif 5131196Sbrian#include <unistd.h> 5230715Sbrian 5393418Sbrian#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 5493418Sbrian#include "id.h" 5593418Sbrian#include "log.h" 5693418Sbrian#endif 5730715Sbrian#include "defs.h" 5830715Sbrian 5946686Sbrian#define issep(c) ((c) == '\t' || (c) == ' ') 6046686Sbrian 61252826Srmh#ifdef __NetBSD__ 6230715Sbrianvoid 6330715Sbrianrandinit() 6430715Sbrian{ 6536285Sbrian srandom((time(NULL)^getpid())+random()); 6630715Sbrian} 6765269Sbrian#endif 6831196Sbrian 6936285Sbrianssize_t 7036285Sbrianfullread(int fd, void *v, size_t n) 7136285Sbrian{ 7236285Sbrian size_t got, total; 7331196Sbrian 7436285Sbrian for (total = 0; total < n; total += got) 7536285Sbrian switch ((got = read(fd, (char *)v + total, n - total))) { 7636285Sbrian case 0: 7736285Sbrian return total; 7836285Sbrian case -1: 7936285Sbrian if (errno == EINTR) 8036285Sbrian got = 0; 8136285Sbrian else 8236285Sbrian return -1; 8336285Sbrian } 8436285Sbrian return total; 8536285Sbrian} 8636285Sbrian 8736285Sbrianstatic struct { 8836285Sbrian int mode; 8936285Sbrian const char *name; 9036285Sbrian} modes[] = { 9136465Sbrian { PHYS_INTERACTIVE, "interactive" }, 9236465Sbrian { PHYS_AUTO, "auto" }, 9336285Sbrian { PHYS_DIRECT, "direct" }, 9436285Sbrian { PHYS_DEDICATED, "dedicated" }, 9536465Sbrian { PHYS_DDIAL, "ddial" }, 9636465Sbrian { PHYS_BACKGROUND, "background" }, 9753830Sbrian { PHYS_FOREGROUND, "foreground" }, 9836285Sbrian { PHYS_ALL, "*" }, 9936285Sbrian { 0, 0 } 10036285Sbrian}; 10136285Sbrian 10236285Sbrianconst char * 10336285Sbrianmode2Nam(int mode) 10431196Sbrian{ 10536285Sbrian int m; 10631196Sbrian 10736285Sbrian for (m = 0; modes[m].mode; m++) 10836285Sbrian if (modes[m].mode == mode) 10936285Sbrian return modes[m].name; 11031196Sbrian 11136285Sbrian return "unknown"; 11231196Sbrian} 11331203Sbrian 11436285Sbrianint 11536285SbrianNam2mode(const char *name) 11631203Sbrian{ 11736285Sbrian int m, got, len; 11831203Sbrian 11936285Sbrian len = strlen(name); 12036285Sbrian got = -1; 12136285Sbrian for (m = 0; modes[m].mode; m++) 12236285Sbrian if (!strncasecmp(name, modes[m].name, len)) { 12336285Sbrian if (modes[m].name[len] == '\0') 12436285Sbrian return modes[m].mode; 12536285Sbrian if (got != -1) 12636285Sbrian return 0; 12736285Sbrian got = m; 12836285Sbrian } 12936285Sbrian 13036285Sbrian return got == -1 ? 0 : modes[got].mode; 13131203Sbrian} 13244279Sbrian 13344279Sbrianstruct in_addr 13444279SbrianGetIpAddr(const char *cp) 13544279Sbrian{ 13644279Sbrian struct in_addr ipaddr; 13744279Sbrian 13844279Sbrian if (!strcasecmp(cp, "default")) 13944279Sbrian ipaddr.s_addr = INADDR_ANY; 14044279Sbrian else if (inet_aton(cp, &ipaddr) == 0) { 14144279Sbrian const char *ptr; 14244279Sbrian 14344279Sbrian /* Any illegal characters ? */ 14444279Sbrian for (ptr = cp; *ptr != '\0'; ptr++) 14544279Sbrian if (!isalnum(*ptr) && strchr("-.", *ptr) == NULL) 14644279Sbrian break; 14744279Sbrian 14844279Sbrian if (*ptr == '\0') { 14944279Sbrian struct hostent *hp; 15044279Sbrian 15144279Sbrian hp = gethostbyname(cp); 15244279Sbrian if (hp && hp->h_addrtype == AF_INET) 15344279Sbrian memcpy(&ipaddr, hp->h_addr, hp->h_length); 15444279Sbrian else 15544279Sbrian ipaddr.s_addr = INADDR_NONE; 15644279Sbrian } else 15744279Sbrian ipaddr.s_addr = INADDR_NONE; 15844279Sbrian } 15944279Sbrian 16044279Sbrian return ipaddr; 16144279Sbrian} 16246686Sbrian 16346686Sbrianstatic const struct speeds { 164134789Sbrian unsigned nspeed; 16546686Sbrian speed_t speed; 16646686Sbrian} speeds[] = { 16746686Sbrian#ifdef B50 16846686Sbrian { 50, B50, }, 16946686Sbrian#endif 17046686Sbrian#ifdef B75 17146686Sbrian { 75, B75, }, 17246686Sbrian#endif 17346686Sbrian#ifdef B110 17446686Sbrian { 110, B110, }, 17546686Sbrian#endif 17646686Sbrian#ifdef B134 17746686Sbrian { 134, B134, }, 17846686Sbrian#endif 17946686Sbrian#ifdef B150 18046686Sbrian { 150, B150, }, 18146686Sbrian#endif 18246686Sbrian#ifdef B200 18346686Sbrian { 200, B200, }, 18446686Sbrian#endif 18546686Sbrian#ifdef B300 18646686Sbrian { 300, B300, }, 18746686Sbrian#endif 18846686Sbrian#ifdef B600 18946686Sbrian { 600, B600, }, 19046686Sbrian#endif 19146686Sbrian#ifdef B1200 19246686Sbrian { 1200, B1200, }, 19346686Sbrian#endif 19446686Sbrian#ifdef B1800 19546686Sbrian { 1800, B1800, }, 19646686Sbrian#endif 19746686Sbrian#ifdef B2400 19846686Sbrian { 2400, B2400, }, 19946686Sbrian#endif 20046686Sbrian#ifdef B4800 20146686Sbrian { 4800, B4800, }, 20246686Sbrian#endif 20346686Sbrian#ifdef B9600 20446686Sbrian { 9600, B9600, }, 20546686Sbrian#endif 20646686Sbrian#ifdef B19200 20746686Sbrian { 19200, B19200, }, 20846686Sbrian#endif 20946686Sbrian#ifdef B38400 21046686Sbrian { 38400, B38400, }, 21146686Sbrian#endif 21246686Sbrian#ifndef _POSIX_SOURCE 21346686Sbrian#ifdef B7200 21446686Sbrian { 7200, B7200, }, 21546686Sbrian#endif 21646686Sbrian#ifdef B14400 21746686Sbrian { 14400, B14400, }, 21846686Sbrian#endif 21946686Sbrian#ifdef B28800 22046686Sbrian { 28800, B28800, }, 22146686Sbrian#endif 22246686Sbrian#ifdef B57600 22346686Sbrian { 57600, B57600, }, 22446686Sbrian#endif 22546686Sbrian#ifdef B76800 22646686Sbrian { 76800, B76800, }, 22746686Sbrian#endif 22846686Sbrian#ifdef B115200 22946686Sbrian { 115200, B115200, }, 23046686Sbrian#endif 23146686Sbrian#ifdef B230400 23246686Sbrian { 230400, B230400, }, 23346686Sbrian#endif 23492142Sbrian#ifdef B460800 23592142Sbrian { 460800, B460800, }, 23692142Sbrian#endif 23792142Sbrian#ifdef B921600 23892142Sbrian { 921600, B921600, }, 23992142Sbrian#endif 24046686Sbrian#ifdef EXTA 24146686Sbrian { 19200, EXTA, }, 24246686Sbrian#endif 24346686Sbrian#ifdef EXTB 24446686Sbrian { 38400, EXTB, }, 24546686Sbrian#endif 24646686Sbrian#endif /* _POSIX_SOURCE */ 24746686Sbrian { 0, 0 } 24846686Sbrian}; 24946686Sbrian 250134789Sbrianunsigned 251134789SbrianSpeedToUnsigned(speed_t speed) 25246686Sbrian{ 25346686Sbrian const struct speeds *sp; 25446686Sbrian 25546686Sbrian for (sp = speeds; sp->nspeed; sp++) { 25646686Sbrian if (sp->speed == speed) { 25746686Sbrian return sp->nspeed; 25846686Sbrian } 25946686Sbrian } 26046686Sbrian return 0; 26146686Sbrian} 26246686Sbrian 26346686Sbrianspeed_t 264134789SbrianUnsignedToSpeed(unsigned nspeed) 26546686Sbrian{ 26646686Sbrian const struct speeds *sp; 26746686Sbrian 26846686Sbrian for (sp = speeds; sp->nspeed; sp++) { 26946686Sbrian if (sp->nspeed == nspeed) { 27046686Sbrian return sp->speed; 27146686Sbrian } 27246686Sbrian } 27346686Sbrian return B0; 27446686Sbrian} 27546686Sbrian 27654915Sbrianchar * 27755145Sbrianfindblank(char *p, int flags) 27846686Sbrian{ 27955065Sbrian int instring; 28055065Sbrian 28155065Sbrian instring = 0; 28254915Sbrian while (*p) { 28354915Sbrian if (*p == '\\') { 28455145Sbrian if (flags & PARSE_REDUCE) { 28555013Sbrian memmove(p, p + 1, strlen(p)); 28655013Sbrian if (!*p) 28755013Sbrian break; 28855013Sbrian } else 28955013Sbrian p++; 29055065Sbrian } else if (*p == '"') { 29155065Sbrian memmove(p, p + 1, strlen(p)); 29255065Sbrian instring = !instring; 29355065Sbrian continue; 29455145Sbrian } else if (!instring && (issep(*p) || 29555145Sbrian (*p == '#' && !(flags & PARSE_NOHASH)))) 29654915Sbrian return p; 29754915Sbrian p++; 29846686Sbrian } 29946686Sbrian 30054915Sbrian return instring ? NULL : p; 30146686Sbrian} 30246686Sbrian 30346686Sbrianint 30455145SbrianMakeArgs(char *script, char **pvect, int maxargs, int flags) 30546686Sbrian{ 30655065Sbrian int nargs; 30746686Sbrian 30846686Sbrian nargs = 0; 30965264Sbrian while (*script) { 31055065Sbrian script += strspn(script, " \t"); 31167825Sbrian if (*script == '#' && !(flags & PARSE_NOHASH)) { 31265264Sbrian *script = '\0'; 31365264Sbrian break; 31465264Sbrian } 31546686Sbrian if (*script) { 31646686Sbrian if (nargs >= maxargs - 1) 31765264Sbrian break; 31846686Sbrian *pvect++ = script; 31946686Sbrian nargs++; 32055145Sbrian script = findblank(script, flags); 32154914Sbrian if (script == NULL) 32254914Sbrian return -1; 32378275Sbrian else if (!(flags & PARSE_NOHASH) && *script == '#') 32465264Sbrian *script = '\0'; 32578275Sbrian else if (*script) 32665264Sbrian *script++ = '\0'; 32746686Sbrian } 32846686Sbrian } 32946686Sbrian *pvect = NULL; 33046686Sbrian return nargs; 33146686Sbrian} 33258034Sbrian 33358034Sbrianconst char * 33458034SbrianNumStr(long val, char *buf, size_t sz) 33558034Sbrian{ 33658034Sbrian static char result[23]; /* handles 64 bit numbers */ 33758034Sbrian 33858034Sbrian if (buf == NULL || sz == 0) { 33958034Sbrian buf = result; 34058034Sbrian sz = sizeof result; 34158034Sbrian } 34258034Sbrian snprintf(buf, sz, "<%ld>", val); 34358034Sbrian return buf; 34458034Sbrian} 34558034Sbrian 34658034Sbrianconst char * 34758034SbrianHexStr(long val, char *buf, size_t sz) 34858034Sbrian{ 34958034Sbrian static char result[21]; /* handles 64 bit numbers */ 35058034Sbrian 35158034Sbrian if (buf == NULL || sz == 0) { 35258034Sbrian buf = result; 35358034Sbrian sz = sizeof result; 35458034Sbrian } 35558034Sbrian snprintf(buf, sz, "<0x%lx>", val); 35658034Sbrian return buf; 35758034Sbrian} 35859084Sbrian 35959084Sbrianconst char * 36059084Sbrianex_desc(int ex) 36159084Sbrian{ 36259084Sbrian static char num[12]; /* Used immediately if returned */ 36359084Sbrian static const char * const desc[] = { 36459084Sbrian "normal", "start", "sock", "modem", "dial", "dead", "done", 36559084Sbrian "reboot", "errdead", "hangup", "term", "nodial", "nologin", 36659084Sbrian "redial", "reconnect" 36759084Sbrian }; 36859084Sbrian 369134789Sbrian if (ex >= 0 && ex < (int)(sizeof desc / sizeof *desc)) 37059084Sbrian return desc[ex]; 37159084Sbrian snprintf(num, sizeof num, "%d", ex); 37259084Sbrian return num; 37359084Sbrian} 37464698Sbrian 37564698Sbrianvoid 37664698SbrianSetTitle(const char *title) 37764698Sbrian{ 37864698Sbrian if (title == NULL) 37964698Sbrian setproctitle(NULL); 38064698Sbrian else if (title[0] == '-' && title[1] != '\0') 38164698Sbrian setproctitle("-%s", title + 1); 38264698Sbrian else 38364698Sbrian setproctitle("%s", title); 38464698Sbrian} 38566898Sbrian 38666898Sbrianfd_set * 38766898Sbrianmkfdset() 38866898Sbrian{ 38966898Sbrian return (fd_set *)malloc(howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask)); 39066898Sbrian} 39166898Sbrian 39266898Sbrianvoid 39366898Sbrianzerofdset(fd_set *s) 39466898Sbrian{ 39566898Sbrian memset(s, '\0', howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask)); 39666898Sbrian} 39785991Sbrian 39885991Sbrianvoid 39985991SbrianConcatinate(char *buf, size_t sz, int argc, const char *const *argv) 40085991Sbrian{ 401134789Sbrian int i, n; 402134789Sbrian unsigned pos; 40385991Sbrian 40485991Sbrian *buf = '\0'; 40585991Sbrian for (pos = i = 0; i < argc; i++) { 40685991Sbrian n = snprintf(buf + pos, sz - pos, "%s%s", i ? " " : "", argv[i]); 40785991Sbrian if (n < 0) { 40885991Sbrian buf[pos] = '\0'; 40985991Sbrian break; 41085991Sbrian } 41185991Sbrian if ((pos += n) >= sz) 41285991Sbrian break; 41385991Sbrian } 41485991Sbrian} 41593418Sbrian 416134789Sbrian#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 41794698Sbrianint 41893418Sbrianloadmodules(int how, const char *module, ...) 41993418Sbrian{ 42094698Sbrian int loaded = 0; 42193418Sbrian va_list ap; 42293418Sbrian 42393418Sbrian va_start(ap, module); 42493418Sbrian while (module != NULL) { 42594698Sbrian if (modfind(module) == -1) { 42694698Sbrian if (ID0kldload(module) == -1) { 42794698Sbrian if (how == LOAD_VERBOSLY) 42894698Sbrian log_Printf(LogWARN, "%s: Cannot load module\n", module); 42994698Sbrian } else 43094698Sbrian loaded++; 43194698Sbrian } 43293418Sbrian module = va_arg(ap, const char *); 43393418Sbrian } 43493418Sbrian va_end(ap); 43594698Sbrian return loaded; 43693418Sbrian} 437134789Sbrian#else 438134789Sbrianint 439134789Sbrianloadmodules(int how __unused, const char *module __unused, ...) 440134789Sbrian{ 441134789Sbrian return 0; 442134789Sbrian} 443134789Sbrian#endif 444