1 /* $OpenBSD: sysctl.c,v 1.12 2018/06/25 16:29:00 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Theo de Raadt <deraadt@openbsd.org> 5 * Copyright (c) 2007 Kenneth R. Westerback <krw@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/types.h> 21 #include <sys/socket.h> 22 #include <sys/sysctl.h> 23 #include <sys/uio.h> 24 25 #include <netinet/in.h> 26 27 #include <ctype.h> 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <unistd.h> 32 33 #define SOIIKEY_LEN 16 34 35 struct var { 36 char *name; 37 int (*print)(struct var *); 38 int nmib; 39 int mib[3]; 40 }; 41 42 int pstring(struct var *); 43 int pint(struct var *); 44 45 struct var vars[] = { 46 { "kern.osrelease", pstring, 2, 47 { CTL_KERN, KERN_OSRELEASE }}, 48 { "hw.machine", pstring, 2, 49 { CTL_HW, HW_MACHINE }}, 50 { "hw.model", pstring, 2, 51 { CTL_HW, HW_MODEL }}, 52 { "hw.product", pstring, 2, 53 { CTL_HW, HW_PRODUCT }}, 54 { "hw.disknames", pstring, 2, 55 { CTL_HW, HW_DISKNAMES }}, 56 { "hw.ncpufound", pint, 2, 57 { CTL_HW, HW_NCPUFOUND }}, 58 }; 59 60 int nflag; 61 char *name; 62 63 int 64 pint(struct var *v) 65 { 66 int n; 67 size_t len = sizeof(n); 68 69 if (sysctl(v->mib, v->nmib, &n, &len, NULL, 0) != -1) { 70 if (nflag == 0) 71 printf("%s=", v->name); 72 printf("%d\n", n); 73 return (0); 74 } 75 return (1); 76 } 77 78 int 79 pstring(struct var *v) 80 { 81 char *p; 82 size_t len; 83 84 if (sysctl(v->mib, v->nmib, NULL, &len, NULL, 0) != -1) 85 if ((p = malloc(len)) != NULL) 86 if (sysctl(v->mib, v->nmib, p, &len, NULL, 0) != -1) { 87 if (nflag == 0) 88 printf("%s=", v->name); 89 printf("%s\n", p); 90 return (0); 91 } 92 return (1); 93 } 94 95 int 96 parse_hex_char(char ch) 97 { 98 if (ch >= '0' && ch <= '9') 99 return (ch - '0'); 100 101 ch = tolower((unsigned char)ch); 102 if (ch >= 'a' && ch <= 'f') 103 return (ch - 'a' + 10); 104 105 return (-1); 106 } 107 108 int 109 set_soii_key(char *src) 110 { 111 uint8_t key[SOIIKEY_LEN]; 112 int mib[4] = {CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_SOIIKEY}; 113 int i, c; 114 115 for(i = 0; i < SOIIKEY_LEN; i++) { 116 if ((c = parse_hex_char(src[2 * i])) == -1) 117 return (-1); 118 key[i] = c << 4; 119 if ((c = parse_hex_char(src[2 * i + 1])) == -1) 120 return (-1); 121 key[i] |= c; 122 } 123 124 return sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, NULL, key, 125 SOIIKEY_LEN); 126 } 127 128 int 129 main(int argc, char *argv[]) 130 { 131 int ch, i; 132 133 while ((ch = getopt(argc, argv, "n")) != -1) { 134 switch (ch) { 135 case 'n': 136 nflag = 1; 137 break; 138 default: 139 fprintf(stderr, "usage: sysctl [-n] name\n"); 140 exit(1); 141 } 142 } 143 144 argc -= optind; 145 argv += optind; 146 147 if (argc == 0) { 148 for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) 149 (vars[i].print)(&vars[i]); 150 exit(0); 151 } 152 153 while (argc--) { 154 name = *argv++; 155 /* 156 * strlen("net.inet6.ip6.soiikey=" 157 * "00000000000000000000000000000000") == 54 158 * strlen("net.inet6.ip6.soiikey=") == 22 159 */ 160 if (strlen(name) == 54 && strncmp(name, 161 "net.inet6.ip6.soiikey=", 22) == 0) { 162 set_soii_key(name + 22); 163 continue; 164 } 165 166 for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) { 167 if (strcmp(name, vars[i].name) == 0) { 168 (vars[i].print)(&vars[i]); 169 break; 170 } 171 } 172 } 173 174 exit(0); 175 } 176