spppcontrol.c revision 88536
130302Sjoerg/* 230302Sjoerg * Copyright (c) 1997 Joerg Wunsch 330302Sjoerg * 430302Sjoerg * All rights reserved. 530302Sjoerg * 630302Sjoerg * Redistribution and use in source and binary forms, with or without 730302Sjoerg * modification, are permitted provided that the following conditions 830302Sjoerg * are met: 930302Sjoerg * 1. Redistributions of source code must retain the above copyright 1030302Sjoerg * notice, this list of conditions and the following disclaimer. 1130302Sjoerg * 2. Redistributions in binary form must reproduce the above copyright 1230302Sjoerg * notice, this list of conditions and the following disclaimer in the 1330302Sjoerg * documentation and/or other materials provided with the distribution. 1430302Sjoerg * 1530302Sjoerg * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 1630302Sjoerg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1730302Sjoerg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1830302Sjoerg * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 1930302Sjoerg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2030302Sjoerg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2130302Sjoerg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2230302Sjoerg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2330302Sjoerg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2430302Sjoerg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2530302Sjoerg */ 2630302Sjoerg 2732274Scharnier#ifndef lint 2832274Scharnierstatic const char rcsid[] = 2950476Speter "$FreeBSD: head/sbin/spppcontrol/spppcontrol.c 88536 2001-12-27 16:52:23Z joerg $"; 3032274Scharnier#endif /* not lint */ 3132274Scharnier 3230302Sjoerg#include <sys/param.h> 3330302Sjoerg#include <sys/callout.h> 3430302Sjoerg#include <sys/ioctl.h> 3588536Sjoerg#include <sys/mbuf.h> 3630302Sjoerg#include <sys/socket.h> 3730302Sjoerg 3830302Sjoerg#include <net/if.h> 3930302Sjoerg#include <net/if_var.h> 4088536Sjoerg#include <netinet/in.h> 4188536Sjoerg#include <netinet/in_systm.h> 4288536Sjoerg#include <netinet/ip.h> 4388536Sjoerg#include <net/slcompress.h> 4430302Sjoerg#include <net/if_sppp.h> 4530302Sjoerg 4630302Sjoerg#include <err.h> 4730302Sjoerg#include <stdio.h> 4878732Sdd#include <stdlib.h> 4930302Sjoerg#include <string.h> 5030302Sjoerg#include <sysexits.h> 5130302Sjoerg#include <unistd.h> 5230302Sjoerg 5332274Scharnierstatic void usage(void); 5430302Sjoergvoid print_vals(const char *ifname, struct spppreq *sp); 5530302Sjoergconst char *phase_name(enum ppp_phase phase); 5630302Sjoergconst char *proto_name(u_short proto); 5730302Sjoergconst char *authflags(u_short flags); 5830302Sjoerg 5930302Sjoerg#define PPP_PAP 0xc023 6030302Sjoerg#define PPP_CHAP 0xc223 6130302Sjoerg 6230302Sjoergint 6330302Sjoergmain(int argc, char **argv) 6430302Sjoerg{ 6530302Sjoerg int s, c; 6630302Sjoerg int errs = 0, verbose = 0; 6730302Sjoerg size_t off; 6830302Sjoerg const char *ifname, *cp; 6930302Sjoerg struct ifreq ifr; 7030302Sjoerg struct spppreq spr; 7130302Sjoerg 7230302Sjoerg while ((c = getopt(argc, argv, "v")) != -1) 7330302Sjoerg switch (c) { 7430302Sjoerg case 'v': 7530302Sjoerg verbose++; 7630302Sjoerg break; 7730302Sjoerg 7830302Sjoerg default: 7930302Sjoerg errs++; 8030302Sjoerg break; 8130302Sjoerg } 8230302Sjoerg argv += optind; 8330302Sjoerg argc -= optind; 8430302Sjoerg 8530302Sjoerg if (errs || argc < 1) 8630302Sjoerg usage(); 8730302Sjoerg 8830302Sjoerg ifname = argv[0]; 8930302Sjoerg strncpy(ifr.ifr_name, ifname, sizeof ifr.ifr_name); 9030302Sjoerg 9130302Sjoerg /* use a random AF to create the socket */ 9230302Sjoerg if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 9330302Sjoerg err(EX_UNAVAILABLE, "ifconfig: socket"); 9430302Sjoerg 9530302Sjoerg argc--; 9630302Sjoerg argv++; 9730302Sjoerg 9830302Sjoerg spr.cmd = (int)SPPPIOGDEFS; 9930302Sjoerg ifr.ifr_data = (caddr_t)&spr; 10030302Sjoerg 10130302Sjoerg if (ioctl(s, SIOCGIFGENERIC, &ifr) == -1) 10230302Sjoerg err(EX_OSERR, "SIOCGIFGENERIC(SPPPIOGDEFS)"); 10330302Sjoerg 10430302Sjoerg if (argc == 0) { 10530302Sjoerg /* list only mode */ 10630302Sjoerg print_vals(ifname, &spr); 10730302Sjoerg return 0; 10830302Sjoerg } 10930302Sjoerg 11030302Sjoerg#define startswith(s) strncmp(argv[0], s, (off = strlen(s))) == 0 11130302Sjoerg 11230302Sjoerg while (argc > 0) { 11330302Sjoerg if (startswith("authproto=")) { 11430302Sjoerg cp = argv[0] + off; 11530302Sjoerg if (strcmp(cp, "pap") == 0) 11630302Sjoerg spr.defs.myauth.proto = 11730302Sjoerg spr.defs.hisauth.proto = PPP_PAP; 11830302Sjoerg else if (strcmp(cp, "chap") == 0) 11930302Sjoerg spr.defs.myauth.proto = 12030302Sjoerg spr.defs.hisauth.proto = PPP_CHAP; 12130302Sjoerg else if (strcmp(cp, "none") == 0) 12230302Sjoerg spr.defs.myauth.proto = 12330302Sjoerg spr.defs.hisauth.proto = 0; 12430302Sjoerg else 12530302Sjoerg errx(EX_DATAERR, "bad auth proto: %s", cp); 12630302Sjoerg } else if (startswith("myauthproto=")) { 12730302Sjoerg cp = argv[0] + off; 12830302Sjoerg if (strcmp(cp, "pap") == 0) 12930302Sjoerg spr.defs.myauth.proto = PPP_PAP; 13030302Sjoerg else if (strcmp(cp, "chap") == 0) 13130302Sjoerg spr.defs.myauth.proto = PPP_CHAP; 13230302Sjoerg else if (strcmp(cp, "none") == 0) 13330302Sjoerg spr.defs.myauth.proto = 0; 13430302Sjoerg else 13530302Sjoerg errx(EX_DATAERR, "bad auth proto: %s", cp); 13630302Sjoerg } else if (startswith("myauthname=")) 13730302Sjoerg strncpy(spr.defs.myauth.name, argv[0] + off, 13830302Sjoerg AUTHNAMELEN); 13930302Sjoerg else if (startswith("myauthsecret=") || 14030302Sjoerg startswith("myauthkey=")) 14130302Sjoerg strncpy(spr.defs.myauth.secret, argv[0] + off, 14230302Sjoerg AUTHKEYLEN); 14330302Sjoerg else if (startswith("hisauthproto=")) { 14430302Sjoerg cp = argv[0] + off; 14530302Sjoerg if (strcmp(cp, "pap") == 0) 14630302Sjoerg spr.defs.hisauth.proto = PPP_PAP; 14730302Sjoerg else if (strcmp(cp, "chap") == 0) 14830302Sjoerg spr.defs.hisauth.proto = PPP_CHAP; 14930302Sjoerg else if (strcmp(cp, "none") == 0) 15030302Sjoerg spr.defs.hisauth.proto = 0; 15130302Sjoerg else 15230302Sjoerg errx(EX_DATAERR, "bad auth proto: %s", cp); 15330302Sjoerg } else if (startswith("hisauthname=")) 15430302Sjoerg strncpy(spr.defs.hisauth.name, argv[0] + off, 15530302Sjoerg AUTHNAMELEN); 15630302Sjoerg else if (startswith("hisauthsecret=") || 15730302Sjoerg startswith("hisauthkey=")) 15830302Sjoerg strncpy(spr.defs.hisauth.secret, argv[0] + off, 15930302Sjoerg AUTHKEYLEN); 16030302Sjoerg else if (strcmp(argv[0], "callin") == 0) 16130302Sjoerg spr.defs.hisauth.flags |= AUTHFLAG_NOCALLOUT; 16230302Sjoerg else if (strcmp(argv[0], "always") == 0) 16330302Sjoerg spr.defs.hisauth.flags &= ~AUTHFLAG_NOCALLOUT; 16430302Sjoerg else if (strcmp(argv[0], "norechallenge") == 0) 16530302Sjoerg spr.defs.hisauth.flags |= AUTHFLAG_NORECHALLENGE; 16630302Sjoerg else if (strcmp(argv[0], "rechallenge") == 0) 16730302Sjoerg spr.defs.hisauth.flags &= ~AUTHFLAG_NORECHALLENGE; 16888536Sjoerg else if (strcmp(argv[0], "enable-vj") == 0) 16988536Sjoerg spr.defs.enable_vj = 1; 17088536Sjoerg else if (strcmp(argv[0], "disable-vj") == 0) 17188536Sjoerg spr.defs.enable_vj = 0; 17230302Sjoerg else 17330302Sjoerg errx(EX_DATAERR, "bad parameter: \"%s\"", argv[0]); 17430302Sjoerg 17530302Sjoerg argv++; 17630302Sjoerg argc--; 17730302Sjoerg } 17830302Sjoerg 17930302Sjoerg spr.cmd = (int)SPPPIOSDEFS; 18030302Sjoerg 18130302Sjoerg if (ioctl(s, SIOCSIFGENERIC, &ifr) == -1) 18230302Sjoerg err(EX_OSERR, "SIOCSIFGENERIC(SPPPIOSDEFS)"); 18330302Sjoerg 18430302Sjoerg if (verbose) 18530302Sjoerg print_vals(ifname, &spr); 18630302Sjoerg 18730302Sjoerg return 0; 18830302Sjoerg} 18930302Sjoerg 19032274Scharnierstatic void 19130302Sjoergusage(void) 19230302Sjoerg{ 19332274Scharnier fprintf(stderr, "%s\n%s\n", 19432274Scharnier "usage: spppcontrol [-v] ifname [{my|his}auth{proto|name|secret}=...]", 19532274Scharnier " spppcontrol [-v] ifname callin|always"); 19632274Scharnier exit(EX_USAGE); 19730302Sjoerg} 19830302Sjoerg 19930302Sjoergvoid 20030302Sjoergprint_vals(const char *ifname, struct spppreq *sp) 20130302Sjoerg{ 20230302Sjoerg printf("%s:\tphase=%s\n", ifname, phase_name(sp->defs.pp_phase)); 20330302Sjoerg if (sp->defs.myauth.proto) { 20430302Sjoerg printf("\tmyauthproto=%s myauthname=\"%.*s\"\n", 20530302Sjoerg proto_name(sp->defs.myauth.proto), 20630302Sjoerg AUTHNAMELEN, sp->defs.myauth.name); 20730302Sjoerg } 20830302Sjoerg if (sp->defs.hisauth.proto) { 20930302Sjoerg printf("\thisauthproto=%s hisauthname=\"%.*s\"%s\n", 21030302Sjoerg proto_name(sp->defs.hisauth.proto), 21130302Sjoerg AUTHNAMELEN, sp->defs.hisauth.name, 21230302Sjoerg authflags(sp->defs.hisauth.flags)); 21330302Sjoerg } 21488536Sjoerg printf("\t%sable-vj\n", sp->defs.enable_vj? "en": "dis"); 21530302Sjoerg} 21630302Sjoerg 21730302Sjoergconst char * 21830302Sjoergphase_name(enum ppp_phase phase) 21930302Sjoerg{ 22030302Sjoerg switch (phase) { 22130302Sjoerg case PHASE_DEAD: return "dead"; 22230302Sjoerg case PHASE_ESTABLISH: return "establish"; 22330302Sjoerg case PHASE_TERMINATE: return "terminate"; 22430302Sjoerg case PHASE_AUTHENTICATE: return "authenticate"; 22530302Sjoerg case PHASE_NETWORK: return "network"; 22630302Sjoerg } 22730302Sjoerg return "illegal"; 22830302Sjoerg} 22930302Sjoerg 23030302Sjoergconst char * 23130302Sjoergproto_name(u_short proto) 23230302Sjoerg{ 23330302Sjoerg static char buf[12]; 23430302Sjoerg switch (proto) { 23530302Sjoerg case PPP_PAP: return "pap"; 23630302Sjoerg case PPP_CHAP: return "chap"; 23730302Sjoerg } 23830302Sjoerg sprintf(buf, "0x%x", (unsigned)proto); 23930302Sjoerg return buf; 24030302Sjoerg} 24130302Sjoerg 24230302Sjoergconst char * 24330302Sjoergauthflags(u_short flags) 24430302Sjoerg{ 24544345Sgj static char buf[30]; 24630302Sjoerg buf[0] = '\0'; 24730302Sjoerg if (flags & AUTHFLAG_NOCALLOUT) 24830302Sjoerg strcat(buf, " callin"); 24930302Sjoerg if (flags & AUTHFLAG_NORECHALLENGE) 25030302Sjoerg strcat(buf, " norechallenge"); 25130302Sjoerg return buf; 25230302Sjoerg} 253