defs.c revision 134789
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 * 2650479Speter * $FreeBSD: head/usr.sbin/ppp/defs.c 134789 2004-09-05 01:46:52Z brian $ 2730715Sbrian */ 2830715Sbrian 2931196Sbrian 3093418Sbrian#include <sys/param.h> 3144279Sbrian#include <netdb.h> 3244279Sbrian#include <netinet/in.h> 3344279Sbrian#include <arpa/inet.h> 3444279Sbrian#include <sys/socket.h> 3544279Sbrian 3644279Sbrian#include <ctype.h> 3746085Sbrian#include <errno.h> 3893418Sbrian#include <stdarg.h> 3958034Sbrian#include <stdio.h> 4030715Sbrian#include <stdlib.h> 4131121Sbrian#include <string.h> 4293418Sbrian#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 4393418Sbrian#include <sys/module.h> 4493418Sbrian#endif 4546686Sbrian#include <termios.h> 4637192Sbrian#if !defined(__FreeBSD__) || __FreeBSD__ < 3 4734539Sbrian#include <time.h> 4837192Sbrian#endif 4931196Sbrian#include <unistd.h> 5030715Sbrian 5193418Sbrian#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 5293418Sbrian#include "id.h" 5393418Sbrian#include "log.h" 5493418Sbrian#endif 5530715Sbrian#include "defs.h" 5630715Sbrian 5746686Sbrian#define issep(c) ((c) == '\t' || (c) == ' ') 5846686Sbrian 5965269Sbrian#if defined(__NetBSD__) || __FreeBSD__ < 3 6030715Sbrianvoid 6130715Sbrianrandinit() 6230715Sbrian{ 6365269Sbrian#if defined(__FreeBSD__) 6437010Sbrian static int initdone; /* srandomdev() call is only required once */ 6530715Sbrian 6630715Sbrian if (!initdone) { 6730715Sbrian initdone = 1; 6830715Sbrian srandomdev(); 6930715Sbrian } 7031343Sbrian#else 7136285Sbrian srandom((time(NULL)^getpid())+random()); 7231343Sbrian#endif 7330715Sbrian} 7465269Sbrian#endif 7531196Sbrian 7636285Sbrianssize_t 7736285Sbrianfullread(int fd, void *v, size_t n) 7836285Sbrian{ 7936285Sbrian size_t got, total; 8031196Sbrian 8136285Sbrian for (total = 0; total < n; total += got) 8236285Sbrian switch ((got = read(fd, (char *)v + total, n - total))) { 8336285Sbrian case 0: 8436285Sbrian return total; 8536285Sbrian case -1: 8636285Sbrian if (errno == EINTR) 8736285Sbrian got = 0; 8836285Sbrian else 8936285Sbrian return -1; 9036285Sbrian } 9136285Sbrian return total; 9236285Sbrian} 9336285Sbrian 9436285Sbrianstatic struct { 9536285Sbrian int mode; 9636285Sbrian const char *name; 9736285Sbrian} modes[] = { 9836465Sbrian { PHYS_INTERACTIVE, "interactive" }, 9936465Sbrian { PHYS_AUTO, "auto" }, 10036285Sbrian { PHYS_DIRECT, "direct" }, 10136285Sbrian { PHYS_DEDICATED, "dedicated" }, 10236465Sbrian { PHYS_DDIAL, "ddial" }, 10336465Sbrian { PHYS_BACKGROUND, "background" }, 10453830Sbrian { PHYS_FOREGROUND, "foreground" }, 10536285Sbrian { PHYS_ALL, "*" }, 10636285Sbrian { 0, 0 } 10736285Sbrian}; 10836285Sbrian 10936285Sbrianconst char * 11036285Sbrianmode2Nam(int mode) 11131196Sbrian{ 11236285Sbrian int m; 11331196Sbrian 11436285Sbrian for (m = 0; modes[m].mode; m++) 11536285Sbrian if (modes[m].mode == mode) 11636285Sbrian return modes[m].name; 11731196Sbrian 11836285Sbrian return "unknown"; 11931196Sbrian} 12031203Sbrian 12136285Sbrianint 12236285SbrianNam2mode(const char *name) 12331203Sbrian{ 12436285Sbrian int m, got, len; 12531203Sbrian 12636285Sbrian len = strlen(name); 12736285Sbrian got = -1; 12836285Sbrian for (m = 0; modes[m].mode; m++) 12936285Sbrian if (!strncasecmp(name, modes[m].name, len)) { 13036285Sbrian if (modes[m].name[len] == '\0') 13136285Sbrian return modes[m].mode; 13236285Sbrian if (got != -1) 13336285Sbrian return 0; 13436285Sbrian got = m; 13536285Sbrian } 13636285Sbrian 13736285Sbrian return got == -1 ? 0 : modes[got].mode; 13831203Sbrian} 13944279Sbrian 14044279Sbrianstruct in_addr 14144279SbrianGetIpAddr(const char *cp) 14244279Sbrian{ 14344279Sbrian struct in_addr ipaddr; 14444279Sbrian 14544279Sbrian if (!strcasecmp(cp, "default")) 14644279Sbrian ipaddr.s_addr = INADDR_ANY; 14744279Sbrian else if (inet_aton(cp, &ipaddr) == 0) { 14844279Sbrian const char *ptr; 14944279Sbrian 15044279Sbrian /* Any illegal characters ? */ 15144279Sbrian for (ptr = cp; *ptr != '\0'; ptr++) 15244279Sbrian if (!isalnum(*ptr) && strchr("-.", *ptr) == NULL) 15344279Sbrian break; 15444279Sbrian 15544279Sbrian if (*ptr == '\0') { 15644279Sbrian struct hostent *hp; 15744279Sbrian 15844279Sbrian hp = gethostbyname(cp); 15944279Sbrian if (hp && hp->h_addrtype == AF_INET) 16044279Sbrian memcpy(&ipaddr, hp->h_addr, hp->h_length); 16144279Sbrian else 16244279Sbrian ipaddr.s_addr = INADDR_NONE; 16344279Sbrian } else 16444279Sbrian ipaddr.s_addr = INADDR_NONE; 16544279Sbrian } 16644279Sbrian 16744279Sbrian return ipaddr; 16844279Sbrian} 16946686Sbrian 17046686Sbrianstatic const struct speeds { 171134789Sbrian unsigned nspeed; 17246686Sbrian speed_t speed; 17346686Sbrian} speeds[] = { 17446686Sbrian#ifdef B50 17546686Sbrian { 50, B50, }, 17646686Sbrian#endif 17746686Sbrian#ifdef B75 17846686Sbrian { 75, B75, }, 17946686Sbrian#endif 18046686Sbrian#ifdef B110 18146686Sbrian { 110, B110, }, 18246686Sbrian#endif 18346686Sbrian#ifdef B134 18446686Sbrian { 134, B134, }, 18546686Sbrian#endif 18646686Sbrian#ifdef B150 18746686Sbrian { 150, B150, }, 18846686Sbrian#endif 18946686Sbrian#ifdef B200 19046686Sbrian { 200, B200, }, 19146686Sbrian#endif 19246686Sbrian#ifdef B300 19346686Sbrian { 300, B300, }, 19446686Sbrian#endif 19546686Sbrian#ifdef B600 19646686Sbrian { 600, B600, }, 19746686Sbrian#endif 19846686Sbrian#ifdef B1200 19946686Sbrian { 1200, B1200, }, 20046686Sbrian#endif 20146686Sbrian#ifdef B1800 20246686Sbrian { 1800, B1800, }, 20346686Sbrian#endif 20446686Sbrian#ifdef B2400 20546686Sbrian { 2400, B2400, }, 20646686Sbrian#endif 20746686Sbrian#ifdef B4800 20846686Sbrian { 4800, B4800, }, 20946686Sbrian#endif 21046686Sbrian#ifdef B9600 21146686Sbrian { 9600, B9600, }, 21246686Sbrian#endif 21346686Sbrian#ifdef B19200 21446686Sbrian { 19200, B19200, }, 21546686Sbrian#endif 21646686Sbrian#ifdef B38400 21746686Sbrian { 38400, B38400, }, 21846686Sbrian#endif 21946686Sbrian#ifndef _POSIX_SOURCE 22046686Sbrian#ifdef B7200 22146686Sbrian { 7200, B7200, }, 22246686Sbrian#endif 22346686Sbrian#ifdef B14400 22446686Sbrian { 14400, B14400, }, 22546686Sbrian#endif 22646686Sbrian#ifdef B28800 22746686Sbrian { 28800, B28800, }, 22846686Sbrian#endif 22946686Sbrian#ifdef B57600 23046686Sbrian { 57600, B57600, }, 23146686Sbrian#endif 23246686Sbrian#ifdef B76800 23346686Sbrian { 76800, B76800, }, 23446686Sbrian#endif 23546686Sbrian#ifdef B115200 23646686Sbrian { 115200, B115200, }, 23746686Sbrian#endif 23846686Sbrian#ifdef B230400 23946686Sbrian { 230400, B230400, }, 24046686Sbrian#endif 24192142Sbrian#ifdef B460800 24292142Sbrian { 460800, B460800, }, 24392142Sbrian#endif 24492142Sbrian#ifdef B921600 24592142Sbrian { 921600, B921600, }, 24692142Sbrian#endif 24746686Sbrian#ifdef EXTA 24846686Sbrian { 19200, EXTA, }, 24946686Sbrian#endif 25046686Sbrian#ifdef EXTB 25146686Sbrian { 38400, EXTB, }, 25246686Sbrian#endif 25346686Sbrian#endif /* _POSIX_SOURCE */ 25446686Sbrian { 0, 0 } 25546686Sbrian}; 25646686Sbrian 257134789Sbrianunsigned 258134789SbrianSpeedToUnsigned(speed_t speed) 25946686Sbrian{ 26046686Sbrian const struct speeds *sp; 26146686Sbrian 26246686Sbrian for (sp = speeds; sp->nspeed; sp++) { 26346686Sbrian if (sp->speed == speed) { 26446686Sbrian return sp->nspeed; 26546686Sbrian } 26646686Sbrian } 26746686Sbrian return 0; 26846686Sbrian} 26946686Sbrian 27046686Sbrianspeed_t 271134789SbrianUnsignedToSpeed(unsigned nspeed) 27246686Sbrian{ 27346686Sbrian const struct speeds *sp; 27446686Sbrian 27546686Sbrian for (sp = speeds; sp->nspeed; sp++) { 27646686Sbrian if (sp->nspeed == nspeed) { 27746686Sbrian return sp->speed; 27846686Sbrian } 27946686Sbrian } 28046686Sbrian return B0; 28146686Sbrian} 28246686Sbrian 28354915Sbrianchar * 28455145Sbrianfindblank(char *p, int flags) 28546686Sbrian{ 28655065Sbrian int instring; 28755065Sbrian 28855065Sbrian instring = 0; 28954915Sbrian while (*p) { 29054915Sbrian if (*p == '\\') { 29155145Sbrian if (flags & PARSE_REDUCE) { 29255013Sbrian memmove(p, p + 1, strlen(p)); 29355013Sbrian if (!*p) 29455013Sbrian break; 29555013Sbrian } else 29655013Sbrian p++; 29755065Sbrian } else if (*p == '"') { 29855065Sbrian memmove(p, p + 1, strlen(p)); 29955065Sbrian instring = !instring; 30055065Sbrian continue; 30155145Sbrian } else if (!instring && (issep(*p) || 30255145Sbrian (*p == '#' && !(flags & PARSE_NOHASH)))) 30354915Sbrian return p; 30454915Sbrian p++; 30546686Sbrian } 30646686Sbrian 30754915Sbrian return instring ? NULL : p; 30846686Sbrian} 30946686Sbrian 31046686Sbrianint 31155145SbrianMakeArgs(char *script, char **pvect, int maxargs, int flags) 31246686Sbrian{ 31355065Sbrian int nargs; 31446686Sbrian 31546686Sbrian nargs = 0; 31665264Sbrian while (*script) { 31755065Sbrian script += strspn(script, " \t"); 31867825Sbrian if (*script == '#' && !(flags & PARSE_NOHASH)) { 31965264Sbrian *script = '\0'; 32065264Sbrian break; 32165264Sbrian } 32246686Sbrian if (*script) { 32346686Sbrian if (nargs >= maxargs - 1) 32465264Sbrian break; 32546686Sbrian *pvect++ = script; 32646686Sbrian nargs++; 32755145Sbrian script = findblank(script, flags); 32854914Sbrian if (script == NULL) 32954914Sbrian return -1; 33078275Sbrian else if (!(flags & PARSE_NOHASH) && *script == '#') 33165264Sbrian *script = '\0'; 33278275Sbrian else if (*script) 33365264Sbrian *script++ = '\0'; 33446686Sbrian } 33546686Sbrian } 33646686Sbrian *pvect = NULL; 33746686Sbrian return nargs; 33846686Sbrian} 33958034Sbrian 34058034Sbrianconst char * 34158034SbrianNumStr(long val, char *buf, size_t sz) 34258034Sbrian{ 34358034Sbrian static char result[23]; /* handles 64 bit numbers */ 34458034Sbrian 34558034Sbrian if (buf == NULL || sz == 0) { 34658034Sbrian buf = result; 34758034Sbrian sz = sizeof result; 34858034Sbrian } 34958034Sbrian snprintf(buf, sz, "<%ld>", val); 35058034Sbrian return buf; 35158034Sbrian} 35258034Sbrian 35358034Sbrianconst char * 35458034SbrianHexStr(long val, char *buf, size_t sz) 35558034Sbrian{ 35658034Sbrian static char result[21]; /* handles 64 bit numbers */ 35758034Sbrian 35858034Sbrian if (buf == NULL || sz == 0) { 35958034Sbrian buf = result; 36058034Sbrian sz = sizeof result; 36158034Sbrian } 36258034Sbrian snprintf(buf, sz, "<0x%lx>", val); 36358034Sbrian return buf; 36458034Sbrian} 36559084Sbrian 36659084Sbrianconst char * 36759084Sbrianex_desc(int ex) 36859084Sbrian{ 36959084Sbrian static char num[12]; /* Used immediately if returned */ 37059084Sbrian static const char * const desc[] = { 37159084Sbrian "normal", "start", "sock", "modem", "dial", "dead", "done", 37259084Sbrian "reboot", "errdead", "hangup", "term", "nodial", "nologin", 37359084Sbrian "redial", "reconnect" 37459084Sbrian }; 37559084Sbrian 376134789Sbrian if (ex >= 0 && ex < (int)(sizeof desc / sizeof *desc)) 37759084Sbrian return desc[ex]; 37859084Sbrian snprintf(num, sizeof num, "%d", ex); 37959084Sbrian return num; 38059084Sbrian} 38164698Sbrian 38264698Sbrianvoid 38364698SbrianSetTitle(const char *title) 38464698Sbrian{ 38564698Sbrian if (title == NULL) 38664698Sbrian setproctitle(NULL); 38764698Sbrian else if (title[0] == '-' && title[1] != '\0') 38864698Sbrian setproctitle("-%s", title + 1); 38964698Sbrian else 39064698Sbrian setproctitle("%s", title); 39164698Sbrian} 39266898Sbrian 39366898Sbrianfd_set * 39466898Sbrianmkfdset() 39566898Sbrian{ 39666898Sbrian return (fd_set *)malloc(howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask)); 39766898Sbrian} 39866898Sbrian 39966898Sbrianvoid 40066898Sbrianzerofdset(fd_set *s) 40166898Sbrian{ 40266898Sbrian memset(s, '\0', howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask)); 40366898Sbrian} 40485991Sbrian 40585991Sbrianvoid 40685991SbrianConcatinate(char *buf, size_t sz, int argc, const char *const *argv) 40785991Sbrian{ 408134789Sbrian int i, n; 409134789Sbrian unsigned pos; 41085991Sbrian 41185991Sbrian *buf = '\0'; 41285991Sbrian for (pos = i = 0; i < argc; i++) { 41385991Sbrian n = snprintf(buf + pos, sz - pos, "%s%s", i ? " " : "", argv[i]); 41485991Sbrian if (n < 0) { 41585991Sbrian buf[pos] = '\0'; 41685991Sbrian break; 41785991Sbrian } 41885991Sbrian if ((pos += n) >= sz) 41985991Sbrian break; 42085991Sbrian } 42185991Sbrian} 42293418Sbrian 423134789Sbrian#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 42494698Sbrianint 42593418Sbrianloadmodules(int how, const char *module, ...) 42693418Sbrian{ 42794698Sbrian int loaded = 0; 42893418Sbrian va_list ap; 42993418Sbrian 43093418Sbrian va_start(ap, module); 43193418Sbrian while (module != NULL) { 43294698Sbrian if (modfind(module) == -1) { 43394698Sbrian if (ID0kldload(module) == -1) { 43494698Sbrian if (how == LOAD_VERBOSLY) 43594698Sbrian log_Printf(LogWARN, "%s: Cannot load module\n", module); 43694698Sbrian } else 43794698Sbrian loaded++; 43894698Sbrian } 43993418Sbrian module = va_arg(ap, const char *); 44093418Sbrian } 44193418Sbrian va_end(ap); 44294698Sbrian return loaded; 44393418Sbrian} 444134789Sbrian#else 445134789Sbrianint 446134789Sbrianloadmodules(int how __unused, const char *module __unused, ...) 447134789Sbrian{ 448134789Sbrian return 0; 449134789Sbrian} 450134789Sbrian#endif 451