void ipv6ll_db_store(struct sockaddr_in6 *sin6, struct sockaddr_in6 *sin6mask, int dbflag, char *ifname) { /* * If linklocal, store a version that will match conf output * with no scope id, ifname in separate database field */ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_INTFACELOCAL(&sin6->sin6_addr)) { sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0; sin6->sin6_scope_id = 0; db_delete_flag_x_ctl_data("ipv6linklocal", ifname, netname6(sin6, sin6mask)); if (dbflag != DB_X_REMOVE) db_insert_flag_x("ipv6linklocal", ifname, 0, dbflag, netname6(sin6, sin6mask)); } }
/* auth proto, auth name, auth key, peer proto, peer name, peer key, peer flag */ int intsppp(char *ifname, int ifs, int argc, char **argv) { struct sauthreq spa; struct ifreq ifr; int set, ch, i, cmd = 0; /* command options for 'auth' */ static struct nopts authopts[] = { { "proto", req_arg, 'p' }, { "name", req_arg, 'n' }, { "key", req_arg, 'k' }, { NULL, 0, 0 } }; /* command options for 'peer' */ static struct nopts peeropts[] = { { "proto", req_arg, 'p' }, { "name", req_arg, 'n' }, { "key", req_arg, 'k' }, { "flag", req_arg, 'f' }, { NULL, 0, 0 } }; /* intsppp commands */ struct intspppcmd { char *name; int cmd; void (*usage)(); struct nopts *nopts; }; struct intspppcmd intspppcmds[] = { { "auth", SPPPIOSMAUTH, authusage, authopts }, { "peer", SPPPIOSHAUTH, peerusage, peeropts }, }; struct intspppcmd *isc = NULL; /* get rid of 'no' arg */ if (NO_ARG(argv[0])) { set = 0; argc--; argv++; } else set = 1; /* point to right intspppcmd */ for (i = 0; i < nitems(intspppcmds); i++) { if (isprefix(argv[0], intspppcmds[i].name)) isc = &intspppcmds[i]; } if (isc == NULL) { printf("%% intsppp: Internal error\n"); return(0); } argc--; argv++; ifr.ifr_data = (caddr_t)&spa; /* setup spa */ memset(&spa, 0, sizeof(spa)); spa.cmd = isc->cmd; /* usage? */ if (argc < 1 && set) { (*isc->usage)(); return(0); } /* parse */ noptind = 0; while ((ch = nopt(argc, argv, isc->nopts)) != -1) switch (ch) { #define __proto 1<<0 case 'p': /* proto */ cmd |= __proto; for (i = 0; i < nitems(spppproto); i++) { if (isprefix(argv[noptind - 1], spppproto[i].name)) spa.proto = spppproto[i].type; } if (!spa.proto) { printf("%% Unknown proto: %s\n", argv[noptind -1 ]); return(0); } break; #define __name 1<<1 case 'n': /* name */ cmd |= __name; if (strlcpy(spa.name, argv[noptind - 1], sizeof(spa.name)) >= sizeof(spa.name)) { printf("%% Name too long (> %lu): %s\n", sizeof(spa.name), argv[noptind - 1]); return(0); } break; #define __key 1<<2 case 'k': /* key */ cmd |= __key; if (strlcpy(spa.secret, argv[noptind - 1], sizeof(spa.secret)) >= sizeof(spa.secret)) { printf("%% Key too long (> %lu): %s\n", sizeof(spa.secret), argv[noptind - 1]); return(0); } break; #define __flag 1<<3 case 'f': /* flag */ cmd |= __flag; if (isprefix(argv[noptind - 1], "callin")) { spa.flags = AUTHFLAG_NOCALLOUT; } else if (isprefix(argv[noptind - 1], "norechallenge")) { spa.flags = AUTHFLAG_NORECHALLENGE; } else { printf("%% Unknown flag: %s", argv[noptind - 1]); return(0); } break; default: printf("%% intsppp: nopt table error\n"); return(0); } if (argc - noptind != 0) { /* leftover salmon */ printf("%% %s", nopterr); if (argv[noptind]) printf(": %s", argv[noptind]); printf("\n"); (*isc->usage)(); return(0); } if (argc < 1) cmd = __proto | __name | __key | __flag; if (!set) { spa.proto = 0; spa.flags = 0; memset(&spa.name, '\0', sizeof(spa.name)); memset(&spa.secret, '\0', sizeof(spa.secret)); } strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(ifs, SIOCSSPPPPARAMS, &ifr) == -1) { printf("%% intspppproto: SIOCSSPPPPARAMS: " "SPPPIOS%sAUTH: %s\n", strerror(errno), isc->cmd == SPPPIOSMAUTH ? "M" : "H"); return 0; } if (cmd & __key) { char type[TYPESZ]; snprintf(type, TYPESZ, "%skey", isc->name); db_delete_flag_x_ctl(type, ifname); if (set) { db_insert_flag_x(type, ifname, 0, DB_X_ENABLE, spa.secret); } } return 0; }
int intrtd(char *ifname, int ifs, int argc, char **argv) { StringList *dbreturn; char *cmdpath, *cmdname; int set; if (NO_ARG(argv[0])) { argv++; argc--; set = 0; } else set = 1; if (isprefix(argv[0], "rtadvd")) { cmdname = "rtadvd"; cmdpath = RTADVD; } else { printf("%% intrtd: Internal error\n"); return 0; } if (argc > 1) { printf ("%% %s\n", cmdname); printf ("%% no %s\n", cmdname); return(0); } dbreturn = sl_init(); if (db_select_flag_x_ctl(dbreturn, cmdname, ifname) < 0) { printf("%% database failure select flag x ctl\n"); sl_free(dbreturn, 1); return(1); } if (dbreturn->sl_cur > 0) { /* already found in db for ifname */ if (!set) { if (db_delete_flag_x_ctl(cmdname, ifname) < 0) printf("%% database delete failure\n"); } else { printf("%% %s already running\n", cmdname); } if (!set && strcmp(cmdname, "rtadvd") == 0) { char *args[] = { PKILL, cmdpath, "-c", "/var/run/rtadvd.0", ifname, '\0' }; cmdargs(PKILL, args); } } else { /* not found in db for ifname */ if (set) { if(db_insert_flag_x(cmdname, ifname, 0, DB_X_ENABLE, NULL) < 0) { printf("%% database insert failure\n"); sl_free(dbreturn, 1); return(1); } } else { printf("%% %s not running\n", cmdname); } if (set && strcmp(cmdname, "rtadvd") == 0) { char *args[] = { cmdpath, "-c", "/var/run/rtadvd.0", ifname, '\0' }; cmdargs(cmdpath, args); } } sl_free(dbreturn, 1); return(0); }
int intlladdr(char *ifname, int ifs, int argc, char **argv) { StringList *hwdaddr; char *lladdr, llorig[sizeof("00:00:00:00:00:00") + 1]; struct ether_addr *addr; struct ifreq ifr; int set; if (NO_ARG(argv[0])) { argv++; argc--; set = 0; } else set = 1; if (set && argc < 2) { printf ("%% lladdr <link level address|random>\n"); printf ("%% no lladdr\n"); return(0); } if ((lladdr = get_hwdaddr(ifname)) == NULL) { printf("%% Failed to retrieve current link level address\n"); return(1); } hwdaddr = sl_init(); if (db_select_flag_x_ctl(hwdaddr, "lladdr", ifname) < 0) { printf("%% database failure select flag x ctl\n"); sl_free(hwdaddr, 1); return(1); } if (hwdaddr->sl_cur > 0) { strlcpy(llorig, hwdaddr->sl_str[0], sizeof(llorig)); if (!set && db_delete_flag_x_ctl("lladdr", ifname) < 0) { printf("%% database delete failure\n"); sl_free(hwdaddr, 1); return(1); } } else { strlcpy(llorig, lladdr, sizeof(llorig)); if (set && db_insert_flag_x("lladdr", ifname, 0, DB_X_ENABLE, llorig) < 0) { printf("%% database delete failure\n"); sl_free(hwdaddr, 1); return(1); } if (!set) { printf("%% No stored lladdr to reinstate\n"); sl_free(hwdaddr, 1); return(1); } } sl_free(hwdaddr, 1); /* At this point, llorig will always represent the booted lladdr */ if (set && isprefix(argv[1], "random")) { struct ether_addr eabuf; arc4random_buf(&eabuf, sizeof eabuf); eabuf.ether_addr_octet[0] &= 0xfc; addr = &eabuf; } else { addr = ether_aton(set ? argv[1] : llorig); if (addr == NULL) { if (set) { printf("%% MAC addresses are six hexadecimal " "fields, up to two digits each,\n" " %% separated with colons" " (1:23:45:ab:cd:ef)\n"); return(1); } else { printf("%% database corrupted, unable to " " retrieve original lladdr\n"); return(1); } } } strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); ifr.ifr_addr.sa_len = ETHER_ADDR_LEN; ifr.ifr_addr.sa_family = AF_LINK; bcopy(addr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN); if(ioctl(ifs, SIOCSIFLLADDR, (caddr_t)&ifr) < 0) { switch(errno) { case EINVAL: printf("%% Requested link level address denied\n"); break; default: printf("%% intlladdr: SIOCSIFLLADDR: %s\n", strerror(errno)); } return(1); } return(0); }