130302Sjoerg/* 288551Sjoerg * Copyright (c) 1997, 2001 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 27114589Sobrien#include <sys/cdefs.h> 28114589Sobrien__FBSDID("$FreeBSD$"); 2932274Scharnier 3088559Sjoerg#include <sys/types.h> 3130302Sjoerg#include <sys/ioctl.h> 3230302Sjoerg#include <sys/socket.h> 3330302Sjoerg 3430302Sjoerg#include <net/if.h> 3530302Sjoerg#include <net/if_sppp.h> 3630302Sjoerg 3730302Sjoerg#include <err.h> 3830302Sjoerg#include <stdio.h> 3978732Sdd#include <stdlib.h> 4030302Sjoerg#include <string.h> 4130302Sjoerg#include <sysexits.h> 4230302Sjoerg#include <unistd.h> 4330302Sjoerg 4432274Scharnierstatic void usage(void); 4530302Sjoergvoid print_vals(const char *ifname, struct spppreq *sp); 4630302Sjoergconst char *phase_name(enum ppp_phase phase); 4730302Sjoergconst char *proto_name(u_short proto); 4830302Sjoergconst char *authflags(u_short flags); 4930302Sjoerg 5030302Sjoerg#define PPP_PAP 0xc023 5130302Sjoerg#define PPP_CHAP 0xc223 5230302Sjoerg 5330302Sjoergint 5430302Sjoergmain(int argc, char **argv) 5530302Sjoerg{ 5630302Sjoerg int s, c; 5730302Sjoerg int errs = 0, verbose = 0; 5830302Sjoerg size_t off; 5988551Sjoerg long to; 6088551Sjoerg char *endp; 6130302Sjoerg const char *ifname, *cp; 6230302Sjoerg struct ifreq ifr; 6330302Sjoerg struct spppreq spr; 6430302Sjoerg 6530302Sjoerg while ((c = getopt(argc, argv, "v")) != -1) 6630302Sjoerg switch (c) { 6730302Sjoerg case 'v': 6830302Sjoerg verbose++; 6930302Sjoerg break; 7030302Sjoerg 7130302Sjoerg default: 7230302Sjoerg errs++; 7330302Sjoerg break; 7430302Sjoerg } 7530302Sjoerg argv += optind; 7630302Sjoerg argc -= optind; 7730302Sjoerg 7830302Sjoerg if (errs || argc < 1) 7930302Sjoerg usage(); 8030302Sjoerg 8130302Sjoerg ifname = argv[0]; 8230302Sjoerg strncpy(ifr.ifr_name, ifname, sizeof ifr.ifr_name); 8330302Sjoerg 8430302Sjoerg /* use a random AF to create the socket */ 8530302Sjoerg if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 8630302Sjoerg err(EX_UNAVAILABLE, "ifconfig: socket"); 8730302Sjoerg 8830302Sjoerg argc--; 8930302Sjoerg argv++; 9030302Sjoerg 91173717Sjb spr.cmd = (uintptr_t) SPPPIOGDEFS; 9230302Sjoerg ifr.ifr_data = (caddr_t)&spr; 9330302Sjoerg 9430302Sjoerg if (ioctl(s, SIOCGIFGENERIC, &ifr) == -1) 9530302Sjoerg err(EX_OSERR, "SIOCGIFGENERIC(SPPPIOGDEFS)"); 9630302Sjoerg 9730302Sjoerg if (argc == 0) { 9830302Sjoerg /* list only mode */ 9930302Sjoerg print_vals(ifname, &spr); 10030302Sjoerg return 0; 10130302Sjoerg } 10230302Sjoerg 10330302Sjoerg#define startswith(s) strncmp(argv[0], s, (off = strlen(s))) == 0 10430302Sjoerg 10530302Sjoerg while (argc > 0) { 10630302Sjoerg if (startswith("authproto=")) { 10730302Sjoerg cp = argv[0] + off; 10830302Sjoerg if (strcmp(cp, "pap") == 0) 10930302Sjoerg spr.defs.myauth.proto = 11030302Sjoerg spr.defs.hisauth.proto = PPP_PAP; 11130302Sjoerg else if (strcmp(cp, "chap") == 0) 11230302Sjoerg spr.defs.myauth.proto = 11330302Sjoerg spr.defs.hisauth.proto = PPP_CHAP; 11430302Sjoerg else if (strcmp(cp, "none") == 0) 11530302Sjoerg spr.defs.myauth.proto = 11630302Sjoerg spr.defs.hisauth.proto = 0; 11730302Sjoerg else 11830302Sjoerg errx(EX_DATAERR, "bad auth proto: %s", cp); 11930302Sjoerg } else if (startswith("myauthproto=")) { 12030302Sjoerg cp = argv[0] + off; 12130302Sjoerg if (strcmp(cp, "pap") == 0) 12230302Sjoerg spr.defs.myauth.proto = PPP_PAP; 12330302Sjoerg else if (strcmp(cp, "chap") == 0) 12430302Sjoerg spr.defs.myauth.proto = PPP_CHAP; 12530302Sjoerg else if (strcmp(cp, "none") == 0) 12630302Sjoerg spr.defs.myauth.proto = 0; 12730302Sjoerg else 12830302Sjoerg errx(EX_DATAERR, "bad auth proto: %s", cp); 12930302Sjoerg } else if (startswith("myauthname=")) 13030302Sjoerg strncpy(spr.defs.myauth.name, argv[0] + off, 13130302Sjoerg AUTHNAMELEN); 13230302Sjoerg else if (startswith("myauthsecret=") || 13330302Sjoerg startswith("myauthkey=")) 13430302Sjoerg strncpy(spr.defs.myauth.secret, argv[0] + off, 13530302Sjoerg AUTHKEYLEN); 13630302Sjoerg else if (startswith("hisauthproto=")) { 13730302Sjoerg cp = argv[0] + off; 13830302Sjoerg if (strcmp(cp, "pap") == 0) 13930302Sjoerg spr.defs.hisauth.proto = PPP_PAP; 14030302Sjoerg else if (strcmp(cp, "chap") == 0) 14130302Sjoerg spr.defs.hisauth.proto = PPP_CHAP; 14230302Sjoerg else if (strcmp(cp, "none") == 0) 14330302Sjoerg spr.defs.hisauth.proto = 0; 14430302Sjoerg else 14530302Sjoerg errx(EX_DATAERR, "bad auth proto: %s", cp); 14630302Sjoerg } else if (startswith("hisauthname=")) 14730302Sjoerg strncpy(spr.defs.hisauth.name, argv[0] + off, 14830302Sjoerg AUTHNAMELEN); 14930302Sjoerg else if (startswith("hisauthsecret=") || 15030302Sjoerg startswith("hisauthkey=")) 15130302Sjoerg strncpy(spr.defs.hisauth.secret, argv[0] + off, 15230302Sjoerg AUTHKEYLEN); 15330302Sjoerg else if (strcmp(argv[0], "callin") == 0) 15430302Sjoerg spr.defs.hisauth.flags |= AUTHFLAG_NOCALLOUT; 15530302Sjoerg else if (strcmp(argv[0], "always") == 0) 15630302Sjoerg spr.defs.hisauth.flags &= ~AUTHFLAG_NOCALLOUT; 15730302Sjoerg else if (strcmp(argv[0], "norechallenge") == 0) 15830302Sjoerg spr.defs.hisauth.flags |= AUTHFLAG_NORECHALLENGE; 15930302Sjoerg else if (strcmp(argv[0], "rechallenge") == 0) 16030302Sjoerg spr.defs.hisauth.flags &= ~AUTHFLAG_NORECHALLENGE; 16188551Sjoerg else if (startswith("lcp-timeout=")) { 16288551Sjoerg cp = argv[0] + off; 16388551Sjoerg to = strtol(cp, &endp, 10); 16488551Sjoerg if (*cp == '\0' || *endp != '\0' || 16588551Sjoerg /* 16688551Sjoerg * NB: 10 ms is the minimal possible value for 16788551Sjoerg * hz=100. We assume no kernel has less clock 16888551Sjoerg * frequency than that... 16988551Sjoerg */ 17088551Sjoerg to < 10 || to > 20000) 17188551Sjoerg errx(EX_DATAERR, "bad lcp timeout value: %s", 17288551Sjoerg cp); 17388551Sjoerg spr.defs.lcp.timeout = to; 17488551Sjoerg } else if (strcmp(argv[0], "enable-vj") == 0) 17588536Sjoerg spr.defs.enable_vj = 1; 17688536Sjoerg else if (strcmp(argv[0], "disable-vj") == 0) 17788536Sjoerg spr.defs.enable_vj = 0; 17888724Sjoerg else if (strcmp(argv[0], "enable-ipv6") == 0) 17988724Sjoerg spr.defs.enable_ipv6 = 1; 18088724Sjoerg else if (strcmp(argv[0], "disable-ipv6") == 0) 18188724Sjoerg spr.defs.enable_ipv6 = 0; 18230302Sjoerg else 18330302Sjoerg errx(EX_DATAERR, "bad parameter: \"%s\"", argv[0]); 18430302Sjoerg 18530302Sjoerg argv++; 18630302Sjoerg argc--; 18730302Sjoerg } 18830302Sjoerg 189173717Sjb spr.cmd = (uintptr_t)SPPPIOSDEFS; 19030302Sjoerg 19130302Sjoerg if (ioctl(s, SIOCSIFGENERIC, &ifr) == -1) 19230302Sjoerg err(EX_OSERR, "SIOCSIFGENERIC(SPPPIOSDEFS)"); 19330302Sjoerg 19430302Sjoerg if (verbose) 19530302Sjoerg print_vals(ifname, &spr); 19630302Sjoerg 19730302Sjoerg return 0; 19830302Sjoerg} 19930302Sjoerg 20032274Scharnierstatic void 20130302Sjoergusage(void) 20230302Sjoerg{ 20332274Scharnier fprintf(stderr, "%s\n%s\n", 20432274Scharnier "usage: spppcontrol [-v] ifname [{my|his}auth{proto|name|secret}=...]", 20532274Scharnier " spppcontrol [-v] ifname callin|always"); 20632274Scharnier exit(EX_USAGE); 20730302Sjoerg} 20830302Sjoerg 20930302Sjoergvoid 21030302Sjoergprint_vals(const char *ifname, struct spppreq *sp) 21130302Sjoerg{ 21230302Sjoerg printf("%s:\tphase=%s\n", ifname, phase_name(sp->defs.pp_phase)); 21330302Sjoerg if (sp->defs.myauth.proto) { 21430302Sjoerg printf("\tmyauthproto=%s myauthname=\"%.*s\"\n", 21530302Sjoerg proto_name(sp->defs.myauth.proto), 21630302Sjoerg AUTHNAMELEN, sp->defs.myauth.name); 21730302Sjoerg } 21830302Sjoerg if (sp->defs.hisauth.proto) { 21930302Sjoerg printf("\thisauthproto=%s hisauthname=\"%.*s\"%s\n", 22030302Sjoerg proto_name(sp->defs.hisauth.proto), 22130302Sjoerg AUTHNAMELEN, sp->defs.hisauth.name, 22230302Sjoerg authflags(sp->defs.hisauth.flags)); 22330302Sjoerg } 22488551Sjoerg printf("\tlcp-timeout=%d ms\n", sp->defs.lcp.timeout); 22588536Sjoerg printf("\t%sable-vj\n", sp->defs.enable_vj? "en": "dis"); 22688724Sjoerg printf("\t%sable-ipv6\n", sp->defs.enable_ipv6? "en": "dis"); 22730302Sjoerg} 22830302Sjoerg 22930302Sjoergconst char * 23030302Sjoergphase_name(enum ppp_phase phase) 23130302Sjoerg{ 23230302Sjoerg switch (phase) { 23330302Sjoerg case PHASE_DEAD: return "dead"; 23430302Sjoerg case PHASE_ESTABLISH: return "establish"; 23530302Sjoerg case PHASE_TERMINATE: return "terminate"; 23630302Sjoerg case PHASE_AUTHENTICATE: return "authenticate"; 23730302Sjoerg case PHASE_NETWORK: return "network"; 23830302Sjoerg } 23930302Sjoerg return "illegal"; 24030302Sjoerg} 24130302Sjoerg 24230302Sjoergconst char * 24330302Sjoergproto_name(u_short proto) 24430302Sjoerg{ 24530302Sjoerg static char buf[12]; 24630302Sjoerg switch (proto) { 24730302Sjoerg case PPP_PAP: return "pap"; 24830302Sjoerg case PPP_CHAP: return "chap"; 24930302Sjoerg } 25030302Sjoerg sprintf(buf, "0x%x", (unsigned)proto); 25130302Sjoerg return buf; 25230302Sjoerg} 25330302Sjoerg 25430302Sjoergconst char * 25530302Sjoergauthflags(u_short flags) 25630302Sjoerg{ 25744345Sgj static char buf[30]; 25830302Sjoerg buf[0] = '\0'; 25930302Sjoerg if (flags & AUTHFLAG_NOCALLOUT) 26030302Sjoerg strcat(buf, " callin"); 26130302Sjoerg if (flags & AUTHFLAG_NORECHALLENGE) 26230302Sjoerg strcat(buf, " norechallenge"); 26330302Sjoerg return buf; 26430302Sjoerg} 265