Loading...
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
/*
 * Copyright (c) 2000-2021 Apple Inc. All rights reserved.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
 *
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. The rights granted to you under the License
 * may not be used to create, or enable the creation or redistribution of,
 * unlawful or unlicensed copies of an Apple operating system, or to
 * circumvent, violate, or enable the circumvention or violation of, any
 * terms of an Apple operating system software license agreement.
 *
 * Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this file.
 *
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
 */
/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
/*
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Mike Karels at Berkeley Software Design, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)sysctl.h	8.1 (Berkeley) 6/2/93
 */
/*
 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
 * support for mandatory and extensible security protections.  This notice
 * is included in support of clause 2.2 (b) of the Apple Public License,
 * Version 2.0.
 */

#ifndef _SYS_SYSCTL_H_
#define _SYS_SYSCTL_H_

/*
 * These are for the eproc structure defined below.
 */
#include <sys/cdefs.h>

#include <sys/appleapiopts.h>
#ifndef KERNEL
#include <sys/time.h>
#include <sys/ucred.h>
#else
#ifdef XNU_KERNEL_PRIVATE
#include <kern/startup.h>
#include <libkern/section_keywords.h>
#else
#include <libkern/sysctl.h>
#include <os/base.h>
#endif /* XNU_KERNEL_PRIVATE */
#endif /* KERNEL */

#include <sys/proc.h>
#include <sys/vm.h>

/*
 * Definitions for sysctl call.  The sysctl call uses a hierarchical name
 * for objects that can be examined or modified.  The name is expressed as
 * a sequence of integers.  Like a file path name, the meaning of each
 * component depends on its place in the hierarchy.  The top-level and kern
 * identifiers are defined here, and other identifiers are defined in the
 * respective subsystem header files.
 */

#define CTL_MAXNAME     12      /* largest number of components supported */

/*
 * Each subsystem defined by sysctl defines a list of variables
 * for that subsystem. Each name is either a node with further
 * levels defined below it, or it is a leaf of some particular
 * type given below. Each sysctl level defines a set of name/type
 * pairs to be used by sysctl(1) in manipulating the subsystem.
 *
 * When declaring new sysctl names, use the CTLFLAG_LOCKED flag in the
 * type to indicate that all necessary locking will be handled
 * within the sysctl.
 *
 * Any sysctl defined without CTLFLAG_LOCKED is considered legacy
 * and will be protected by a global mutex.
 *
 * Note:	This is not optimal, so it is best to handle locking
 *		yourself, if you are able to do so.  A simple design
 *		pattern for use to avoid in a single function known
 *		to potentially be in the paging path ot doing a DMA
 *		to physical memory in a user space process is:
 *
 *			lock
 *			perform operation vs. local buffer
 *			unlock
 *			SYSCTL_OUT(rey, local buffer, length)
 *
 *		...this assumes you are not using a deep call graph
 *		or are unable to pass a local buffer address as a
 *		parameter into your deep call graph.
 *
 *		Note that very large user buffers can fail the wire
 *		if to do so would require more physical pages than
 *		are available (the caller will get an ENOMEM error,
 *		see sysctl_mem_hold() for details).
 */
struct ctlname {
	char    *ctl_name;      /* subsystem name */
	int     ctl_type;       /* type of name */
};

#define CTLTYPE             0xf             /* Mask for the type */
#define CTLTYPE_NODE        1               /* name is a node */
#define CTLTYPE_INT         2               /* name describes an integer */
#define CTLTYPE_STRING      3               /* name describes a string */
#define CTLTYPE_QUAD        4               /* name describes a 64-bit number */
#define CTLTYPE_OPAQUE      5               /* name describes a structure */
#define CTLTYPE_STRUCT      CTLTYPE_OPAQUE  /* name describes a structure */

#define CTLFLAG_RD          0x80000000      /* Allow reads of variable */
#define CTLFLAG_WR          0x40000000      /* Allow writes to the variable */
#define CTLFLAG_RW          (CTLFLAG_RD|CTLFLAG_WR)
#define CTLFLAG_NOLOCK      0x20000000      /* XXX Don't Lock */
#define CTLFLAG_ANYBODY     0x10000000      /* All users can set this var */
#define CTLFLAG_SECURE      0x08000000      /* Permit set only if securelevel<=0 */
#define CTLFLAG_MASKED      0x04000000      /* deprecated variable, do not display */
#define CTLFLAG_NOAUTO      0x02000000      /* do not auto-register */
#define CTLFLAG_KERN        0x01000000      /* valid inside the kernel */
#define CTLFLAG_LOCKED      0x00800000      /* node will handle locking itself */
#define CTLFLAG_OID2        0x00400000      /* struct sysctl_oid has version info */
#if XNU_KERNEL_PRIVATE
#define CTLFLAG_PERMANENT   0x00200000      /* permanent sysctl_oid */
#endif
#define CTLFLAG_EXPERIMENT 0x00100000 /* Allows writing w/ the trial experiment entitlement. */

/*
 * USE THIS instead of a hardwired number from the categories below
 * to get dynamically assigned sysctl entries using the linker-set
 * technology. This is the way nearly all new sysctl variables should
 * be implemented.
 *
 * e.g. SYSCTL_INT(_parent, OID_AUTO, name, CTLFLAG_RW, &variable, 0, "");
 *
 * Note that linker set technology will automatically register all nodes
 * declared like this on kernel initialization, UNLESS they are defined
 * in I/O-Kit. In this case, you have to call sysctl_register_oid()
 * manually - just like in a KEXT.
 */
#define OID_AUTO              (-1)
#if XNU_KERNEL_PRIVATE
/*
 * Used to allow for most of the core kernel sysctl OIDs to be in immutable
 * memory. The nodes that can be extensible have a fake first node with this
 * particular oid_number which hangs a second mutable list from this node.
 *
 * This node is always first when it is used
 */
#define OID_MUTABLE_ANCHOR    (INT_MIN)
#endif
#define OID_AUTO_START        100 /* conventional */

#ifdef KERNEL
#define SYSCTL_HANDLER_ARGS \
	(struct sysctl_oid *oidp __unused, void *arg1 __unused, int arg2 __unused, \
	struct sysctl_req *req)


/*
 * This describes the access space for a sysctl request.  This is needed
 * so that we can use the interface from the kernel or from user-space.
 */
struct sysctl_req {
	struct proc     *p;
	int             lock;
	user_addr_t     oldptr;         /* pointer to user supplied buffer */
	size_t          oldlen;         /* user buffer length (also returned) */
	size_t          oldidx;         /* total data iteratively copied out */
	int             (*oldfunc)(struct sysctl_req *, const void *, size_t);
	user_addr_t     newptr;         /* buffer containing new value */
	size_t          newlen;         /* length of new value */
	size_t          newidx;         /* total data iteratively copied in */
	int             (*newfunc)(struct sysctl_req *, void *, size_t);
};

SLIST_HEAD(sysctl_oid_list, sysctl_oid);

#define SYSCTL_OID_VERSION      1       /* current OID structure version */

/*
 * This describes one "oid" in the MIB tree.  Potentially more nodes can
 * be hidden behind it, expanded by the handler.
 *
 * NOTES:	We implement binary comparibility between CTLFLAG_OID2 and
 *		pre-CTLFLAG_OID2 structure in sysctl_register_oid() and in
 *		sysctl_unregister_oid() using the fact that the fields up
 *		to oid_fmt are unchanged, and that the field immediately
 *		following is on an alignment boundary following a pointer
 *		type and is also a pointer.  This lets us get the previous
 *		size of the structure, and the copy-cut-off point, using
 *		the offsetof() language primitive, and these values  are
 *		used in conjunction with the fact that earlier and future
 *		statically compiled sysctl_oid structures are declared via
 *		macros.  This lets us overload the macros so that the addition
 *		of the CTLFLAG_OID2 in newly compiled code containing sysctl
 *		node declarations, subsequently allowing us to to avoid
 *		changing the KPI used for non-static (un)registration in
 *		KEXTs.
 *
 *		Non CTLFLAG_OID2 based sysctls are deprecated and unavailable
 *		to non Intel platforms.
 *
 *		This depends on the fact that people declare SYSCTLs,
 *		rather than declaring sysctl_oid structures.  All new code
 *		should avoid declaring struct sysctl_oid's directly without
 *		the macros; the current risk for this is limited to losing
 *		your description field and ending up with a malloc'ed copy,
 *		as if it were a legacy binary static declaration via SYSCTL;
 *		in the future, we may deprecate access to a named structure
 *		type in third party code.  Use the macros, or our code will
 *		end up with compile errors when that happens.
 *
 *		Please try to include a long description of the field in any
 *		new sysctl declarations (all the macros support this).  This
 *		field may be the only human readable documentation your users
 *		get for your sysctl.
 */
struct sysctl_oid {
	struct sysctl_oid_list * OS_PTRAUTH_SIGNED_PTR("sysctl_oid.oid_parent") oid_parent;
	SLIST_ENTRY(sysctl_oid) oid_link;
	int             oid_number;
	int             oid_kind;
	void            *oid_arg1;
	int             oid_arg2;
	const char      *oid_name;
	int             (*oid_handler)SYSCTL_HANDLER_ARGS;
	const char      *oid_fmt;
	const char      *oid_descr; /* offsetof() field / long description */
	int             oid_version;
	int             oid_refcnt;
};

#define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l)
#define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l)

typedef int (* sysctl_handler_t) SYSCTL_HANDLER_ARGS;

__BEGIN_DECLS

/* old interface */
int sysctl_handle_int SYSCTL_HANDLER_ARGS;
int sysctl_handle_long SYSCTL_HANDLER_ARGS;
int sysctl_handle_quad SYSCTL_HANDLER_ARGS;
int sysctl_handle_int2quad SYSCTL_HANDLER_ARGS;
int sysctl_handle_string SYSCTL_HANDLER_ARGS;
int sysctl_handle_opaque SYSCTL_HANDLER_ARGS;
/* new interface */
int sysctl_io_number(struct sysctl_req *req, long long bigValue, size_t valueSize, void *pValue, int *changed);
int sysctl_io_string(struct sysctl_req *req, char *pValue, size_t valueSize, int trunc, int *changed);
int sysctl_io_opaque(struct sysctl_req *req, void *pValue, size_t valueSize, int *changed);

/*
 * These functions are used to add/remove an oid from the mib.
 */
void sysctl_register_oid(struct sysctl_oid *oidp);
void sysctl_unregister_oid(struct sysctl_oid *oidp);

#define nvram_osenvironment "osenvironment"
void sysctl_set_osenvironment(unsigned int size, const void* value);
void sysctl_unblock_osenvironment(void);

/* Deprecated */
void sysctl_register_fixed(void) __deprecated;

__END_DECLS

/* Declare an oid to allow child oids to be added to it. */
#define SYSCTL_DECL(name)                                       \
	extern struct sysctl_oid_list sysctl_##name##_children

/*
 * Macros to define sysctl entries.  Which to use?  Pure data that are
 * returned without modification, SYSCTL_<data type> is for you, like
 * SYSCTL_QUAD for a 64-bit value.  When you want to run a handler of your
 * own, SYSCTL_PROC.
 *
 * parent:	parent in name hierarchy (e.g. _kern for "kern")
 * nbr:		ID.  Almost certainly OID_AUTO ("pick one for me") for you.
 * name:	name for this particular item (e.g. "thesysctl" for "kern.thesysctl")
 * kind/access: Control flags (CTLFLAG_*).  Some notable options include:
 *                      CTLFLAG_ANYBODY:        non-root users allowed
 *                      CTLFLAG_MASKED:	        don't show in sysctl listing in userland
 *                      CTLFLAG_LOCKED:		does own locking (no additional protection needed)
 *                      CTLFLAG_KERN:		valid inside kernel (best avoided generally)
 *                      CTLFLAG_WR:		"new" value accepted
 * a1, a2:	entry-data, passed to handler (see specific macros)
 * Format String: Tells "sysctl" tool how to print data from this entry.
 *	                "A" - string
 *	                "I" - list of integers. "IU" - list of unsigned integers. space-separated.
 *	                "-" - do not print
 *	                "L" - longs, as ints with I
 *			"P" - pointer
 *                      "Q" - quads
 *                      "S","T" - clock info, see sysctl.c in system_cmds (you probably don't need this)
 * Description: unused
 */


/* This constructs a "raw" MIB oid. */
#define SYSCTL_STRUCT_INIT(parent, nbr, name, kind, a1, a2, fn, fmt, desc) {    \
	    .oid_parent     = &sysctl_##parent##_children,                      \
	    .oid_number     = nbr,                                              \
	    .oid_kind       = (int)(kind | CTLFLAG_OID2),                       \
	    .oid_arg1       = a1,                                               \
	    .oid_arg2       = (int)(a2),                                        \
	    .oid_name       = #name,                                            \
	    .oid_handler    = fn,                                               \
	    .oid_fmt        = fmt,                                              \
	    .oid_descr      = desc,                                             \
	    .oid_version    = SYSCTL_OID_VERSION,                               \
	}

#define __SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
	struct sysctl_oid sysctl_##parent##_##name = SYSCTL_STRUCT_INIT(\
	    parent, nbr, name, kind, a1, a2, handler, fmt, descr)

#if XNU_KERNEL_PRIVATE

/*
 * Core kernel registers sysctls before lockdown and protects those entries
 * in immutable memory.
 *
 * When a node needs to support dynamic extension after lockdown, it needs to be
 * declared with SYSCTL_EXTENSIBLE_NODE() to insert a dummy "OID_MUTABLE_ANCHOR"
 * node in this node chain which will allow extensibility.
 *
 * OIDs that are to be inserted dynamically based on system properties that
 * aren't known at compile time, have three options, in increasing order of
 * unsafety:
 *
 * - The OID can use the CTLFLAG_NOAUTO flag. Such entries aren't inserted to
 *   the sysctl tree automatically but will be made read-only at lock down.
 *
 *   Such entries must be inserted in the STARTUP_SUB_SYSCTL "Middle" phase
 *   using sysctl_register_oid_early().
 *
 * - The OID can be always registered and test whether it is ready to operate.
 *   When it is not, it must return ENOENT which simulates an absent entry.
 *
 *   This however has the downside that the entry is still resolvable as an MIB
 *   or listed in `sysctl -a` when it isn't masked.
 *
 *   This is acceptable for sysctls that will become valid quickly during boot
 *   (but after lockdown).
 *
 * - SYSCTL_OID_MANUAL / SYSCTL_NODE_MANUAL can be used for completely
 *   dynamic/manual oid registration. Such nodes must be registered with
 *   sysctl_register_oid() after lockdown.
 *
 *   This is the least preferred solution.
 */

__BEGIN_DECLS
void sysctl_register_oid_early(struct sysctl_oid *oidp);
__END_DECLS

#define SYSCTL_OID_MANUAL(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
	__XNU_PRIVATE_EXTERN                                                    \
	__SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr)

#define SYSCTL_NODE_MANUAL(parent, nbr, name, access, handler, descr)           \
	struct sysctl_oid_list sysctl_##parent##_##name##_children;             \
	__XNU_PRIVATE_EXTERN                                                    \
	__SYSCTL_OID(parent, nbr, name, CTLTYPE_NODE|access,                    \
	    &sysctl_##parent##_##name##_children, 0, handler, "N", descr);

#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr)        \
	__security_const_late __XNU_PRIVATE_EXTERN                              \
	__SYSCTL_OID(parent, nbr, name, CTLFLAG_PERMANENT|kind,                 \
	    a1, a2, handler, fmt, descr);                                       \
	__STARTUP_ARG(sysctl_##parent, _##name,                                 \
	    SYSCTL, STARTUP_RANK_SECOND, sysctl_register_oid_early,             \
	    &sysctl_##parent##_##name)

#define __SYSCTL_NODE(parent, nbr, name, access, handler, descr)                \
	__security_const_late                                                   \
	struct sysctl_oid_list sysctl_##parent##_##name##_children;             \
	__security_const_late __XNU_PRIVATE_EXTERN                              \
	__SYSCTL_OID(parent, nbr, name, CTLFLAG_PERMANENT|CTLTYPE_NODE|access,  \
	    &sysctl_##parent##_##name##_children, 0, handler, "N", descr);      \
	__STARTUP_ARG(sysctl_##parent, _##name,                                 \
	    SYSCTL, STARTUP_RANK_FIRST, sysctl_register_oid_early,              \
	    &sysctl_##parent##_##name)

#define __SYSCTL_EXTENSION_NODE(name)                                           \
	static __security_read_write                                            \
	struct sysctl_oid_list sysctl_##name##_children_mutable;                \
	static __security_const_late                                            \
	struct sysctl_oid sysctl_##name##_wranchor = {                          \
	    .oid_parent     = &sysctl_##name##_children,                        \
	    .oid_number     = OID_MUTABLE_ANCHOR,                               \
	    .oid_kind       = CTLFLAG_OID2 | CTLFLAG_PERMANENT,                 \
	    .oid_arg1       = &sysctl_##name##_children_mutable,                \
	    .oid_name       = "__anchor__(" #name ")",                          \
	    .oid_version    = SYSCTL_OID_VERSION,                               \
	};                                                                      \
	__STARTUP_ARG(sysctl_##name, _wranchor,                                 \
	    SYSCTL, STARTUP_RANK_LAST, sysctl_register_oid_early,               \
	    &sysctl_##name##_wranchor)

#define SYSCTL_NODE(parent, nbr, name, access, handler, descr)                  \
	__XNU_PRIVATE_EXTERN                                                    \
	__SYSCTL_NODE(parent, nbr, name, access, handler, descr)

#define SYSCTL_EXTENSIBLE_NODE(parent, nbr, name, access, handler, descr)       \
	__SYSCTL_NODE(parent, nbr, name, access, handler, descr);               \
	__SYSCTL_EXTENSION_NODE(parent##_##name)
#else
#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
	__SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr)

/* This constructs a node from which other oids can hang. */
#define SYSCTL_NODE(parent, nbr, name, access, handler, descr)                  \
	struct sysctl_oid_list sysctl_##parent##_##name##_children;             \
	SYSCTL_OID(parent, nbr, name, CTLTYPE_NODE|access,                      \
	    &sysctl_##parent##_##name##_children, 0, handler, "N", descr)
#endif /* XNU_KERNEL_PRIVATE */

/* Oid for a string.  len can be 0 to indicate '\0' termination. */
#define SYSCTL_STRING(parent, nbr, name, access, arg, len, descr) \
	SYSCTL_OID(parent, nbr, name, CTLTYPE_STRING|access, \
	    arg, len, sysctl_handle_string, "A", descr)

#define SYSCTL_COMPAT_INT(parent, nbr, name, access, ptr, val, descr) \
	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
	    ptr, val, sysctl_handle_int, "I", descr)

#define SYSCTL_COMPAT_UINT(parent, nbr, name, access, ptr, val, descr) \
	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
	    ptr, val, sysctl_handle_int, "IU", descr)

/* Oid for an int.  If ptr is NULL, val is returned. */
#define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) \
	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
	    ptr, val, sysctl_handle_int, "I", descr); \
	_Static_assert(__builtin_constant_p(ptr) || sizeof(*(ptr)) == sizeof(int), \
	    "must be integer sized");

/* Oid for an unsigned int.  If ptr is NULL, val is returned. */
#define SYSCTL_UINT(parent, nbr, name, access, ptr, val, descr) \
	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
	    ptr, val, sysctl_handle_int, "IU", descr); \
	_Static_assert(__builtin_constant_p(ptr) || sizeof(*(ptr)) == sizeof(unsigned int), \
	    "must be integer sized");

/* Oid for a long.  The pointer must be non NULL. */
#define SYSCTL_LONG(parent, nbr, name, access, ptr, descr) \
	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
	    ptr, 0, sysctl_handle_long, "L", descr); \
	_Static_assert(__builtin_constant_p(ptr) || sizeof(*(ptr)) == sizeof(long), \
	    "must be long sized");

/* Oid for a unsigned long.  The pointer must be non NULL. */
#define SYSCTL_ULONG(parent, nbr, name, access, ptr, descr) \
	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
	    ptr, 0, sysctl_handle_long, "LU", descr); \
	_Static_assert(__builtin_constant_p(ptr) || sizeof(*(ptr)) == sizeof(unsigned long), \
	    "must be long sized");

/* Oid for a quad.  The pointer must be non NULL. */
#define SYSCTL_QUAD(parent, nbr, name, access, ptr, descr) \
	SYSCTL_OID(parent, nbr, name, CTLTYPE_QUAD|access, \
	    ptr, 0, sysctl_handle_quad, "Q", descr); \
	_Static_assert(__builtin_constant_p(ptr) || sizeof(*(ptr)) == sizeof(long long), \
	    "must be long long sized");

/* Oid for an opaque object.  Specified by a pointer and a length. */
#define SYSCTL_OPAQUE(parent, nbr, name, access, ptr, len, fmt, descr) \
	SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|access, \
	        ptr, len, sysctl_handle_opaque, fmt, descr)

/* Oid for a struct.  Specified by a pointer and a type. */
#define SYSCTL_STRUCT(parent, nbr, name, access, ptr, type, descr) \
	SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|access, \
	    ptr, sizeof(struct type), sysctl_handle_opaque, \
	    "S," #type, descr)

/*
 * Oid for a procedure.  Specified by a pointer and an arg.
 * CTLTYPE_* macros can determine how the "sysctl" tool deals with
 * input (e.g. converting to int).
 */
#define SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr) \
	SYSCTL_OID(parent, nbr, name, access, \
	    ptr, arg, handler, fmt, descr)

/*
 * The EXPERIMENT macros below expose values for on-device experimentation (A/B testing) via Trial.
 * These values will be set shortly after boot by the KRExperiments framework based on any
 * active experiments on the device.
 * Values exposed via these macros are still normal sysctls and can be set by the superuser in the
 * development or debug kernel. However, on the release kernel they can ONLY be set by processes
 * with the com.apple.private.write-kr-experiment-factors entitlement.
 * In addition, for numeric types, special macros are provided that enforce a valid range for the value (inclusive)
 * to ensure that an errant experiment can't set a totally unexpected value. These macros also track which
 * values have been modified via sycstl(3) so that they can be inspected with the showexperiments lldb macro.
 */

struct experiment_spec {
	void *ptr; /* ptr to numeric experiment factor. */
	uint64_t min_value; /* Min value that can be set via sysctl(3) (inclusive). */
	uint64_t max_value; /* Max value that can be set via sysctl(3) (inclusive). */
	uint64_t original_value; /* First value that was overwritten via sysctl(3). */
	_Atomic bool modified; /* Has this value ever been overwritten via sysctl(3)? */
};

/*
 * The handlers for the numeric types can be easily parameterized by type.
 * So they're defined via an X macro.
 */
#define experiment_factor_numeric_types \
    X(uint, unsigned int) \
    X(int, int) \
    X(ulong, unsigned long) \
    X(long, long) \
    X(uint64, uint64_t) \
    X(int64, int64_t)

#define X(experiment_factor_typename, _) \
int experiment_factor_##experiment_factor_typename##_handler SYSCTL_HANDLER_ARGS;

experiment_factor_numeric_types
#undef X

#define __EXPERIMENT_FACTOR_SPEC(parent, name, p, min, max) \
	struct experiment_spec experiment_##parent##_##name = { \
	        .ptr = p, \
	        .min_value = min, \
	        .max_value = max, \
	        .original_value = 0, \
	        .modified = false \
	}

#define EXPERIMENT_FACTOR_UINT(parent, name, ptr, min, max, descr) \
	__EXPERIMENT_FACTOR_SPEC(parent, name, ptr, min, max); \
	_Static_assert(sizeof(*(ptr)) == sizeof(unsigned int), "must be integer sized"); \
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_uint_handler, "IU", descr);

#define EXPERIMENT_FACTOR_INT(parent, name, ptr, min, max, descr) \
	__EXPERIMENT_FACTOR_SPEC(parent, name, ptr, min, max); \
	_Static_assert(sizeof(*(ptr)) == sizeof(int), "must be integer sized"); \
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_int_handler, "I", descr);

#define EXPERIMENT_FACTOR_ULONG(parent, name, ptr, min, max, descr) \
	__EXPERIMENT_FACTOR_SPEC(parent, name, ptr, min, max); \
	_Static_assert(sizeof(*(ptr)) == sizeof(unsigned long), "must be long sized"); \
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_ulong_handler, "LU", descr);

#define EXPERIMENT_FACTOR_LONG(parent, name, ptr, min, max, descr) \
	__EXPERIMENT_FACTOR_SPEC(parent, name, ptr, min, max); \
	_Static_assert(sizeof(*(ptr)) == sizeof(long), "must be long sized"); \
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_long_handler, "L", descr);

#define EXPERIMENT_FACTOR_UINT64(parent, name, ptr, min, max, descr) \
	__EXPERIMENT_FACTOR_SPEC(parent, name, ptr, min, max); \
	_Static_assert(sizeof(*(ptr)) == sizeof(uint64_t), "must be 8 bytes"); \
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_uint64_handler, "QU", descr);

#define EXPERIMENT_FACTOR_INT64(parent, name, ptr, min, max, descr) \
	__EXPERIMENT_FACTOR_SPEC(parent, name, ptr, min, max); \
	_Static_assert(sizeof(*(ptr)) == sizeof(int64_t), "must be 8 bytes"); \
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_int64_handler, "Q", descr);

/*
 * Calls an user provided handler to read / write this factor.
 * Entitlement checking will still be done by sysctl, but it's the callers responsibility to validate any new values.
 * This factor will not be printed out via the showexperiments lldb macro.
 */
#define EXPERIMENT_FACTOR_PROC(parent, name, access, ptr, arg, handler, fmt, descr) \
	_Static_assert(arg != 1, "arg can not be 1"); \
	SYSCTL_PROC(parent, OID_AUTO, name, access | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, ptr, arg, handler, fmt, descr);

#ifdef XNU_KERNEL_PRIVATE
/*
 * Sysctl handler for reading a simple counter.
 * Using this directly is not recommended. Use the SYSCTL_SCALABLE_COUNTER macro
 */
int scalable_counter_sysctl_handler SYSCTL_HANDLER_ARGS;

/*!
 * @macro SYSCTL_SCALABLE_COUNTER
 *
 * @abstract
 * Provides a sysctl for reading the value of a percpu counter.
 */
#define SYSCTL_SCALABLE_COUNTER(parent, name, counter, descr) \
SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED, \
    (void *)(&counter), 0, &scalable_counter_sysctl_handler, "Q", descr);
#endif /* XNU_KERNEL_PRIVATE */

extern struct sysctl_oid_list sysctl__children;
SYSCTL_DECL(_kern);
SYSCTL_DECL(_sysctl);
SYSCTL_DECL(_vm);
SYSCTL_DECL(_vfs);
SYSCTL_DECL(_net);
SYSCTL_DECL(_debug);
SYSCTL_DECL(_hw);
SYSCTL_DECL(_machdep);
SYSCTL_DECL(_user);
#if DEVELOPMENT || DEBUG
SYSCTL_DECL(_debug_test);
#endif /* DEVELOPMENT || DEBUG */

#ifdef PRIVATE
SYSCTL_DECL(_kern_bridge);
SYSCTL_DECL(_hw_features);
#endif

#if defined(BSD_KERNEL_PRIVATE) && SKYWALK
#include <skywalk/os_sysctls_private.h>
#endif  /* defined(BSD_KERNEL_PRIVATE) && SKYWALK */

#ifndef SYSCTL_SKMEM_UPDATE_FIELD

#define SYSCTL_SKMEM 0
#define SYSCTL_SKMEM_UPDATE_FIELD(field, value)
#define SYSCTL_SKMEM_UPDATE_AT_OFFSET(offset, value)
#define SYSCTL_SKMEM_INT(parent, oid, sysctl_name, access, ptr, offset, descr) \
	SYSCTL_INT(parent, oid, sysctl_name, access, ptr, 0, descr)

#define SYSCTL_SKMEM_TCP_INT(oid, sysctl_name, access, variable_type,   \
	    variable_name, initial_value, descr)           \
	variable_type variable_name = initial_value;                                            \
	SYSCTL_SKMEM_INT(_net_inet_tcp, oid, sysctl_name, access,                       \
	                                 &variable_name, 0, descr)

#else /* SYSCTL_SKMEM_UPDATE_FIELD */
#define SYSCTL_SKMEM 1
#endif /* SYSCTL_SKMEM_UPDATE_FIELD */



#endif /* KERNEL */

#ifdef XNU_KERNEL_PRIVATE
#define SYSCTL_DEF_ENABLED
#else
#ifndef KERNEL
#define SYSCTL_DEF_ENABLED
#endif
#endif

#ifdef SYSCTL_DEF_ENABLED
/*
 * Top-level identifiers
 */
#define CTL_UNSPEC      0               /* unused */
#define CTL_KERN        1               /* "high kernel": proc, limits */
#define CTL_VM          2               /* virtual memory */
#define CTL_VFS         3               /* file system, mount type is next */
#define CTL_NET         4               /* network, see socket.h */
#define CTL_DEBUG       5               /* debugging parameters */
#define CTL_HW          6               /* generic cpu/io */
#define CTL_MACHDEP     7               /* machine dependent */
#define CTL_USER        8               /* user-level */
#define CTL_MAXID       9               /* number of valid top-level ids */

#define CTL_NAMES { \
	{ 0, 0 }, \
	{ "kern", CTLTYPE_NODE }, \
	{ "vm", CTLTYPE_NODE }, \
	{ "vfs", CTLTYPE_NODE }, \
	{ "net", CTLTYPE_NODE }, \
	{ "debug", CTLTYPE_NODE }, \
	{ "hw", CTLTYPE_NODE }, \
	{ "machdep", CTLTYPE_NODE }, \
	{ "user", CTLTYPE_NODE }, \
}

/*
 * CTL_KERN identifiers
 */
#define KERN_OSTYPE              1      /* string: system version */
#define KERN_OSRELEASE           2      /* string: system release */
#define KERN_OSREV               3      /* int: system revision */
#define KERN_VERSION             4      /* string: compile time info */
#define KERN_MAXVNODES           5      /* int: max vnodes */
#define KERN_MAXPROC             6      /* int: max processes */
#define KERN_MAXFILES            7      /* int: max open files */
#define KERN_ARGMAX              8      /* int: max arguments to exec */
#define KERN_SECURELVL           9      /* int: system security level */
#define KERN_HOSTNAME           10      /* string: hostname */
#define KERN_HOSTID             11      /* int: host identifier */
#define KERN_CLOCKRATE          12      /* struct: struct clockrate */
#define KERN_VNODE              13      /* struct: vnode structures */
#define KERN_PROC               14      /* struct: process entries */
#define KERN_FILE               15      /* struct: file entries */
#define KERN_PROF               16      /* node: kernel profiling info */
#define KERN_POSIX1             17      /* int: POSIX.1 version */
#define KERN_NGROUPS            18      /* int: # of supplemental group ids */
#define KERN_JOB_CONTROL        19      /* int: is job control available */
#define KERN_SAVED_IDS          20      /* int: saved set-user/group-ID */
#define KERN_BOOTTIME           21      /* struct: time kernel was booted */
#define KERN_NISDOMAINNAME      22      /* string: YP domain name */
#define KERN_DOMAINNAME         KERN_NISDOMAINNAME
#define KERN_MAXPARTITIONS      23      /* int: number of partitions/disk */
#define KERN_KDEBUG             24      /* int: kernel trace points */
#define KERN_UPDATEINTERVAL     25      /* int: update process sleep time */
#define KERN_OSRELDATE          26      /* int: OS release date */
#define KERN_NTP_PLL            27      /* node: NTP PLL control */
#define KERN_BOOTFILE           28      /* string: name of booted kernel */
#define KERN_MAXFILESPERPROC    29      /* int: max open files per proc */
#define KERN_MAXPROCPERUID      30      /* int: max processes per uid */
#define KERN_DUMPDEV            31      /* dev_t: device to dump on */
#define KERN_IPC                32      /* node: anything related to IPC */
#define KERN_DUMMY              33      /* unused */
#define KERN_PS_STRINGS 34      /* int: address of PS_STRINGS */
#define KERN_USRSTACK32 35      /* int: address of USRSTACK */
#define KERN_LOGSIGEXIT 36      /* int: do we log sigexit procs? */
#define KERN_SYMFILE            37      /* string: kernel symbol filename */
#define KERN_PROCARGS           38
/* 39 was KERN_PCSAMPLES... now obsolete */
#define KERN_NETBOOT            40      /* int: are we netbooted? 1=yes,0=no */
/* 41 was KERN_PANICINFO : panic UI information (deprecated) */
#define KERN_SYSV               42      /* node: System V IPC information */
#define KERN_AFFINITY           43      /* xxx */
#define KERN_TRANSLATE          44      /* xxx */
#define KERN_CLASSIC            KERN_TRANSLATE  /* XXX backwards compat */
#define KERN_EXEC               45      /* xxx */
#define KERN_CLASSICHANDLER     KERN_EXEC /* XXX backwards compatibility */
#define KERN_AIOMAX             46      /* int: max aio requests */
#define KERN_AIOPROCMAX         47      /* int: max aio requests per process */
#define KERN_AIOTHREADS         48      /* int: max aio worker threads */
#ifdef __APPLE_API_UNSTABLE
#define KERN_PROCARGS2          49
#endif /* __APPLE_API_UNSTABLE */
#define KERN_COREFILE           50      /* string: corefile format string */
#define KERN_COREDUMP           51      /* int: whether to coredump at all */
#define KERN_SUGID_COREDUMP     52      /* int: whether to dump SUGID cores */
#define KERN_PROCDELAYTERM      53      /* int: set/reset current proc for delayed termination during shutdown */
#define KERN_SHREG_PRIVATIZABLE 54      /* int: can shared regions be privatized ? */
/* 55 was KERN_PROC_LOW_PRI_IO... now deprecated */
#define KERN_LOW_PRI_WINDOW     56      /* int: set/reset throttle window - milliseconds */
#define KERN_LOW_PRI_DELAY      57      /* int: set/reset throttle delay - milliseconds */
#define KERN_POSIX              58      /* node: posix tunables */
#define KERN_USRSTACK64         59      /* LP64 user stack query */
#define KERN_NX_PROTECTION      60      /* int: whether no-execute protection is enabled */
#define KERN_TFP                61      /* Task for pid settings */
#define KERN_PROCNAME           62      /* setup process program  name(2*MAXCOMLEN) */
#define KERN_THALTSTACK         63      /* for compat with older x86 and does nothing */
#define KERN_SPECULATIVE_READS  64      /* int: whether speculative reads are disabled */
#define KERN_OSVERSION          65      /* for build number i.e. 9A127 */
#define KERN_SAFEBOOT           66      /* are we booted safe? */
/*	67 was KERN_LCTX (login context) */
#define KERN_RAGEVNODE          68
#define KERN_TTY                69      /* node: tty settings */
#define KERN_CHECKOPENEVT       70      /* spi: check the VOPENEVT flag on vnodes at open time */
#define KERN_THREADNAME         71      /* set/get thread name */
#define KERN_MAXID              72      /* number of valid kern ids */
/*
 * Don't add any more sysctls like this.  Instead, use the SYSCTL_*() macros
 * and OID_AUTO. This will have the added benefit of not having to recompile
 * sysctl(8) to pick up your changes.
 */

#if COUNT_SYSCALLS && defined(KERNEL)
#define KERN_COUNT_SYSCALLS (KERN_OSTYPE + 1000)        /* keep called count for each bsd syscall */
#endif

#if defined(__LP64__)
#define KERN_USRSTACK KERN_USRSTACK64
#else
#define KERN_USRSTACK KERN_USRSTACK32
#endif


/* KERN_RAGEVNODE types */
#define KERN_RAGE_PROC          1
#define KERN_RAGE_THREAD        2
#define KERN_UNRAGE_PROC        3
#define KERN_UNRAGE_THREAD      4

/* KERN_OPENEVT types */
#define KERN_OPENEVT_PROC     1
#define KERN_UNOPENEVT_PROC   2

/* KERN_TFP types */
#define KERN_TFP_POLICY                 1

/* KERN_TFP_POLICY values . All policies allow task port for self */
#define KERN_TFP_POLICY_DENY            0       /* Deny Mode: None allowed except privileged */
#define KERN_TFP_POLICY_DEFAULT         2       /* Default  Mode: related ones allowed and upcall authentication */

/* KERN_KDEBUG types */
#define KERN_KDEFLAGS         1
#define KERN_KDDFLAGS         2
#define KERN_KDENABLE         3
#define KERN_KDSETBUF         4
#define KERN_KDGETBUF         5
#define KERN_KDSETUP          6
#define KERN_KDREMOVE         7
#define KERN_KDSETREG         8
#define KERN_KDGETREG         9
#define KERN_KDREADTR         10
#define KERN_KDPIDTR          11
#define KERN_KDTHRMAP         12
/* Don't use 13 as it is overloaded with KERN_VNODE */
#define KERN_KDPIDEX          14
#define KERN_KDSETRTCDEC      15 /* obsolete */
#define KERN_KDGETENTROPY     16 /* obsolete */
#define KERN_KDWRITETR        17
#define KERN_KDWRITEMAP       18
#define KERN_KDTEST           19
/* 20 unused */
#define KERN_KDREADCURTHRMAP  21
#define KERN_KDSET_TYPEFILTER 22
#define KERN_KDBUFWAIT        23
#define KERN_KDCPUMAP         24
#define KERN_KDCPUMAP_EXT     25
#define KERN_KDSET_EDM        26
#define KERN_KDGET_EDM        27
#define KERN_KDWRITETR_V3     28

#define CTL_KERN_NAMES { \
	{ 0, 0 }, \
	{ "ostype", CTLTYPE_STRING }, \
	{ "osrelease", CTLTYPE_STRING }, \
	{ "osrevision", CTLTYPE_INT }, \
	{ "version", CTLTYPE_STRING }, \
	{ "maxvnodes", CTLTYPE_INT }, \
	{ "maxproc", CTLTYPE_INT }, \
	{ "maxfiles", CTLTYPE_INT }, \
	{ "argmax", CTLTYPE_INT }, \
	{ "securelevel", CTLTYPE_INT }, \
	{ "hostname", CTLTYPE_STRING }, \
	{ "hostid", CTLTYPE_INT }, \
	{ "clockrate", CTLTYPE_STRUCT }, \
	{ "vnode", CTLTYPE_STRUCT }, \
	{ "proc", CTLTYPE_STRUCT }, \
	{ "file", CTLTYPE_STRUCT }, \
	{ "profiling", CTLTYPE_NODE }, \
	{ "posix1version", CTLTYPE_INT }, \
	{ "ngroups", CTLTYPE_INT }, \
	{ "job_control", CTLTYPE_INT }, \
	{ "saved_ids", CTLTYPE_INT }, \
	{ "boottime", CTLTYPE_STRUCT }, \
	{ "nisdomainname", CTLTYPE_STRING }, \
	{ "maxpartitions", CTLTYPE_INT }, \
	{ "kdebug", CTLTYPE_INT }, \
	{ "update", CTLTYPE_INT }, \
	{ "osreldate", CTLTYPE_INT }, \
	{ "ntp_pll", CTLTYPE_NODE }, \
	{ "bootfile", CTLTYPE_STRING }, \
	{ "maxfilesperproc", CTLTYPE_INT }, \
	{ "maxprocperuid", CTLTYPE_INT }, \
	{ "dumpdev", CTLTYPE_STRUCT }, /* we lie; don't print as int */ \
	{ "ipc", CTLTYPE_NODE }, \
	{ "dummy", CTLTYPE_INT }, \
	{ "dummy", CTLTYPE_INT }, \
	{ "usrstack", CTLTYPE_INT }, \
	{ "logsigexit", CTLTYPE_INT }, \
	{ "symfile",CTLTYPE_STRING },\
	{ "procargs",CTLTYPE_STRUCT },\
	{ "dummy", CTLTYPE_INT },               /* deprecated pcsamples */ \
	{ "netboot", CTLTYPE_INT }, \
	{ "dummy", CTLTYPE_INT },               /* deprecated: panicinfo */ \
	{ "sysv", CTLTYPE_NODE }, \
	{ "dummy", CTLTYPE_INT }, \
	{ "dummy", CTLTYPE_INT }, \
	{ "exec", CTLTYPE_NODE }, \
	{ "aiomax", CTLTYPE_INT }, \
	{ "aioprocmax", CTLTYPE_INT }, \
	{ "aiothreads", CTLTYPE_INT }, \
	{ "procargs2",CTLTYPE_STRUCT }, \
	{ "corefile",CTLTYPE_STRING }, \
	{ "coredump", CTLTYPE_INT }, \
	{ "sugid_coredump", CTLTYPE_INT }, \
	{ "delayterm", CTLTYPE_INT }, \
	{ "shreg_private", CTLTYPE_INT }, \
	{ "proc_low_pri_io", CTLTYPE_INT }, \
	{ "low_pri_window", CTLTYPE_INT }, \
	{ "low_pri_delay", CTLTYPE_INT }, \
	{ "posix", CTLTYPE_NODE }, \
	{ "usrstack64", CTLTYPE_QUAD }, \
	{ "nx", CTLTYPE_INT }, \
	{ "tfp", CTLTYPE_NODE }, \
	{ "procname", CTLTYPE_STRING }, \
	{ "threadsigaltstack", CTLTYPE_INT }, \
	{ "speculative_reads_disabled", CTLTYPE_INT }, \
	{ "osversion", CTLTYPE_STRING }, \
	{ "safeboot", CTLTYPE_INT }, \
	{ "dummy", CTLTYPE_INT },               /* deprecated: lctx */ \
	{ "rage_vnode", CTLTYPE_INT }, \
	{ "tty", CTLTYPE_NODE },        \
	{ "check_openevt", CTLTYPE_INT }, \
	{ "thread_name", CTLTYPE_STRING } \
}

/*
 * CTL_VFS identifiers
 */
#define CTL_VFS_NAMES { \
	{ "vfsconf", CTLTYPE_STRUCT } \
}

/*
 * KERN_PROC subtypes
 */
#define KERN_PROC_ALL           0       /* everything */
#define KERN_PROC_PID           1       /* by process id */
#define KERN_PROC_PGRP          2       /* by process group id */
#define KERN_PROC_SESSION       3       /* by session of pid */
#define KERN_PROC_TTY           4       /* by controlling tty */
#define KERN_PROC_UID           5       /* by effective uid */
#define KERN_PROC_RUID          6       /* by real uid */
#define KERN_PROC_LCID          7       /* by login context id */

/*
 * KERN_VFSNSPACE subtypes
 */
#define KERN_VFSNSPACE_HANDLE_PROC              1
#define KERN_VFSNSPACE_UNHANDLE_PROC    2

#if defined(XNU_KERNEL_PRIVATE) || !defined(KERNEL)
/*
 * KERN_PROC subtype ops return arrays of augmented proc structures:
 */

struct _pcred {
	char    pc_lock[72];            /* opaque content */
	struct  ucred *pc_ucred;        /* Current credentials. */
	uid_t   p_ruid;                 /* Real user id. */
	uid_t   p_svuid;                /* Saved effective user id. */
	gid_t   p_rgid;                 /* Real group id. */
	gid_t   p_svgid;                /* Saved effective group id. */
	int     p_refcnt;               /* Number of references. */
};

struct _ucred {
	int32_t cr_ref;                 /* reference count */
	uid_t   cr_uid;                 /* effective user id */
	short   cr_ngroups;             /* number of groups */
	gid_t   cr_groups[NGROUPS];     /* groups */
};

struct kinfo_proc {
	struct  extern_proc kp_proc;                    /* proc structure */
	struct  eproc {
		struct  proc *e_paddr;          /* address of proc */
		struct  session *e_sess;        /* session pointer */
		struct  _pcred e_pcred;         /* process credentials */
		struct  _ucred e_ucred;         /* current credentials */
		struct   vmspace e_vm;          /* address space */
		pid_t   e_ppid;                 /* parent process id */
		pid_t   e_pgid;                 /* process group id */
		short   e_jobc;                 /* job control counter */
		dev_t   e_tdev;                 /* controlling tty dev */
		pid_t   e_tpgid;                /* tty process group id */
		struct  session *e_tsess;       /* tty session pointer */
#define WMESGLEN        7
		char    e_wmesg[WMESGLEN + 1];    /* wchan message */
		segsz_t e_xsize;                /* text size */
		short   e_xrssize;              /* text rss */
		short   e_xccount;              /* text references */
		short   e_xswrss;
		int32_t e_flag;
#define EPROC_CTTY      0x01    /* controlling tty vnode active */
#define EPROC_SLEADER   0x02    /* session leader */
#define COMAPT_MAXLOGNAME       12
		char    e_login[COMAPT_MAXLOGNAME];     /* short setlogin() name */
		int32_t e_spare[4];
	} kp_eproc;
};

#endif /* defined(XNU_KERNEL_PRIVATE) || !defined(KERNEL) */

#ifdef BSD_KERNEL_PRIVATE
#include <sys/proc_internal.h>

/* LP64 version of _pcred.  all pointers
 * grow when we're dealing with a 64-bit process.
 * WARNING - keep in sync with _pcred
 */

struct user32_pcred {
	char          pc_lock[72];    /* opaque content */
	user32_addr_t pc_ucred;       /* Current credentials. */
	uid_t         p_ruid;         /* Real user id. */
	uid_t         p_svuid;        /* Saved effective user id. */
	gid_t         p_rgid;         /* Real group id. */
	gid_t         p_svgid;        /* Saved effective group id. */
	int           p_refcnt;       /* Number of references. */
};
struct user64_pcred {
	char          pc_lock[72];      /* opaque content */
	user64_addr_t pc_ucred;         /* Current credentials. */
	uid_t         p_ruid;           /* Real user id. */
	uid_t         p_svuid;          /* Saved effective user id. */
	gid_t         p_rgid;           /* Real group id. */
	gid_t         p_svgid;          /* Saved effective group id. */
	int           p_refcnt;         /* Number of references. */
};

/* LP64 version of kinfo_proc.  all pointers
 * grow when we're dealing with a 64-bit process.
 * WARNING - keep in sync with kinfo_proc
 */
struct user32_kinfo_proc {
	struct  user32_extern_proc kp_proc;     /* proc structure */
	struct  user32_eproc {
		user32_addr_t e_paddr;          /* address of proc */
		user32_addr_t e_sess;                   /* session pointer */
		struct  user32_pcred e_pcred;           /* process credentials */
		struct  _ucred e_ucred;         /* current credentials */
		struct  user32_vmspace e_vm; /* address space */
		pid_t   e_ppid;                 /* parent process id */
		pid_t   e_pgid;                 /* process group id */
		int     e_jobc;                 /* job control counter */
		dev_t   e_tdev;                 /* controlling tty dev */
		pid_t   e_tpgid;                /* tty process group id */
		user32_addr_t   e_tsess;        /* tty session pointer */
		char    e_wmesg[WMESGLEN + 1];    /* wchan message */
		segsz_t e_xsize;                /* text size */
		short   e_xrssize;              /* text rss */
		short   e_xccount;              /* text references */
		short   e_xswrss;
		int32_t e_flag;
		char    e_login[COMAPT_MAXLOGNAME];     /* short setlogin() name */
		int32_t e_spare[4];
	} kp_eproc;
};
struct user64_kinfo_proc {
	struct  user64_extern_proc kp_proc;     /* proc structure */
	struct  user64_eproc {
		user_addr_t e_paddr;            /* address of proc */
		user_addr_t e_sess;                     /* session pointer */
		struct  user64_pcred e_pcred;           /* process credentials */
		struct  _ucred e_ucred;         /* current credentials */
		struct   user_vmspace e_vm; /* address space */
		pid_t   e_ppid;                 /* parent process id */
		pid_t   e_pgid;                 /* process group id */
		int     e_jobc;                 /* job control counter */
		dev_t   e_tdev;                 /* controlling tty dev */
		pid_t   e_tpgid;                /* tty process group id */
		user64_addr_t   e_tsess __attribute((aligned(8)));      /* tty session pointer */
		char    e_wmesg[WMESGLEN + 1];    /* wchan message */
		segsz_t e_xsize;                /* text size */
		short   e_xrssize;              /* text rss */
		short   e_xccount;              /* text references */
		short   e_xswrss;
		int32_t e_flag;
		char    e_login[COMAPT_MAXLOGNAME];     /* short setlogin() name */
		int32_t e_spare[4];
	} kp_eproc;
};

#endif  /* BSD_KERNEL_PRIVATE */

/*
 * KERN_IPC identifiers
 */
#define KIPC_MAXSOCKBUF         1       /* int: max size of a socket buffer */
#define KIPC_SOCKBUF_WASTE      2       /* int: wastage factor in sockbuf */
#define KIPC_SOMAXCONN          3       /* int: max length of connection q */
#define KIPC_MAX_LINKHDR        4       /* int: max length of link header */
#define KIPC_MAX_PROTOHDR       5       /* int: max length of network header */
#define KIPC_MAX_HDR            6       /* int: max total length of headers */
#define KIPC_MAX_DATALEN        7       /* int: max length of data? */
#define KIPC_MBSTAT             8       /* struct: mbuf usage statistics */
#define KIPC_NMBCLUSTERS        9       /* int: maximum mbuf clusters */
#define KIPC_SOQLIMITCOMPAT     10      /* int: socket queue limit */

/*
 * CTL_VM identifiers
 */
#define VM_METER        1               /* struct vmmeter */
#define VM_LOADAVG      2               /* struct loadavg */
/*
 * Note: "3" was skipped sometime ago and should probably remain unused
 * to avoid any new entry from being accepted by older kernels...
 */
#define VM_MACHFACTOR   4               /* struct loadavg with mach factor*/
#define VM_SWAPUSAGE    5               /* total swap usage */
#define VM_MAXID        6               /* number of valid vm ids */

#define CTL_VM_NAMES { \
	{ 0, 0 }, \
	{ "vmmeter", CTLTYPE_STRUCT }, \
	{ "loadavg", CTLTYPE_STRUCT }, \
	{ 0, 0 }, /* placeholder for "3" (see comment above) */ \
	{ "dummy", CTLTYPE_INT }, \
	{ "swapusage", CTLTYPE_STRUCT } \
}

struct xsw_usage {
	u_int64_t       xsu_total;
	u_int64_t       xsu_avail;
	u_int64_t       xsu_used;
	u_int32_t       xsu_pagesize;
	boolean_t       xsu_encrypted;
};

#ifdef __APPLE_API_PRIVATE
/* Load average structure.  Use of fixpt_t assume <sys/types.h> in scope. */
/* XXX perhaps we should protect fixpt_t, and define it here (or discard it) */
struct loadavg {
	fixpt_t ldavg[3];
	long    fscale;
};
extern struct loadavg averunnable;
#define LSCALE  1000            /* scaling for "fixed point" arithmetic */

#ifdef BSD_KERNEL_PRIVATE

struct user32_loadavg {
	fixpt_t ldavg[3];
	user32_long_t       fscale;
};

struct user64_loadavg {
	fixpt_t ldavg[3];
	user64_long_t       fscale;
};

#endif  /* BSD_KERNEL_PRIVATE */
#endif /* __APPLE_API_PRIVATE */


/*
 * CTL_HW identifiers
 */
#define HW_MACHINE       1              /* string: machine class (deprecated: use HW_PRODUCT) */
#define HW_MODEL         2              /* string: specific machine model (deprecated: use HW_TARGET) */
#define HW_NCPU          3              /* int: number of cpus */
#define HW_BYTEORDER     4              /* int: machine byte order */
#define HW_PHYSMEM       5              /* int: total memory */
#define HW_USERMEM       6              /* int: non-kernel memory */
#define HW_PAGESIZE      7              /* int: software page size */
#define HW_DISKNAMES     8              /* strings: disk drive names */
#define HW_DISKSTATS     9              /* struct: diskstats[] */
#define HW_EPOCH        10              /* int: 0 for Legacy, else NewWorld */
#define HW_FLOATINGPT   11              /* int: has HW floating point? */
#define HW_MACHINE_ARCH 12              /* string: machine architecture */
#define HW_VECTORUNIT   13              /* int: has HW vector unit? */
#define HW_BUS_FREQ     14              /* int: Bus Frequency */
#define HW_CPU_FREQ     15              /* int: CPU Frequency */
#define HW_CACHELINE    16              /* int: Cache Line Size in Bytes */
#define HW_L1ICACHESIZE 17              /* int: L1 I Cache Size in Bytes */
#define HW_L1DCACHESIZE 18              /* int: L1 D Cache Size in Bytes */
#define HW_L2SETTINGS   19              /* int: L2 Cache Settings */
#define HW_L2CACHESIZE  20              /* int: L2 Cache Size in Bytes */
#define HW_L3SETTINGS   21              /* int: L3 Cache Settings */
#define HW_L3CACHESIZE  22              /* int: L3 Cache Size in Bytes */
#define HW_TB_FREQ      23              /* int: Bus Frequency */
#define HW_MEMSIZE      24              /* uint64_t: physical ram size */
#define HW_AVAILCPU     25              /* int: number of available CPUs */
#define HW_TARGET       26              /* string: model identifier */
#define HW_PRODUCT      27              /* string: product identifier */
#define HW_MAXID        28              /* number of valid hw ids */

#define CTL_HW_NAMES { \
	{ 0, 0 }, \
	{ "machine", CTLTYPE_STRING },          /* Deprecated: use hw.product */ \
	{ "model", CTLTYPE_STRING },            /* Deprecated: use hw.target */ \
	{ "ncpu", CTLTYPE_INT }, \
	{ "byteorder", CTLTYPE_INT }, \
	{ "physmem", CTLTYPE_INT }, \
	{ "usermem", CTLTYPE_INT }, \
	{ "pagesize", CTLTYPE_INT }, \
	{ "disknames", CTLTYPE_STRUCT }, \
	{ "diskstats", CTLTYPE_STRUCT }, \
	{ "epoch", CTLTYPE_INT }, \
	{ "floatingpoint", CTLTYPE_INT }, \
	{ "machinearch", CTLTYPE_STRING }, \
	{ "vectorunit", CTLTYPE_INT }, \
	{ "busfrequency", CTLTYPE_INT }, \
	{ "cpufrequency", CTLTYPE_INT }, \
	{ "cachelinesize", CTLTYPE_INT }, \
	{ "l1icachesize", CTLTYPE_INT }, \
	{ "l1dcachesize", CTLTYPE_INT }, \
	{ "l2settings", CTLTYPE_INT }, \
	{ "l2cachesize", CTLTYPE_INT }, \
	{ "l3settings", CTLTYPE_INT }, \
	{ "l3cachesize", CTLTYPE_INT }, \
	{ "tbfrequency", CTLTYPE_INT }, \
	{ "memsize", CTLTYPE_QUAD }, \
	{ "availcpu", CTLTYPE_INT }, \
	{ "target", CTLTYPE_STRING }, \
	{ "product", CTLTYPE_STRING }, \
}

/*
 * XXX This information should be moved to the man page.
 *
 * These are the support HW selectors for sysctlbyname.  Parameters that are byte counts or frequencies are 64 bit numbers.
 * All other parameters are 32 bit numbers.
 *
 *   hw.memsize                - The number of bytes of physical memory in the system.
 *
 *   hw.ncpu                   - The maximum number of processors that could be available this boot.
 *                               Use this value for sizing of static per processor arrays; i.e. processor load statistics.
 *
 *   hw.activecpu              - The number of processors currently available for executing threads.
 *                               Use this number to determine the number threads to create in SMP aware applications.
 *                               This number can change when power management modes are changed.
 *
 *   hw.physicalcpu            - The number of physical processors available in the current power management mode.
 *   hw.physicalcpu_max        - The maximum number of physical processors that could be available this boot
 *
 *   hw.logicalcpu             - The number of logical processors available in the current power management mode.
 *   hw.logicalcpu_max         - The maximum number of logical processors that could be available this boot
 *
 *   hw.tbfrequency            - This gives the time base frequency used by the OS and is the basis of all timing services.
 *                               In general is is better to use mach's or higher level timing services, but this value
 *                               is needed to convert the PPC Time Base registers to real time.
 *
 *   hw.cpufrequency           - These values provide the current, min and max cpu frequency.  The min and max are for
 *   hw.cpufrequency_max       - all power management modes.  The current frequency is the max frequency in the current mode.
 *   hw.cpufrequency_min       - All frequencies are in Hz.
 *
 *   hw.busfrequency           - These values provide the current, min and max bus frequency.  The min and max are for
 *   hw.busfrequency_max       - all power management modes.  The current frequency is the max frequency in the current mode.
 *   hw.busfrequency_min       - All frequencies are in Hz.
 *
 *   hw.cputype                - These values provide the mach-o cpu type and subtype.  A complete list is in <mach/machine.h>
 *   hw.cpusubtype             - These values should be used to determine what processor family the running cpu is from so that
 *                               the best binary can be chosen, or the best dynamic code generated.  They should not be used
 *                               to determine if a given processor feature is available.
 *   hw.cputhreadtype          - This value will be present if the processor supports threads.  Like hw.cpusubtype this selector
 *                               should not be used to infer features, and only used to name the processors thread architecture.
 *                               The values are defined in <mach/machine.h>
 *
 *   hw.byteorder              - Gives the byte order of the processor.  4321 for big endian, 1234 for little.
 *
 *   hw.pagesize               - Gives the size in bytes of the pages used by the processor and VM system.
 *
 *   hw.cachelinesize          - Gives the size in bytes of the processor's cache lines.
 *                               This value should be use to control the strides of loops that use cache control instructions
 *                               like dcbz, dcbt or dcbst.
 *
 *   hw.l1dcachesize           - These values provide the size in bytes of the L1, L2 and L3 caches.  If a cache is not present
 *   hw.l1icachesize           - then the selector will return and error.
 *   hw.l2cachesize            -
 *   hw.l3cachesize            -
 *
 *   hw.nperflevels            - Number of core types in the system. See the parameters below, which can be used to get
 *                             - information associated with a specific perf level.
 *
 *   The following parameters apply to perflevel N, where N is a number between 0 and the number of core types in the system minus one.
 *   perflevel 0 always refers to the highest performance core type in the system.
 *
 *   hw.perflevelN.physicalcpu      - The number of physical processors available in the current power management mode.
 *   hw.perflevelN.physicalcpumax   - The maximum number of physical processors that could be available this boot.
 *   hw.perflevelN.logicalcpu       - The number of logical processors available in the current power management mode.
 *   hw.perflevelN.logicalcpumax    - The maximum number of logical processors that could be available this boot.
 *
 *   hw.perflevelN.l1dcachesize     - These values provide the size in bytes of the L1, L2 and L3 caches.  If a cache is not present
 *   hw.perflevelN.l1icachesize     - then the selector will return and error.
 *   hw.perflevelN.l2cachesize      -
 *   hw.perflevelN.l3cachesize      -
 *
 *   hw.perflevelN.cpusperl2        - These values provide the number of CPUs of the same type that share L2 and L3 caches.
 *   hw.perflevelN.cpusperl3        - If a cache is not present then the selector will return and error.
 *
 *   hw.perflevelN.l2perflevels     - These values provide a bitmap, where bit  number of CPUs of the same type that share L2 and L3 caches.
 *   hw.perflevelN.l3perflevels     - If a cache is not present then the selector will return and error.
 *
 *   hw.packages               - Gives the number of processor packages.
 *
 * These are the selectors for optional processor features for specific processors.  Selectors that return errors are not support
 * on the system.  Supported features will return 1 if they are recommended or 0 if they are supported but are not expected to help .
 * performance.  Future versions of these selectors may return larger values as necessary so it is best to test for non zero.
 *
 * For PowerPC:
 *
 *   hw.optional.floatingpoint - Floating Point Instructions
 *   hw.optional.altivec       - AltiVec Instructions
 *   hw.optional.graphicsops   - Graphics Operations
 *   hw.optional.64bitops      - 64-bit Instructions
 *   hw.optional.fsqrt         - HW Floating Point Square Root Instruction
 *   hw.optional.stfiwx        - Store Floating Point as Integer Word Indexed Instructions
 *   hw.optional.dcba          - Data Cache Block Allocate Instruction
 *   hw.optional.datastreams   - Data Streams Instructions
 *   hw.optional.dcbtstreams   - Data Cache Block Touch Steams Instruction Form
 *
 * For x86 Architecture:
 *
 *   hw.optional.floatingpoint     - Floating Point Instructions
 *   hw.optional.mmx               - Original MMX vector instructions
 *   hw.optional.sse               - Streaming SIMD Extensions
 *   hw.optional.sse2              - Streaming SIMD Extensions 2
 *   hw.optional.sse3              - Streaming SIMD Extensions 3
 *   hw.optional.supplementalsse3  - Supplemental Streaming SIMD Extensions 3
 *   hw.optional.x86_64            - 64-bit support
 */


/*
 * CTL_USER definitions
 */
#define USER_CS_PATH             1      /* string: _CS_PATH */
#define USER_BC_BASE_MAX         2      /* int: BC_BASE_MAX */
#define USER_BC_DIM_MAX          3      /* int: BC_DIM_MAX */
#define USER_BC_SCALE_MAX        4      /* int: BC_SCALE_MAX */
#define USER_BC_STRING_MAX       5      /* int: BC_STRING_MAX */
#define USER_COLL_WEIGHTS_MAX    6      /* int: COLL_WEIGHTS_MAX */
#define USER_EXPR_NEST_MAX       7      /* int: EXPR_NEST_MAX */
#define USER_LINE_MAX            8      /* int: LINE_MAX */
#define USER_RE_DUP_MAX          9      /* int: RE_DUP_MAX */
#define USER_POSIX2_VERSION     10      /* int: POSIX2_VERSION */
#define USER_POSIX2_C_BIND      11      /* int: POSIX2_C_BIND */
#define USER_POSIX2_C_DEV       12      /* int: POSIX2_C_DEV */
#define USER_POSIX2_CHAR_TERM   13      /* int: POSIX2_CHAR_TERM */
#define USER_POSIX2_FORT_DEV    14      /* int: POSIX2_FORT_DEV */
#define USER_POSIX2_FORT_RUN    15      /* int: POSIX2_FORT_RUN */
#define USER_POSIX2_LOCALEDEF   16      /* int: POSIX2_LOCALEDEF */
#define USER_POSIX2_SW_DEV      17      /* int: POSIX2_SW_DEV */
#define USER_POSIX2_UPE         18      /* int: POSIX2_UPE */
#define USER_STREAM_MAX         19      /* int: POSIX2_STREAM_MAX */
#define USER_TZNAME_MAX         20      /* int: POSIX2_TZNAME_MAX */
#define USER_MAXID              21      /* number of valid user ids */

#define CTL_USER_NAMES { \
	{ 0, 0 }, \
	{ "cs_path", CTLTYPE_STRING }, \
	{ "bc_base_max", CTLTYPE_INT }, \
	{ "bc_dim_max", CTLTYPE_INT }, \
	{ "bc_scale_max", CTLTYPE_INT }, \
	{ "bc_string_max", CTLTYPE_INT }, \
	{ "coll_weights_max", CTLTYPE_INT }, \
	{ "expr_nest_max", CTLTYPE_INT }, \
	{ "line_max", CTLTYPE_INT }, \
	{ "re_dup_max", CTLTYPE_INT }, \
	{ "posix2_version", CTLTYPE_INT }, \
	{ "posix2_c_bind", CTLTYPE_INT }, \
	{ "posix2_c_dev", CTLTYPE_INT }, \
	{ "posix2_char_term", CTLTYPE_INT }, \
	{ "posix2_fort_dev", CTLTYPE_INT }, \
	{ "posix2_fort_run", CTLTYPE_INT }, \
	{ "posix2_localedef", CTLTYPE_INT }, \
	{ "posix2_sw_dev", CTLTYPE_INT }, \
	{ "posix2_upe", CTLTYPE_INT }, \
	{ "stream_max", CTLTYPE_INT }, \
	{ "tzname_max", CTLTYPE_INT } \
}



/*
 * CTL_DEBUG definitions
 *
 * Second level identifier specifies which debug variable.
 * Third level identifier specifies which stucture component.
 */
#define CTL_DEBUG_NAME          0       /* string: variable name */
#define CTL_DEBUG_VALUE         1       /* int: variable value */
#define CTL_DEBUG_MAXID         20


#if (CTL_MAXID != 9) || (KERN_MAXID != 72) || (VM_MAXID != 6) || (HW_MAXID != 28) || (USER_MAXID != 21) || (CTL_DEBUG_MAXID != 20)
#error Use the SYSCTL_*() macros and OID_AUTO instead!
#endif


#ifdef  KERNEL

#ifdef BSD_KERNEL_PRIVATE
extern char     machine[];
extern char     osrelease[];
extern char     ostype[];
extern char     osversion[];
extern char     osproductversion[];
extern char     osbuild_config[];
#if defined(XNU_TARGET_OS_BRIDGE)
/*
 * 15 characters at maximum so both the productversion
 * and the build version can fit in the panic header
 * osversion field with the formatting requirements.
 */
#define MACOS_VERS_LEN 15

extern char     macosproductversion[];
extern char     macosversion[];
#endif

void    sysctl_mib_init(void);

#endif /* BSD_KERNEL_PRIVATE */
#else   /* !KERNEL */

__BEGIN_DECLS
int     sysctl(int *, u_int, void *, size_t *, void *, size_t);
int     sysctlbyname(const char *, void *, size_t *, void *, size_t);
int     sysctlnametomib(const char *, int *, size_t *);
__END_DECLS

#endif  /* KERNEL */


#endif /* SYSCTL_DEF_ENABLED */


#endif  /* !_SYS_SYSCTL_H_ */