1 /* $OpenBSD: sysctl.c,v 1.15 2023/05/22 09:29:54 kn 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/time.h> 23 #include <sys/sysctl.h> 24 #include <sys/uio.h> 25 26 #include <netinet/in.h> 27 28 #include <ctype.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <unistd.h> 33 34 #include <machine/cpu.h> 35 36 #define SOIIKEY_LEN 16 37 38 struct var { 39 char *name; 40 int (*print)(struct var *); 41 int nmib; 42 int mib[3]; 43 }; 44 45 int pstring(struct var *); 46 int pint(struct var *); 47 48 struct var vars[] = { 49 { "kern.osrelease", pstring, 2, 50 { CTL_KERN, KERN_OSRELEASE }}, 51 { "hw.machine", pstring, 2, 52 { CTL_HW, HW_MACHINE }}, 53 { "hw.model", pstring, 2, 54 { CTL_HW, HW_MODEL }}, 55 { "hw.product", pstring, 2, 56 { CTL_HW, HW_PRODUCT }}, 57 { "hw.disknames", pstring, 2, 58 { CTL_HW, HW_DISKNAMES }}, 59 { "hw.ncpufound", pint, 2, 60 { CTL_HW, HW_NCPUFOUND }}, 61 #ifdef CPU_COMPATIBLE 62 { "machdep.compatible", pstring, 2, 63 { CTL_MACHDEP, CPU_COMPATIBLE }}, 64 #endif 65 }; 66 67 int nflag; 68 char *name; 69 70 int 71 pint(struct var *v) 72 { 73 int n; 74 size_t len = sizeof(n); 75 76 if (sysctl(v->mib, v->nmib, &n, &len, NULL, 0) != -1) { 77 if (nflag == 0) 78 printf("%s=", v->name); 79 printf("%d\n", n); 80 return (0); 81 } 82 return (1); 83 } 84 85 int 86 pstring(struct var *v) 87 { 88 char *p; 89 size_t len; 90 91 if (sysctl(v->mib, v->nmib, NULL, &len, NULL, 0) != -1) 92 if ((p = malloc(len)) != NULL) 93 if (sysctl(v->mib, v->nmib, p, &len, NULL, 0) != -1) { 94 if (nflag == 0) 95 printf("%s=", v->name); 96 printf("%s\n", p); 97 return (0); 98 } 99 return (1); 100 } 101 102 int 103 parse_hex_char(char ch) 104 { 105 if (ch >= '0' && ch <= '9') 106 return (ch - '0'); 107 108 ch = tolower((unsigned char)ch); 109 if (ch >= 'a' && ch <= 'f') 110 return (ch - 'a' + 10); 111 112 return (-1); 113 } 114 115 int 116 set_soii_key(char *src) 117 { 118 uint8_t key[SOIIKEY_LEN]; 119 int mib[4] = {CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_SOIIKEY}; 120 int i, c; 121 122 for(i = 0; i < SOIIKEY_LEN; i++) { 123 if ((c = parse_hex_char(src[2 * i])) == -1) 124 return (-1); 125 key[i] = c << 4; 126 if ((c = parse_hex_char(src[2 * i + 1])) == -1) 127 return (-1); 128 key[i] |= c; 129 } 130 131 return sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, NULL, key, 132 SOIIKEY_LEN); 133 } 134 135 int 136 main(int argc, char *argv[]) 137 { 138 int ch, i; 139 140 while ((ch = getopt(argc, argv, "n")) != -1) { 141 switch (ch) { 142 case 'n': 143 nflag = 1; 144 break; 145 default: 146 fprintf(stderr, "usage: sysctl [-n] [name]\n"); 147 exit(1); 148 } 149 } 150 151 argc -= optind; 152 argv += optind; 153 154 if (argc == 0) { 155 for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) 156 (vars[i].print)(&vars[i]); 157 exit(0); 158 } 159 160 while (argc--) { 161 name = *argv++; 162 /* 163 * strlen("net.inet6.ip6.soiikey=" 164 * "00000000000000000000000000000000") == 54 165 * strlen("net.inet6.ip6.soiikey=") == 22 166 */ 167 if (strlen(name) == 54 && strncmp(name, 168 "net.inet6.ip6.soiikey=", 22) == 0) { 169 set_soii_key(name + 22); 170 continue; 171 } 172 173 for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) { 174 if (strcmp(name, vars[i].name) == 0) { 175 (vars[i].print)(&vars[i]); 176 break; 177 } 178 } 179 } 180 181 exit(0); 182 } 183