spppcontrol.c revision 30302
133965Sjdp/* 2218822Sdim * Copyright (c) 1997 Joerg Wunsch 3218822Sdim * 477298Sobrien * All rights reserved. 533965Sjdp * 633965Sjdp * Redistribution and use in source and binary forms, with or without 733965Sjdp * modification, are permitted provided that the following conditions 833965Sjdp * are met: 933965Sjdp * 1. Redistributions of source code must retain the above copyright 1033965Sjdp * notice, this list of conditions and the following disclaimer. 1133965Sjdp * 2. Redistributions in binary form must reproduce the above copyright 1233965Sjdp * notice, this list of conditions and the following disclaimer in the 1333965Sjdp * documentation and/or other materials provided with the distribution. 1433965Sjdp * 1533965Sjdp * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 1633965Sjdp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1733965Sjdp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1833965Sjdp * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 1933965Sjdp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2033965Sjdp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21217394Skib * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22217394Skib * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23217394Skib * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24130561Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25130561Sobrien * 26130561Sobrien * $Id$ 27130561Sobrien */ 28130561Sobrien 29130561Sobrien#include <sys/param.h> 30130561Sobrien#include <sys/callout.h> 31130561Sobrien#include <sys/ioctl.h> 32130561Sobrien#include <sys/socket.h> 33130561Sobrien#include <sys/time.h> 34130561Sobrien 35130561Sobrien#include <net/if.h> 36130561Sobrien#include <net/if_var.h> 37130561Sobrien#include <net/if_sppp.h> 38130561Sobrien 39130561Sobrien#include <err.h> 40130561Sobrien#include <errno.h> 41130561Sobrien#include <fcntl.h> 42130561Sobrien#include <stdio.h> 43130561Sobrien#include <stdlib.h> 44130561Sobrien#include <string.h> 45130561Sobrien#include <sysexits.h> 46130561Sobrien#include <unistd.h> 47130561Sobrien 48130561Sobrienvoid usage(void); 49130561Sobrienvoid print_vals(const char *ifname, struct spppreq *sp); 50130561Sobrienconst char *phase_name(enum ppp_phase phase); 51130561Sobrienconst char *proto_name(u_short proto); 52130561Sobrienconst char *authflags(u_short flags); 53130561Sobrien 54130561Sobrien#define PPP_PAP 0xc023 55130561Sobrien#define PPP_CHAP 0xc223 56130561Sobrien 57218822Sdimint 58130561Sobrienmain(int argc, char **argv) 59130561Sobrien{ 60130561Sobrien int s, c; 61130561Sobrien int errs = 0, verbose = 0; 62130561Sobrien size_t off; 63130561Sobrien const char *ifname, *cp; 64130561Sobrien struct ifreq ifr; 65130561Sobrien struct spppreq spr; 66130561Sobrien 67130561Sobrien while ((c = getopt(argc, argv, "v")) != -1) 68130561Sobrien switch (c) { 69130561Sobrien case 'v': 70130561Sobrien verbose++; 71130561Sobrien break; 72130561Sobrien 73130561Sobrien default: 74130561Sobrien errs++; 75130561Sobrien break; 76130561Sobrien } 77130561Sobrien argv += optind; 78130561Sobrien argc -= optind; 79130561Sobrien 80218822Sdim if (errs || argc < 1) 81218822Sdim usage(); 82218822Sdim 83218822Sdim ifname = argv[0]; 84130561Sobrien strncpy(ifr.ifr_name, ifname, sizeof ifr.ifr_name); 85130561Sobrien 86130561Sobrien /* use a random AF to create the socket */ 87130561Sobrien if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 88130561Sobrien err(EX_UNAVAILABLE, "ifconfig: socket"); 89130561Sobrien 9060484Sobrien argc--; 91130561Sobrien argv++; 92104834Sobrien 93130561Sobrien spr.cmd = (int)SPPPIOGDEFS; 9433965Sjdp ifr.ifr_data = (caddr_t)&spr; 9577298Sobrien 9633965Sjdp if (ioctl(s, SIOCGIFGENERIC, &ifr) == -1) 9733965Sjdp err(EX_OSERR, "SIOCGIFGENERIC(SPPPIOGDEFS)"); 98130561Sobrien 9933965Sjdp if (argc == 0) { 10033965Sjdp /* list only mode */ 101130561Sobrien print_vals(ifname, &spr); 10233965Sjdp return 0; 10333965Sjdp } 104130561Sobrien 10533965Sjdp#define startswith(s) strncmp(argv[0], s, (off = strlen(s))) == 0 10633965Sjdp 107130561Sobrien while (argc > 0) { 10833965Sjdp if (startswith("authproto=")) { 10933965Sjdp cp = argv[0] + off; 110130561Sobrien if (strcmp(cp, "pap") == 0) 11133965Sjdp spr.defs.myauth.proto = 11233965Sjdp spr.defs.hisauth.proto = PPP_PAP; 113130561Sobrien else if (strcmp(cp, "chap") == 0) 11433965Sjdp spr.defs.myauth.proto = 11533965Sjdp spr.defs.hisauth.proto = PPP_CHAP; 116130561Sobrien else if (strcmp(cp, "none") == 0) 11733965Sjdp spr.defs.myauth.proto = 11833965Sjdp spr.defs.hisauth.proto = 0; 119130561Sobrien else 12033965Sjdp errx(EX_DATAERR, "bad auth proto: %s", cp); 12133965Sjdp } else if (startswith("myauthproto=")) { 122130561Sobrien cp = argv[0] + off; 12333965Sjdp if (strcmp(cp, "pap") == 0) 12433965Sjdp spr.defs.myauth.proto = PPP_PAP; 125130561Sobrien else if (strcmp(cp, "chap") == 0) 12633965Sjdp spr.defs.myauth.proto = PPP_CHAP; 12733965Sjdp else if (strcmp(cp, "none") == 0) 12833965Sjdp spr.defs.myauth.proto = 0; 12933965Sjdp else 13033965Sjdp errx(EX_DATAERR, "bad auth proto: %s", cp); 13133965Sjdp } else if (startswith("myauthname=")) 13233965Sjdp strncpy(spr.defs.myauth.name, argv[0] + off, 13333965Sjdp AUTHNAMELEN); 134130561Sobrien else if (startswith("myauthsecret=") || 13533965Sjdp startswith("myauthkey=")) 13633965Sjdp strncpy(spr.defs.myauth.secret, argv[0] + off, 137130561Sobrien AUTHKEYLEN); 13833965Sjdp else if (startswith("hisauthproto=")) { 13933965Sjdp cp = argv[0] + off; 14033965Sjdp if (strcmp(cp, "pap") == 0) 14133965Sjdp spr.defs.hisauth.proto = PPP_PAP; 142130561Sobrien else if (strcmp(cp, "chap") == 0) 143130561Sobrien spr.defs.hisauth.proto = PPP_CHAP; 144130561Sobrien else if (strcmp(cp, "none") == 0) 14533965Sjdp spr.defs.hisauth.proto = 0; 146130561Sobrien else 14733965Sjdp errx(EX_DATAERR, "bad auth proto: %s", cp); 14833965Sjdp } else if (startswith("hisauthname=")) 149130561Sobrien strncpy(spr.defs.hisauth.name, argv[0] + off, 150218822Sdim AUTHNAMELEN); 15133965Sjdp else if (startswith("hisauthsecret=") || 15277298Sobrien startswith("hisauthkey=")) 15377298Sobrien strncpy(spr.defs.hisauth.secret, argv[0] + off, 154130561Sobrien AUTHKEYLEN); 15533965Sjdp else if (strcmp(argv[0], "callin") == 0) 156130561Sobrien spr.defs.hisauth.flags |= AUTHFLAG_NOCALLOUT; 157130561Sobrien else if (strcmp(argv[0], "always") == 0) 158130561Sobrien spr.defs.hisauth.flags &= ~AUTHFLAG_NOCALLOUT; 15933965Sjdp else if (strcmp(argv[0], "norechallenge") == 0) 160130561Sobrien spr.defs.hisauth.flags |= AUTHFLAG_NORECHALLENGE; 161130561Sobrien else if (strcmp(argv[0], "rechallenge") == 0) 162130561Sobrien spr.defs.hisauth.flags &= ~AUTHFLAG_NORECHALLENGE; 163130561Sobrien else 164130561Sobrien errx(EX_DATAERR, "bad parameter: \"%s\"", argv[0]); 165130561Sobrien 166130561Sobrien argv++; 167130561Sobrien argc--; 168130561Sobrien } 16933965Sjdp 170130561Sobrien spr.cmd = (int)SPPPIOSDEFS; 171130561Sobrien 172130561Sobrien if (ioctl(s, SIOCSIFGENERIC, &ifr) == -1) 17333965Sjdp err(EX_OSERR, "SIOCSIFGENERIC(SPPPIOSDEFS)"); 17460484Sobrien 175130561Sobrien if (verbose) 17660484Sobrien print_vals(ifname, &spr); 17760484Sobrien 178130561Sobrien return 0; 179130561Sobrien} 180130561Sobrien 18160484Sobrienvoid 18260484Sobrienusage(void) 18360484Sobrien{ 18460484Sobrien errx(EX_USAGE, 18560484Sobrien "usage: [-v] ifname [{my|his}auth{proto|name|secret}=..." 18660484Sobrien "|callin|always]"); 187130561Sobrien} 18877298Sobrien 189104834Sobrienvoid 190104834Sobrienprint_vals(const char *ifname, struct spppreq *sp) 191104834Sobrien{ 192130561Sobrien printf("%s:\tphase=%s\n", ifname, phase_name(sp->defs.pp_phase)); 193104834Sobrien if (sp->defs.myauth.proto) { 19433965Sjdp printf("\tmyauthproto=%s myauthname=\"%.*s\"\n", 19533965Sjdp proto_name(sp->defs.myauth.proto), 19677298Sobrien AUTHNAMELEN, sp->defs.myauth.name); 19733965Sjdp } 19877298Sobrien if (sp->defs.hisauth.proto) { 19933965Sjdp printf("\thisauthproto=%s hisauthname=\"%.*s\"%s\n", 20033965Sjdp proto_name(sp->defs.hisauth.proto), 20133965Sjdp AUTHNAMELEN, sp->defs.hisauth.name, 20233965Sjdp authflags(sp->defs.hisauth.flags)); 20333965Sjdp } 20433965Sjdp} 205 206const char * 207phase_name(enum ppp_phase phase) 208{ 209 switch (phase) { 210 case PHASE_DEAD: return "dead"; 211 case PHASE_ESTABLISH: return "establish"; 212 case PHASE_TERMINATE: return "terminate"; 213 case PHASE_AUTHENTICATE: return "authenticate"; 214 case PHASE_NETWORK: return "network"; 215 } 216 return "illegal"; 217} 218 219const char * 220proto_name(u_short proto) 221{ 222 static char buf[12]; 223 switch (proto) { 224 case PPP_PAP: return "pap"; 225 case PPP_CHAP: return "chap"; 226 } 227 sprintf(buf, "0x%x", (unsigned)proto); 228 return buf; 229} 230 231const char * 232authflags(u_short flags) 233{ 234 static char buf[10]; 235 buf[0] = '\0'; 236 if (flags & AUTHFLAG_NOCALLOUT) 237 strcat(buf, " callin"); 238 if (flags & AUTHFLAG_NORECHALLENGE) 239 strcat(buf, " norechallenge"); 240 return buf; 241} 242