Mercurial > flash_v2
changeset 1145:a571341dd6e5
Fixed all (I hope) compiler warnings
Added back sysctl support which was removed when the stack was ported.
line wrap: on
line diff
--- a/packages/net/bsd_tcpip/current/ChangeLog +++ b/packages/net/bsd_tcpip/current/ChangeLog @@ -1,3 +1,60 @@ +2003-07-25 Andrew Lunn <andrew.lunn@ascom.ch> + + * include/netinet/icmp_var.h + * include/netinet/igmp_var.h + * include/netinet/in_var.h + * include/netinet/udp_var.h + * include/netinet6/tcp6_var.h + * include/netinet6/udp6_var.h + * include/sys/socket.h + * src/sys/net/if.c + * src/sys/net/if_ethersubr.c + * src/sys/net/rtsock.c + * sys/netinet/if_ether.c + * sys/netinet/igmp.c + * src/sys/netinet/in.c + * src/sys/netinet/in_pcb.c + * src/sys/netinet/in_proto.c + * src/sys/netinet/in_rmx.c + * src/sys/netinet/ip_flow.c + * src/sys/netinet/ip_icmp.c + * src/sys/netinet/ip_input.c + * src/sys/netinet/ip_output.c + * src/sys/netinet/raw_ip.c + * src/sys/netinet/tcp_input.c + * src/sys/netinet/tcp_output.c + * src/sys/netinet/tcp_output.c + * src/sys/netinet/tcp_subr.c + * src/sys/netinet/tcp_timer.c + * src/sys/netinet/tcp_usrreq.c + * src/sys/netinet/udp_usrreq.c + * src/sys/netinet6/in6_proto.c + * src/sys/netinet6/in6_rmx.c + * src/sys/netinet6/nd6.c + * src/sys/netinet6/udp6_output.c + * sys/netinet6/udp6_usrreq.c: Added back the support for sysctl + which was removed in the port of the stack into eCos. + * include/sys/malloc.h (M_SYSCTL): SYSCTL types for malloc + * sys/kern/kern_sysctl.c (NEW): sysctl system call and support + functions + * include/sys/sysctrl.h (NEW): header file for sysctl. + * cdl/freebsd_net.cdl: CDL to enable/disable sysctl and a test case. + * tests/sysctl1.c (NEW): Test program for sysctl. + +2003-07-25 Andrew Lunn <andrew.lunn@ascom.ch> + + * include/sys/param.h: Fixed some compiler warnings. + * src/sys/netinet6/in6_ifattach.c: More fixes. + * src/sys/netinet6/in6.c: And some more. + * src/sys/netinet6/in6_pcb.c: YACW. + * include/netinet6/ip6protosw.h: Maybe the last one? + * include/netinet6/ip6protosw.h: Nope + * include/sys/param.h: + * sys/kern/uipc_socket.c: More warnings + * src/sys/netinet6/in6_pcb.c: rename errno to _errno to avoid conflict. + * src/sys/netinet6/in6_ifattach.c: Prototype for _show_ifp(). + * src/sys/netinet6/in6.c: Prototype for _show_ifp(). + 2003-07-28 Jay Foster <jay@systech.com> * src/sys/kern/sockio.c:
--- a/packages/net/bsd_tcpip/current/cdl/freebsd_net.cdl +++ b/packages/net/bsd_tcpip/current/cdl/freebsd_net.cdl @@ -151,8 +151,18 @@ cdl_package CYGPKG_NET_FREEBSD_STACK { ## Only if firewall enabled ## sys/netinet6/ip6_fw.c \ ## - } + cdl_option CYGPKG_NET_FREEBSD_SYSCTL { + display "sysctl support" + flavor bool + default_value 0 + description " + This option enables support for the system call sysctl used + to configure options/variables in the stack and retrieve statistics. " + # This file was derived from FreeBSD and carries that copyright + compile \ + sys/kern/kern_sysctl.c + } } cdl_option CYGPKG_NET_NGIF { @@ -321,4 +331,13 @@ cdl_package CYGPKG_NET_FREEBSD_STACK { the set of global flags if present." } } + cdl_option CYGPKG_NET_FREEBSD_STACK_TESTS { + display "FreeBSD network stack tests" + flavor data + no_define + calculated { CYGPKG_NET_FREEBSD_SYSCTL ? "tests/sysctl1" : "" } + description " + These are test specifically for the FreeBSD stack. These test features + which only the FreeBSD stack has" + } }
--- a/packages/net/bsd_tcpip/current/include/netinet/icmp_var.h +++ b/packages/net/bsd_tcpip/current/include/netinet/icmp_var.h @@ -79,7 +79,23 @@ struct icmpstat { u_long icps_bmcasttstamp; /* b/mcast tstamp requests dropped */ }; +/* + * Names for ICMP sysctl objects + */ +#define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */ +#define ICMPCTL_STATS 2 /* statistics (read-only) */ +#define ICMPCTL_ICMPLIM 3 +#define ICMPCTL_MAXID 4 + +#define ICMPCTL_NAMES { \ + { 0, 0 }, \ + { "maskrepl", CTLTYPE_INT }, \ + { "stats", CTLTYPE_STRUCT }, \ + { "icmplim", CTLTYPE_INT }, \ +} + #ifdef _KERNEL +SYSCTL_DECL(_net_inet_icmp); #ifdef ICMP_BANDLIM extern int badport_bandlim __P((int)); #endif
--- a/packages/net/bsd_tcpip/current/include/netinet/igmp_var.h +++ b/packages/net/bsd_tcpip/current/include/netinet/igmp_var.h @@ -113,5 +113,18 @@ void igmp_leavegroup __P((struct in_mult void igmp_fasttimo __P((void)); void igmp_slowtimo __P((void)); +SYSCTL_DECL(_net_inet_igmp); + #endif + +/* + * Names for IGMP sysctl objects + */ +#define IGMPCTL_STATS 1 /* statistics (read-only) */ +#define IGMPCTL_MAXID 2 + +#define IGMPCTL_NAMES { \ + { 0, 0 }, \ + { "stats", CTLTYPE_STRUCT }, \ +} #endif
--- a/packages/net/bsd_tcpip/current/include/netinet/in_var.h +++ b/packages/net/bsd_tcpip/current/include/netinet/in_var.h @@ -170,6 +170,11 @@ struct in_multi { #ifdef _KERNEL +#ifdef SYSCTL_DECL +SYSCTL_DECL(_net_inet_ip); +SYSCTL_DECL(_net_inet_raw); +#endif + extern LIST_HEAD(in_multihead, in_multi) in_multihead; /*
--- a/packages/net/bsd_tcpip/current/include/netinet/udp_var.h +++ b/packages/net/bsd_tcpip/current/include/netinet/udp_var.h @@ -94,7 +94,27 @@ struct udpstat { u_long udps_noportmcast; }; +/* + * Names for UDP sysctl objects + */ +#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ +#define UDPCTL_STATS 2 /* statistics (read-only) */ +#define UDPCTL_MAXDGRAM 3 /* max datagram size */ +#define UDPCTL_RECVSPACE 4 /* default receive buffer space */ +#define UDPCTL_PCBLIST 5 /* list of PCBs for UDP sockets */ +#define UDPCTL_MAXID 6 + +#define UDPCTL_NAMES { \ + { 0, 0 }, \ + { "checksum", CTLTYPE_INT }, \ + { "stats", CTLTYPE_STRUCT }, \ + { "maxdgram", CTLTYPE_INT }, \ + { "recvspace", CTLTYPE_INT }, \ + { "pcblist", CTLTYPE_STRUCT }, \ +} + #ifdef _KERNEL +SYSCTL_DECL(_net_inet_udp); extern struct pr_usrreqs udp_usrreqs; extern struct inpcbhead udb;
--- a/packages/net/bsd_tcpip/current/include/netinet6/ip6protosw.h +++ b/packages/net/bsd_tcpip/current/include/netinet6/ip6protosw.h @@ -161,8 +161,14 @@ struct ip6protosw { #ifdef __bsdi__ int (*pr_output)(); /* output to protocol (from above) */ #else - int (*pr_output) /* output to protocol (from above) */ - __P((struct mbuf *, ...)); +#if (defined(__FreeBSD__) && __FreeBSD__ >= 4) + int (*rip6_output) + __P((struct mbuf *, struct socket *, + struct sockaddr_in6 *, struct mbuf *)); +#else +int int (*rip6_output) + __P((struct mbuf *, ...)); +#endif /* (defined(__FreeBSD__) && __FreeBSD__ >= 4) */ #endif void (*pr_ctlinput) /* control input (from below) */ __P((int, struct sockaddr *, void *));
--- a/packages/net/bsd_tcpip/current/include/netinet6/tcp6_var.h +++ b/packages/net/bsd_tcpip/current/include/netinet6/tcp6_var.h @@ -90,6 +90,9 @@ #define _NETINET_TCP6_VAR_H_ #ifdef _KERNEL +#ifdef SYSCTL_DECL +SYSCTL_DECL(_net_inet6_tcp6); +#endif extern int tcp_v6mssdflt; /* XXX */
--- a/packages/net/bsd_tcpip/current/include/netinet6/udp6_var.h +++ b/packages/net/bsd_tcpip/current/include/netinet6/udp6_var.h @@ -89,6 +89,7 @@ #define _NETINET6_UDP6_VAR_H_ #ifdef _KERNEL +SYSCTL_DECL(_net_inet6_udp6); extern struct pr_usrreqs udp6_usrreqs;
--- a/packages/net/bsd_tcpip/current/include/sys/malloc.h +++ b/packages/net/bsd_tcpip/current/include/sys/malloc.h @@ -60,5 +60,7 @@ externC void cyg_net_free(caddr_t addr, #define M_IP6NDP 90 #define M_MRTABLE 89 #define M_FTABLE 88 +#define M_SYSCTLOID 100 +#define M_SYSCTL 101 #endif // _SYS_MALLOC_H_
--- a/packages/net/bsd_tcpip/current/include/sys/param.h +++ b/packages/net/bsd_tcpip/current/include/sys/param.h @@ -734,11 +734,6 @@ extern void getmicrouptime(struct timeva extern int tvtohz(struct timeval *tv); extern int arc4random(void); -//extern u_int in_cksum_hdr(const struct ip *ip); -//extern u_short in_cksum_skip(struct mbuf *m, int len, int skip); -//extern u_short in_pseudo(u_int32_t a, u_int32_t b, u_int32_t c); - - // Function mappings extern int cyg_ticks(void); @@ -896,7 +891,7 @@ struct init_tab_entry { #define _cat(a,b) a##b #define __Net_init(_p1_,_p2_,_f_,_d_) \ struct init_tab_entry _cat(_net_init_tab,_p1_##_p2_##_f_) \ - CYG_HAL_TABLE_QUALIFIED_ENTRY(_Net_inits,_p1_##_p2_##_f_) = { _f_, _d_, #_f_ }; + CYG_HAL_TABLE_QUALIFIED_ENTRY(_Net_inits,_p1_##_p2_##_f_) = { (_init_fun_ptr) _f_, _d_, #_f_ }; #define _Net_init(_p1_,_p2_,_f_,_d_) \ __Net_init(_p1_,_p2_,_f_,_d_) @@ -988,5 +983,5 @@ if (cyg_net_log_mask & lvl) #endif #endif // _KERNEL - +int extern cyg_arc4random(void); #endif //_SYS_PARAM_H_
--- a/packages/net/bsd_tcpip/current/include/sys/socket.h +++ b/packages/net/bsd_tcpip/current/include/sys/socket.h @@ -244,7 +244,6 @@ struct sockaddr_storage { #define PF_MAX AF_MAX -#if 0 // sysctl() interface not supported /* * Definitions for network related sysctl, CTL_NET. * @@ -310,7 +309,6 @@ struct sockaddr_storage { { "flags", CTLTYPE_STRUCT }, \ { "iflist", CTLTYPE_STRUCT }, \ } -#endif // sysctl() support /* * Maximum queue length specifiable by listen.
new file mode 100644 --- /dev/null +++ b/packages/net/bsd_tcpip/current/include/sys/sysctl.h @@ -0,0 +1,635 @@ +//========================================================================== +// +// include/sys/sysctl.h +// +//========================================================================== +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD, +// FreeBSD or other sources, and are covered by the appropriate +// copyright disclaimers included herein. +// +// Portions created by Red Hat are +// Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== + +/* + * 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 + * $FreeBSD: src/sys/sys/sysctl.h,v 1.81.2.7 2001/07/18 15:36:56 pirzyk Exp $ + */ + +#ifndef _SYS_SYSCTL_H_ +#define _SYS_SYSCTL_H_ + +#include <sys/queue.h> +#include <cyg/hal/hal_tables.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. + */ +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 CTLTYPE_UINT 6 /* name describes an unsigned integer */ +#define CTLTYPE_LONG 7 /* name describes a long */ +#define CTLTYPE_ULONG 8 /* name describes an unsigned long */ + +#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_PRISON 0x04000000 /* Prisoned roots can fiddle */ +#define CTLFLAG_DYN 0x02000000 /* Dynamic oid - can be freed */ + +/* + * 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, ""); + */ +#define OID_AUTO (-1) + +#ifdef _KERNEL +#define SYSCTL_HANDLER_ARGS struct sysctl_oid *oidp, void *arg1, int arg2, \ + 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; + void *oldptr; + size_t oldlen; + size_t oldidx; + int (*oldfunc)(struct sysctl_req *, const void *, size_t); + void *newptr; + size_t newlen; + size_t newidx; + int (*newfunc)(struct sysctl_req *, void *, size_t); +}; + +SLIST_HEAD(sysctl_oid_list, sysctl_oid); + +/* + * This describes one "oid" in the MIB tree. Potentially more nodes can + * be hidden behind it, expanded by the handler. + */ +struct sysctl_oid { + struct sysctl_oid_list *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; + int oid_refcnt; +} CYG_HAL_TABLE_TYPE; + +#define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l) +#define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l) + +int sysctl_handle_int(SYSCTL_HANDLER_ARGS); +int sysctl_handle_long(SYSCTL_HANDLER_ARGS); +int sysctl_handle_intptr(SYSCTL_HANDLER_ARGS); +int sysctl_handle_string(SYSCTL_HANDLER_ARGS); +int sysctl_handle_opaque(SYSCTL_HANDLER_ARGS); + +/* + * 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); + +/* Declare a static oid to allow child oids to be added to it. */ +#define SYSCTL_DECL(name) \ + extern struct sysctl_oid_list sysctl_##name##_children + +/* Hide these in macros */ +#define SYSCTL_CHILDREN(oid_ptr) (struct sysctl_oid_list *) \ + (oid_ptr)->oid_arg1 +#define SYSCTL_STATIC_CHILDREN(oid_name) \ + (&sysctl_##oid_name##_children) + +/* === Structs and macros related to context handling === */ + +/* All dynamically created sysctls can be tracked in a context list. */ +struct sysctl_ctx_entry { + struct sysctl_oid *entry; + TAILQ_ENTRY(sysctl_ctx_entry) link; +}; + +TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); + +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +/* This constructs a "raw" MIB oid. */ +#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \ + struct sysctl_oid sysctl__##parent##_##name \ + CYG_HAL_TABLE_ENTRY(sysctl_set) = { \ + &sysctl_##parent##_children, { 0 }, \ + nbr, kind, a1, a2, #name, handler, fmt }; +#else +#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) +#endif + +#define SYSCTL_ADD_OID(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, descr) \ + sysctl_add_oid(ctx, 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, \ + (void*)&sysctl_##parent##_##name##_children, 0, handler, \ + "N", descr); + +#define SYSCTL_ADD_NODE(ctx, parent, nbr, name, access, handler, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_NODE|access, \ + 0, 0, handler, "N", descr); + +/* 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_ADD_STRING(ctx, parent, nbr, name, access, arg, len, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_STRING|access, \ + arg, len, sysctl_handle_string, "A", 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) + +#define SYSCTL_ADD_INT(ctx, parent, nbr, name, access, ptr, val, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_INT|access, \ + ptr, val, sysctl_handle_int, "I", descr); + +/* 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_UINT|access, \ + ptr, val, sysctl_handle_int, "IU", descr) + +#define SYSCTL_ADD_UINT(ctx, parent, nbr, name, access, ptr, val, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|access, \ + ptr, val, sysctl_handle_int, "IU", descr); + +/* Oid for a long. The pointer must be non NULL. */ +#define SYSCTL_LONG(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, CTLTYPE_LONG|access, \ + ptr, val, sysctl_handle_long, "L", descr) + +#define SYSCTL_ADD_LONG(ctx, parent, nbr, name, access, ptr, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_LONG|access, \ + ptr, 0, sysctl_handle_long, "L", descr); + +/* Oid for a long. The pointer must be non NULL. */ +#define SYSCTL_ULONG(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, CTLTYPE_ULONG|access, \ + ptr, val, sysctl_handle_long, "LU", descr) + +#define SYSCTL_ADD_ULONG(ctx, parent, nbr, name, access, ptr, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_ULONG|access, \ + ptr, 0, sysctl_handle_long, "LU", descr); + +/* 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) + +#define SYSCTL_ADD_OPAQUE(ctx, parent, nbr, name, access, ptr, len, fmt, descr)\ + sysctl_add_oid(ctx, 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) + +#define SYSCTL_ADD_STRUCT(ctx, parent, nbr, name, access, ptr, type, descr) \ + sysctl_add_oid(ctx, 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. */ +#define SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr) \ + SYSCTL_OID(parent, nbr, name, access, \ + ptr, arg, handler, fmt, descr) + +#define SYSCTL_ADD_PROC(ctx, parent, nbr, name, access, ptr, arg, handler, fmt, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, access, \ + ptr, arg, handler, fmt, descr); + +#endif /* _KERNEL */ + +/* + * 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_P1003_1B 9 /* POSIX 1003.1B */ +#define CTL_MAXID 10 /* 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 }, \ + { "p1003_1b", 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_UPDATEINTERVAL 23 /* int: update process sleep time */ +#define KERN_OSRELDATE 24 /* int: OS release date */ +#define KERN_NTP_PLL 25 /* node: NTP PLL control */ +#define KERN_BOOTFILE 26 /* string: name of booted kernel */ +#define KERN_MAXFILESPERPROC 27 /* int: max open files per proc */ +#define KERN_MAXPROCPERUID 28 /* int: max processes per uid */ +#define KERN_DUMPDEV 29 /* dev_t: device to dump on */ +#define KERN_IPC 30 /* node: anything related to IPC */ +#define KERN_DUMMY 31 /* unused */ +#define KERN_PS_STRINGS 32 /* int: address of PS_STRINGS */ +#define KERN_USRSTACK 33 /* int: address of USRSTACK */ +#define KERN_LOGSIGEXIT 34 /* int: do we log sigexit procs? */ +#define KERN_MAXID 35 /* number of valid kern ids */ + +#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_UINT }, \ + { "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 }, \ + { "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 }, \ + { "ps_strings", CTLTYPE_INT }, \ + { "usrstack", CTLTYPE_INT }, \ + { "logsigexit", CTLTYPE_INT }, \ +} + +/* + * 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_ARGS 7 /* get/set arguments/proctitle */ + +/* + * 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 */ + +/* + * CTL_HW identifiers + */ +#define HW_MACHINE 1 /* string: machine class */ +#define HW_MODEL 2 /* string: specific machine model */ +#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_FLOATINGPT 10 /* int: has HW floating point? */ +#define HW_MACHINE_ARCH 11 /* string: machine architecture */ +#define HW_MAXID 12 /* number of valid hw ids */ + +#define CTL_HW_NAMES { \ + { 0, 0 }, \ + { "machine", CTLTYPE_STRING }, \ + { "model", CTLTYPE_STRING }, \ + { "ncpu", CTLTYPE_INT }, \ + { "byteorder", CTLTYPE_INT }, \ + { "physmem", CTLTYPE_UINT }, \ + { "usermem", CTLTYPE_UINT }, \ + { "pagesize", CTLTYPE_INT }, \ + { "disknames", CTLTYPE_STRUCT }, \ + { "diskstats", CTLTYPE_STRUCT }, \ + { "floatingpoint", CTLTYPE_INT }, \ +} + +/* + * 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 }, \ +} + +#define CTL_P1003_1B_ASYNCHRONOUS_IO 1 /* boolean */ +#define CTL_P1003_1B_MAPPED_FILES 2 /* boolean */ +#define CTL_P1003_1B_MEMLOCK 3 /* boolean */ +#define CTL_P1003_1B_MEMLOCK_RANGE 4 /* boolean */ +#define CTL_P1003_1B_MEMORY_PROTECTION 5 /* boolean */ +#define CTL_P1003_1B_MESSAGE_PASSING 6 /* boolean */ +#define CTL_P1003_1B_PRIORITIZED_IO 7 /* boolean */ +#define CTL_P1003_1B_PRIORITY_SCHEDULING 8 /* boolean */ +#define CTL_P1003_1B_REALTIME_SIGNALS 9 /* boolean */ +#define CTL_P1003_1B_SEMAPHORES 10 /* boolean */ +#define CTL_P1003_1B_FSYNC 11 /* boolean */ +#define CTL_P1003_1B_SHARED_MEMORY_OBJECTS 12 /* boolean */ +#define CTL_P1003_1B_SYNCHRONIZED_IO 13 /* boolean */ +#define CTL_P1003_1B_TIMERS 14 /* boolean */ +#define CTL_P1003_1B_AIO_LISTIO_MAX 15 /* int */ +#define CTL_P1003_1B_AIO_MAX 16 /* int */ +#define CTL_P1003_1B_AIO_PRIO_DELTA_MAX 17 /* int */ +#define CTL_P1003_1B_DELAYTIMER_MAX 18 /* int */ +#define CTL_P1003_1B_MQ_OPEN_MAX 19 /* int */ +#define CTL_P1003_1B_PAGESIZE 20 /* int */ +#define CTL_P1003_1B_RTSIG_MAX 21 /* int */ +#define CTL_P1003_1B_SEM_NSEMS_MAX 22 /* int */ +#define CTL_P1003_1B_SEM_VALUE_MAX 23 /* int */ +#define CTL_P1003_1B_SIGQUEUE_MAX 24 /* int */ +#define CTL_P1003_1B_TIMER_MAX 25 /* int */ + +#define CTL_P1003_1B_MAXID 26 + +#define CTL_P1003_1B_NAMES { \ + { 0, 0 }, \ + { "asynchronous_io", CTLTYPE_INT }, \ + { "mapped_files", CTLTYPE_INT }, \ + { "memlock", CTLTYPE_INT }, \ + { "memlock_range", CTLTYPE_INT }, \ + { "memory_protection", CTLTYPE_INT }, \ + { "message_passing", CTLTYPE_INT }, \ + { "prioritized_io", CTLTYPE_INT }, \ + { "priority_scheduling", CTLTYPE_INT }, \ + { "realtime_signals", CTLTYPE_INT }, \ + { "semaphores", CTLTYPE_INT }, \ + { "fsync", CTLTYPE_INT }, \ + { "shared_memory_objects", CTLTYPE_INT }, \ + { "synchronized_io", CTLTYPE_INT }, \ + { "timers", CTLTYPE_INT }, \ + { "aio_listio_max", CTLTYPE_INT }, \ + { "aio_max", CTLTYPE_INT }, \ + { "aio_prio_delta_max", CTLTYPE_INT }, \ + { "delaytimer_max", CTLTYPE_INT }, \ + { "mq_open_max", CTLTYPE_INT }, \ + { "pagesize", CTLTYPE_INT }, \ + { "rtsig_max", CTLTYPE_INT }, \ + { "nsems_max", CTLTYPE_INT }, \ + { "sem_value_max", CTLTYPE_INT }, \ + { "sigqueue_max", CTLTYPE_INT }, \ + { "timer_max", CTLTYPE_INT }, \ +} + +#ifdef _KERNEL + +/* + * Declare some common oids. + */ +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); +SYSCTL_DECL(_compat); + +extern char machine[]; +extern char osrelease[]; +extern char ostype[]; + +struct linker_set; + +/* Dynamic oid handling */ +struct sysctl_oid *sysctl_add_oid(struct sysctl_ctx_list *clist, + struct sysctl_oid_list *parent, int nbr, const char *name, + int kind, void *arg1, int arg2, + int (*handler) (SYSCTL_HANDLER_ARGS), + const char *fmt, const char *descr); +int sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse); +int sysctl_ctx_init(struct sysctl_ctx_list *clist); +int sysctl_ctx_free(struct sysctl_ctx_list *clist); +struct sysctl_ctx_entry *sysctl_ctx_entry_add(struct sysctl_ctx_list *clist, + struct sysctl_oid *oidp); +struct sysctl_ctx_entry *sysctl_ctx_entry_find(struct sysctl_ctx_list *clist, + struct sysctl_oid *oidp); +int sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, + struct sysctl_oid *oidp); + +/* Linker set based oid handling */ +void sysctl_register_set(struct linker_set *lsp); +void sysctl_unregister_set(struct linker_set *lsp); + +int kernel_sysctl(struct proc *p, int *name, u_int namelen, void *old, + size_t *oldlenp, void *new, size_t newlen, + size_t *retval); +int userland_sysctl(struct proc *p, int *name, u_int namelen, void *old, + size_t *oldlenp, int inkernel, void *new, size_t newlen, + size_t *retval); +int sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid, + int *nindx, struct sysctl_req *req); + +#else /* !_KERNEL */ +#include <sys/cdefs.h> + +__BEGIN_DECLS +int sysctl __P((int *, u_int, void *, size_t *, void *, size_t)); +int sysctlbyname __P((const char *, void *, size_t *, void *, size_t)); +int sysctlnametomib __P((const char *, int *, size_t *)); +__END_DECLS +#endif /* _KERNEL */ + +#endif /* !_SYS_SYSCTL_H_ */ + + + + + +
new file mode 100644 --- /dev/null +++ b/packages/net/bsd_tcpip/current/src/sys/kern/kern_sysctl.c @@ -0,0 +1,1029 @@ +/*- + * Copyright (c) 1982, 1986, 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. + * + * Quite extensively rewritten by Poul-Henning Kamp of the FreeBSD + * project, to make these variables more userfriendly. + * + * 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. + * + * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94 + * $FreeBSD: src/sys/kern/kern_sysctl.c,v 1.92.2.5 2001/06/18 23:48:13 dd Exp $ + */ + +//#include "opt_compat.h" + +#include <sys/param.h> +//#include <sys/systm.h> +//#include <sys/kernel.h> +//#include <sys/buf.h> +#include <sys/sysctl.h> +#include <sys/malloc.h> +//#include <sys/proc.h> +//#include <sys/sysproto.h> +//#include <vm/vm.h> +//#include <vm/vm_extern.h> + +#include <cyg/kernel/kapi.h> +#include <cyg/hal/hal_tables.h> + +/* + * Locking and stats + */ + +static cyg_mutex_t mutex; +static int mutex_init = 0; + +static int sysctl_root(SYSCTL_HANDLER_ARGS); + +struct sysctl_oid_list sysctl__children; /* root list */ +SYSCTL_NODE( , CTL_NET, net , CTLFLAG_RW, NULL, "Network root"); +SYSCTL_NODE( , CTL_DEBUG, sysctl , CTLFLAG_RW, NULL, "Debug root"); + +struct sysctl_oid_list sysctl__net_children; + struct sysctl_oid_list sysctl__sysctl_children; + +static struct sysctl_oid * +sysctl_find_oidname(const char *name, struct sysctl_oid_list *list) +{ + struct sysctl_oid *oidp; + + SLIST_FOREACH(oidp, list, oid_link) { + if (strcmp(oidp->oid_name, name) == 0) { + return (oidp); + } + } + return (NULL); +} + +/* + * Initialization of the MIB tree. + * + * Order by number in each list. + */ + +void sysctl_register_oid(struct sysctl_oid *oidp) +{ + struct sysctl_oid_list *parent = oidp->oid_parent; + struct sysctl_oid *p; + struct sysctl_oid *q; + int n; + + /* + * First check if another oid with the same name already + * exists in the parent's list. + */ + p = sysctl_find_oidname(oidp->oid_name, parent); + if (p != NULL) { + if ((p->oid_kind & CTLTYPE) == CTLTYPE_NODE) { + p->oid_refcnt++; + return; + } else { + printf("can't re-use a leaf (%s)!\n", p->oid_name); + return; + } + } + /* + * If this oid has a number OID_AUTO, give it a number which + * is greater than any current oid. Make sure it is at least + * 100 to leave space for pre-assigned oid numbers. + */ + if (oidp->oid_number == OID_AUTO) { + /* First, find the highest oid in the parent list >99 */ + n = 99; + SLIST_FOREACH(p, parent, oid_link) { + if (p->oid_number > n) + n = p->oid_number; + } + oidp->oid_number = n + 1; + } + + /* + * Insert the oid into the parent's list in order. + */ + q = NULL; + SLIST_FOREACH(p, parent, oid_link) { + if (oidp->oid_number < p->oid_number) + break; + q = p; + } + if (q) + SLIST_INSERT_AFTER(q, oidp, oid_link); + else + SLIST_INSERT_HEAD(parent, oidp, oid_link); +} + +void sysctl_unregister_oid(struct sysctl_oid *oidp) +{ + SLIST_REMOVE(oidp->oid_parent, oidp, sysctl_oid, oid_link); +} + +/* Initialize a new context to keep track of dynamically added sysctls. */ +int +sysctl_ctx_init(struct sysctl_ctx_list *c) +{ + + if (c == NULL) { + return (EINVAL); + } + TAILQ_INIT(c); + return (0); +} + +/* Free the context, and destroy all dynamic oids registered in this context */ +int +sysctl_ctx_free(struct sysctl_ctx_list *clist) +{ + struct sysctl_ctx_entry *e, *e1; + int error; + + error = 0; + /* + * First perform a "dry run" to check if it's ok to remove oids. + * XXX FIXME + * XXX This algorithm is a hack. But I don't know any + * XXX better solution for now... + */ + TAILQ_FOREACH(e, clist, link) { + error = sysctl_remove_oid(e->entry, 0, 0); + if (error) + break; + } + /* + * Restore deregistered entries, either from the end, + * or from the place where error occured. + * e contains the entry that was not unregistered + */ + if (error) + e1 = TAILQ_PREV(e, sysctl_ctx_list, link); + else + e1 = TAILQ_LAST(clist, sysctl_ctx_list); + while (e1 != NULL) { + sysctl_register_oid(e1->entry); + e1 = TAILQ_PREV(e1, sysctl_ctx_list, link); + } + if (error) + return(EBUSY); + /* Now really delete the entries */ + e = TAILQ_FIRST(clist); + while (e != NULL) { + e1 = TAILQ_NEXT(e, link); + error = sysctl_remove_oid(e->entry, 1, 0); + if (error) + panic("sysctl_remove_oid: corrupt tree, entry: %s", + e->entry->oid_name); + free(e, M_SYSCTLOID); + e = e1; + } + return (error); +} + +/* Add an entry to the context */ +struct sysctl_ctx_entry * +sysctl_ctx_entry_add(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) +{ + struct sysctl_ctx_entry *e; + + if (clist == NULL || oidp == NULL) + return(NULL); + e = malloc(sizeof(struct sysctl_ctx_entry), M_SYSCTLOID, M_WAITOK); + e->entry = oidp; + TAILQ_INSERT_HEAD(clist, e, link); + return (e); +} + +/* Find an entry in the context */ +struct sysctl_ctx_entry * +sysctl_ctx_entry_find(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) +{ + struct sysctl_ctx_entry *e; + + if (clist == NULL || oidp == NULL) + return(NULL); + for (e = TAILQ_FIRST(clist); e != NULL; e = TAILQ_NEXT(e, link)) { + if(e->entry == oidp) + return(e); + } + return (e); +} + +/* + * Delete an entry from the context. + * NOTE: this function doesn't free oidp! You have to remove it + * with sysctl_remove_oid(). + */ +int +sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) +{ + struct sysctl_ctx_entry *e; + + if (clist == NULL || oidp == NULL) + return (EINVAL); + e = sysctl_ctx_entry_find(clist, oidp); + if (e != NULL) { + TAILQ_REMOVE(clist, e, link); + free(e, M_SYSCTLOID); + return (0); + } else + return (ENOENT); +} + +/* + * Remove dynamically created sysctl trees. + * oidp - top of the tree to be removed + * del - if 0 - just deregister, otherwise free up entries as well + * recurse - if != 0 traverse the subtree to be deleted + */ +int +sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse) +{ + struct sysctl_oid *p; + int error; + + if (oidp == NULL) + return(EINVAL); + if ((oidp->oid_kind & CTLFLAG_DYN) == 0) { + printf("can't remove non-dynamic nodes!\n"); + return (EINVAL); + } + /* + * WARNING: normal method to do this should be through + * sysctl_ctx_free(). Use recursing as the last resort + * method to purge your sysctl tree of leftovers... + * However, if some other code still references these nodes, + * it will panic. + */ + if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { + if (oidp->oid_refcnt == 1) { + SLIST_FOREACH(p, SYSCTL_CHILDREN(oidp), oid_link) { + if (!recurse) + return (ENOTEMPTY); + error = sysctl_remove_oid(p, del, recurse); + if (error) + return (error); + } + if (del) + free(SYSCTL_CHILDREN(oidp), M_SYSCTLOID); + } + } + if (oidp->oid_refcnt > 1 ) { + oidp->oid_refcnt--; + } else { + if (oidp->oid_refcnt == 0) { + printf("Warning: bad oid_refcnt=%u (%s)!\n", + oidp->oid_refcnt, oidp->oid_name); + return (EINVAL); + } + sysctl_unregister_oid(oidp); + if (del) { + free((void *)oidp->oid_name, + M_SYSCTLOID); + free(oidp, M_SYSCTLOID); + } + } + return (0); +} + +/* + * Create new sysctls at run time. + * clist may point to a valid context initialized with sysctl_ctx_init(). + */ +struct sysctl_oid * +sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, + int number, const char *name, int kind, void *arg1, int arg2, + int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, const char *descr) +{ + struct sysctl_oid *oidp; + ssize_t len; + char *newname; + + /* You have to hook up somewhere.. */ + if (parent == NULL) + return(NULL); + /* Check if the node already exists, otherwise create it */ + oidp = sysctl_find_oidname(name, parent); + if (oidp != NULL) { + if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { + oidp->oid_refcnt++; + /* Update the context */ + if (clist != NULL) + sysctl_ctx_entry_add(clist, oidp); + return (oidp); + } else { + printf("can't re-use a leaf (%s)!\n", name); + return (NULL); + } + } + oidp = malloc(sizeof(struct sysctl_oid), M_SYSCTLOID, M_WAITOK); + bzero(oidp, sizeof(struct sysctl_oid)); + oidp->oid_parent = parent; + SLIST_NEXT(oidp, oid_link) = NULL; + oidp->oid_number = number; + oidp->oid_refcnt = 1; + len = strlen(name); + newname = malloc(len + 1, M_SYSCTLOID, M_WAITOK); + bcopy(name, newname, len + 1); + newname[len] = '\0'; + oidp->oid_name = newname; + oidp->oid_handler = handler; + oidp->oid_kind = CTLFLAG_DYN | kind; + if ((kind & CTLTYPE) == CTLTYPE_NODE) { + /* Allocate space for children */ + SYSCTL_CHILDREN(oidp) = malloc(sizeof(struct sysctl_oid_list), + M_SYSCTLOID, M_WAITOK); + SLIST_INIT(SYSCTL_CHILDREN(oidp)); + } else { + oidp->oid_arg1 = arg1; + oidp->oid_arg2 = arg2; + } + oidp->oid_fmt = fmt; + /* Update the context, if used */ + if (clist != NULL) + sysctl_ctx_entry_add(clist, oidp); + /* Register this oid */ + sysctl_register_oid(oidp); + return (oidp); +} + +/* + * Bulk-register all the oids in the table. + */ +CYG_HAL_TABLE_BEGIN(__sysctl_tab__, sysctl_set); +CYG_HAL_TABLE_END(__sysctl_tab_end__, sysctl_set); +extern struct sysctl_oid __sysctl_tab__[]; +extern struct sysctl_oid __sysctl_tab_end__; + +static void sysctl_register_all(void *arg) +{ + struct sysctl_oid * oidp; + + for (oidp = __sysctl_tab__ ; oidp != &__sysctl_tab_end__; oidp++) { + sysctl_register_oid(oidp); + } +} + +SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_all, 0); + +/* + * "Staff-functions" + * + * These functions implement a presently undocumented interface + * used by the sysctl program to walk the tree, and get the type + * so it can print the value. + * This interface is under work and consideration, and should probably + * be killed with a big axe by the first person who can find the time. + * (be aware though, that the proper interface isn't as obvious as it + * may seem, there are various conflicting requirements. + * + * {0,0} printf the entire MIB-tree. + * {0,1,...} return the name of the "..." OID. + * {0,2,...} return the next OID. + * {0,3} return the OID of the name in "new" + * {0,4,...} return the kind & format info for the "..." OID. + */ + +static void +sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i) +{ + int k; + struct sysctl_oid *oidp; + + SLIST_FOREACH(oidp, l, oid_link) { + + for (k=0; k<i; k++) + printf(" "); + + printf("%d %s ", oidp->oid_number, oidp->oid_name); + + printf("%c%c", + oidp->oid_kind & CTLFLAG_RD ? 'R':' ', + oidp->oid_kind & CTLFLAG_WR ? 'W':' '); + + if (oidp->oid_handler) + printf(" *Handler"); + + switch (oidp->oid_kind & CTLTYPE) { + case CTLTYPE_NODE: + printf(" Node\n"); + if (!oidp->oid_handler) { + sysctl_sysctl_debug_dump_node( + oidp->oid_arg1, i+2); + } + break; + case CTLTYPE_INT: printf(" Int\n"); break; + case CTLTYPE_STRING: printf(" String\n"); break; + case CTLTYPE_QUAD: printf(" Quad\n"); break; + case CTLTYPE_OPAQUE: printf(" Opaque/struct\n"); break; + default: printf("\n"); + } + + } +} + +static int +sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS) +{ + sysctl_sysctl_debug_dump_node(&sysctl__children, 0); + return ENOENT; +} + +SYSCTL_PROC(_sysctl, 0, debug, CTLTYPE_STRING|CTLFLAG_RD, + 0, 0, sysctl_sysctl_debug, "-", ""); + +static int +sysctl_sysctl_name(SYSCTL_HANDLER_ARGS) +{ + int *name = (int *) arg1; + u_int namelen = arg2; + int error = 0; + struct sysctl_oid *oid; + struct sysctl_oid_list *lsp = &sysctl__children, *lsp2; + char buf[10]; + + while (namelen) { + if (!lsp) { + snprintf(buf,sizeof(buf),"%d",*name); + if (req->oldidx) + error = SYSCTL_OUT(req, ".", 1); + if (!error) + error = SYSCTL_OUT(req, buf, strlen(buf)); + if (error) + return (error); + namelen--; + name++; + continue; + } + lsp2 = 0; + SLIST_FOREACH(oid, lsp, oid_link) { + if (oid->oid_number != *name) + continue; + + if (req->oldidx) + error = SYSCTL_OUT(req, ".", 1); + if (!error) + error = SYSCTL_OUT(req, oid->oid_name, + strlen(oid->oid_name)); + if (error) + return (error); + + namelen--; + name++; + + if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE) + break; + + if (oid->oid_handler) + break; + + lsp2 = (struct sysctl_oid_list *)oid->oid_arg1; + break; + } + lsp = lsp2; + } + return (SYSCTL_OUT(req, "", 1)); +} + +SYSCTL_NODE(_sysctl, 1, name, CTLFLAG_RD, sysctl_sysctl_name, ""); + +static int +sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, + int *next, int *len, int level, struct sysctl_oid **oidpp) +{ + struct sysctl_oid *oidp; + + *len = level; + SLIST_FOREACH(oidp, lsp, oid_link) { + *next = oidp->oid_number; + *oidpp = oidp; + + if (!namelen) { + if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) + return 0; + if (oidp->oid_handler) + /* We really should call the handler here...*/ + return 0; + lsp = (struct sysctl_oid_list *)oidp->oid_arg1; + if (!sysctl_sysctl_next_ls(lsp, 0, 0, next+1, + len, level+1, oidpp)) + return 0; + goto emptynode; + } + + if (oidp->oid_number < *name) + continue; + + if (oidp->oid_number > *name) { + if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) + return 0; + if (oidp->oid_handler) + return 0; + lsp = (struct sysctl_oid_list *)oidp->oid_arg1; + if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, + next+1, len, level+1, oidpp)) + return (0); + goto next; + } + if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) + continue; + + if (oidp->oid_handler) + continue; + + lsp = (struct sysctl_oid_list *)oidp->oid_arg1; + if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, next+1, + len, level+1, oidpp)) + return (0); + next: + namelen = 1; + emptynode: + *len = level; + } + return 1; +} + +static int +sysctl_sysctl_next(SYSCTL_HANDLER_ARGS) +{ + int *name = (int *) arg1; + u_int namelen = arg2; + int i, j, error; + struct sysctl_oid *oid; + struct sysctl_oid_list *lsp = &sysctl__children; + int newoid[CTL_MAXNAME]; + + i = sysctl_sysctl_next_ls(lsp, name, namelen, newoid, &j, 1, &oid); + if (i) + return ENOENT; + error = SYSCTL_OUT(req, newoid, j * sizeof (int)); + return (error); +} + +SYSCTL_NODE(_sysctl, 2, next, CTLFLAG_RD, sysctl_sysctl_next, ""); + +static int +name2oid (char *name, int *oid, int *len, struct sysctl_oid **oidpp) +{ + int i; + struct sysctl_oid *oidp; + struct sysctl_oid_list *lsp = &sysctl__children; + char *p; + + if (!*name) + return ENOENT; + + p = name + strlen(name) - 1 ; + if (*p == '.') + *p = '\0'; + + *len = 0; + + for (p = name; *p && *p != '.'; p++) + ; + i = *p; + if (i == '.') + *p = '\0'; + + oidp = SLIST_FIRST(lsp); + + while (oidp && *len < CTL_MAXNAME) { + if (strcmp(name, oidp->oid_name)) { + oidp = SLIST_NEXT(oidp, oid_link); + continue; + } + *oid++ = oidp->oid_number; + (*len)++; + + if (!i) { + if (oidpp) + *oidpp = oidp; + return (0); + } + + if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) + break; + + if (oidp->oid_handler) + break; + + lsp = (struct sysctl_oid_list *)oidp->oid_arg1; + oidp = SLIST_FIRST(lsp); + name = p+1; + for (p = name; *p && *p != '.'; p++) + ; + i = *p; + if (i == '.') + *p = '\0'; + } + return ENOENT; +} + +static int +sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS) +{ + char *p; + int error, oid[CTL_MAXNAME], len; + struct sysctl_oid *op = 0; + + if (!req->newlen) + return ENOENT; + if (req->newlen >= _POSIX_PATH_MAX) /* XXX arbitrary, undocumented */ + return (ENAMETOOLONG); + + p = malloc(req->newlen+1, M_SYSCTL, M_WAITOK); + + error = SYSCTL_IN(req, p, req->newlen); + if (error) { + free(p, M_SYSCTL); + return (error); + } + + p [req->newlen] = '\0'; + + error = name2oid(p, oid, &len, &op); + + free(p, M_SYSCTL); + + if (error) + return (error); + + error = SYSCTL_OUT(req, oid, len * sizeof *oid); + return (error); +} + +SYSCTL_PROC(_sysctl, 3, name2oid, CTLFLAG_RW|CTLFLAG_ANYBODY, 0, 0, + sysctl_sysctl_name2oid, "I", ""); + +static int +sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS) +{ + struct sysctl_oid *oid; + int error; + + error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); + if (error) + return (error); + + if (!oid->oid_fmt) + return (ENOENT); + error = SYSCTL_OUT(req, &oid->oid_kind, sizeof(oid->oid_kind)); + if (error) + return (error); + error = SYSCTL_OUT(req, oid->oid_fmt, strlen(oid->oid_fmt) + 1); + return (error); +} + + +SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD, sysctl_sysctl_oidfmt, ""); + +/* + * Default "handler" functions. + */ + +/* + * Handle an int, signed or unsigned. + * Two cases: + * a variable: point arg1 at it. + * a constant: pass it in arg2. + */ + +int +sysctl_handle_int(SYSCTL_HANDLER_ARGS) +{ + int error = 0; + + if (arg1) + error = SYSCTL_OUT(req, arg1, sizeof(int)); + else + error = SYSCTL_OUT(req, &arg2, sizeof(int)); + + if (error || !req->newptr) + return (error); + + if (!arg1) + error = EPERM; + else + error = SYSCTL_IN(req, arg1, sizeof(int)); + return (error); +} + +/* + * Handle a long, signed or unsigned. arg1 points to it. + */ + +int +sysctl_handle_long(SYSCTL_HANDLER_ARGS) +{ + int error = 0; + + if (!arg1) + return (EINVAL); + error = SYSCTL_OUT(req, arg1, sizeof(long)); + + if (error || !req->newptr) + return (error); + + error = SYSCTL_IN(req, arg1, sizeof(long)); + return (error); +} + +/* + * Handle our generic '\0' terminated 'C' string. + * Two cases: + * a variable string: point arg1 at it, arg2 is max length. + * a constant string: point arg1 at it, arg2 is zero. + */ + +int +sysctl_handle_string(SYSCTL_HANDLER_ARGS) +{ + int error=0; + + error = SYSCTL_OUT(req, arg1, strlen((char *)arg1)+1); + + if (error || !req->newptr) + return (error); + + if ((req->newlen - req->newidx) >= arg2) { + error = EINVAL; + } else { + arg2 = (req->newlen - req->newidx); + error = SYSCTL_IN(req, arg1, arg2); + ((char *)arg1)[arg2] = '\0'; + } + + return (error); +} + +/* + * Handle any kind of opaque data. + * arg1 points to it, arg2 is the size. + */ + +int +sysctl_handle_opaque(SYSCTL_HANDLER_ARGS) +{ + int error; + + error = SYSCTL_OUT(req, arg1, arg2); + + if (error || !req->newptr) + return (error); + + error = SYSCTL_IN(req, arg1, arg2); + + return (error); +} + +/* + * Transfer function to/from user space. + */ +static int +sysctl_old_user(struct sysctl_req *req, const void *p, size_t l) +{ + int error = 0; + size_t i = 0; + + if (req->oldptr) { + i = l; + if (i > req->oldlen - req->oldidx) + i = req->oldlen - req->oldidx; + if (i > 0) + error = copyout(p, (char *)req->oldptr + req->oldidx, + i); + } + req->oldidx += l; + if (error) + return (error); + if (req->oldptr && i < l) + return (ENOMEM); + return (0); +} + +static int +sysctl_new_user(struct sysctl_req *req, void *p, size_t l) +{ + int error; + + if (!req->newptr) + return 0; + if (req->newlen - req->newidx < l) + return (EINVAL); + error = copyin((char *)req->newptr + req->newidx, p, l); + req->newidx += l; + return (error); +} + +int +sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid, + int *nindx, struct sysctl_req *req) +{ + struct sysctl_oid *oid; + int indx; + + oid = SLIST_FIRST(&sysctl__children); + indx = 0; + while (oid && indx < CTL_MAXNAME) { + if (oid->oid_number == name[indx]) { + indx++; + if (oid->oid_kind & CTLFLAG_NOLOCK) + req->lock = 0; + if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { + if (oid->oid_handler != NULL || + indx == namelen) { + *noid = oid; + if (nindx != NULL) + *nindx = indx; + return (0); + } + oid = SLIST_FIRST( + (struct sysctl_oid_list *)oid->oid_arg1); + } else if (indx == namelen) { + *noid = oid; + if (nindx != NULL) + *nindx = indx; + return (0); + } else { + return (ENOTDIR); + } + } else { + oid = SLIST_NEXT(oid, oid_link); + } + } + return (ENOENT); +} + +/* + * Traverse our tree, and find the right node, execute whatever it points + * to, and return the resulting error code. + */ + +int +sysctl_root(SYSCTL_HANDLER_ARGS) +{ + struct sysctl_oid *oid; + int error, indx; + + error = sysctl_find_oid(arg1, arg2, &oid, &indx, req); + if (error) + return (error); + + if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { + /* + * You can't call a sysctl when it's a node, but has + * no handler. Inform the user that it's a node. + * The indx may or may not be the same as namelen. + */ + if (oid->oid_handler == NULL) + return (EISDIR); + } + + /* If writing isn't allowed */ + if (req->newptr && (!(oid->oid_kind & CTLFLAG_WR))) + return (EPERM); + + if (!oid->oid_handler) + return EINVAL; + + if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) + error = oid->oid_handler(oid, (int *)arg1 + indx, arg2 - indx, + req); + else + error = oid->oid_handler(oid, oid->oid_arg1, oid->oid_arg2, + req); + return (error); +} + +#ifndef _SYS_SYSPROTO_H_ +struct sysctl_args { + int *name; + u_int namelen; + void *old; + size_t *oldlenp; + void *new; + size_t newlen; +}; +#endif + +int +sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen) +{ + int error = 0; + struct sysctl_req req, req2; + int retval; + + if (!mutex_init) { + cyg_mutex_init(&mutex); + } + + bzero(&req, sizeof req); + + if (oldlenp) { + req.oldlen = *oldlenp; + } + + if (old) { + req.oldptr= old; + } + + if (new != NULL) { + req.newlen = newlen; + req.newptr = new; + } + + req.oldfunc = sysctl_old_user; + req.newfunc = sysctl_new_user; + req.lock = 1; + + cyg_mutex_lock(&mutex); + + do { + req2 = req; + error = sysctl_root(0, name, namelen, &req2); + } while (error == EAGAIN); + + req = req2; + + cyg_mutex_unlock(&mutex); + + if (error && error != ENOMEM) { + errno = error; + return -1; + } + + if (req.oldptr && req.oldidx > req.oldlen) + retval = req.oldlen; + else + retval = req.oldidx; + + return retval; +} + +/* name2oid modify the name passed to it. So we have to make a local copy */ +int sysctlnametomib(const char * name, int *mibp, size_t *sizep) +{ + int error = 0, oid[CTL_MAXNAME], len; + char *namep; + + len = strlen(name); + namep = malloc(len+1,M_SYSCTLOID, M_WAITOK); + strcpy(namep, name); + + error = name2oid(namep, oid, &len, NULL); + free(namep,M_SYSCTLOID); + + if (len * sizeof(int) > *sizep) { + error = ENOMEM; + } + + if (error) { + errno = error; + return -1; + } + + memcpy(mibp, oid, len * sizeof(int)); + *sizep = len; + return 0; +} + +int sysctlbyname(const char * name,void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int oid[CTL_MAXNAME]; + size_t sizep = sizeof(oid); + + if (sysctlnametomib(name, oid, &sizep) != -1) { + return (sysctl(oid, sizep, oldp, oldlenp, newp, newlen)); + } + + return -1; +} +
--- a/packages/net/bsd_tcpip/current/src/sys/net/if.c +++ b/packages/net/bsd_tcpip/current/src/sys/net/if.c @@ -62,6 +62,7 @@ #include <sys/socketvar.h> #include <sys/protosw.h> #include <sys/sockio.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/if_arp.h> @@ -1727,3 +1728,6 @@ ifmaof_ifpforaddr(sa, ifp) return ifma; } + +SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers"); +SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");
--- a/packages/net/bsd_tcpip/current/src/sys/net/rtsock.c +++ b/packages/net/bsd_tcpip/current/src/sys/net/rtsock.c @@ -57,6 +57,7 @@ #include <sys/param.h> +#include <sys/sysctl.h> #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -85,6 +86,10 @@ static struct mbuf * static int rt_msg2 __P((int, struct rt_addrinfo *, caddr_t, struct walkarg *)); static int rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *)); +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +static int sysctl_dumpentry __P((struct radix_node *rn, void *vw)); +static int sysctl_iflist __P((int af, struct walkarg *w)); +#endif static int route_output __P((struct mbuf *, struct socket *)); static void rt_setmetrics __P((u_long, struct rt_metrics *, struct rt_metrics *)); @@ -873,6 +878,144 @@ rt_newmaddrmsg(cmd, ifma) raw_input(m, &route_proto, &route_src, &route_dst); } +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +/* + * This is used in dumping the kernel table via sysctl(). + */ +int +sysctl_dumpentry(rn, vw) + struct radix_node *rn; + void *vw; +{ + register struct walkarg *w = vw; + register struct rtentry *rt = (struct rtentry *)rn; + int error = 0, size; + struct rt_addrinfo info; + + if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) + return 0; + bzero((caddr_t)&info, sizeof(info)); + dst = rt_key(rt); + gate = rt->rt_gateway; + netmask = rt_mask(rt); + genmask = rt->rt_genmask; + size = rt_msg2(RTM_GET, &info, 0, w); + if (w->w_req && w->w_tmem) { + register struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; + + rtm->rtm_flags = rt->rt_flags; + rtm->rtm_use = rt->rt_use; + rtm->rtm_rmx = rt->rt_rmx; + rtm->rtm_index = rt->rt_ifp->if_index; + rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; + rtm->rtm_addrs = info.rti_addrs; + error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size); + return (error); + } + return (error); +} + +int +sysctl_iflist(af, w) + int af; + register struct walkarg *w; +{ + register struct ifnet *ifp; + register struct ifaddr *ifa; + struct rt_addrinfo info; + int len, error = 0; + + bzero((caddr_t)&info, sizeof(info)); + for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) { + if (w->w_arg && w->w_arg != ifp->if_index) + continue; + ifa = ifp->if_addrhead.tqh_first; + ifpaddr = ifa->ifa_addr; + len = rt_msg2(RTM_IFINFO, &info, (caddr_t)0, w); + ifpaddr = 0; + if (w->w_req && w->w_tmem) { + register struct if_msghdr *ifm; + + ifm = (struct if_msghdr *)w->w_tmem; + ifm->ifm_index = ifp->if_index; + ifm->ifm_flags = (u_short)ifp->if_flags; + ifm->ifm_data = ifp->if_data; + ifm->ifm_addrs = info.rti_addrs; + error = SYSCTL_OUT(w->w_req,(caddr_t)ifm, len); + if (error) + return (error); + } + while ((ifa = ifa->ifa_link.tqe_next) != 0) { + if (af && af != ifa->ifa_addr->sa_family) + continue; + ifaaddr = ifa->ifa_addr; + netmask = ifa->ifa_netmask; + brdaddr = ifa->ifa_dstaddr; + len = rt_msg2(RTM_NEWADDR, &info, 0, w); + if (w->w_req && w->w_tmem) { + register struct ifa_msghdr *ifam; + + ifam = (struct ifa_msghdr *)w->w_tmem; + ifam->ifam_index = ifa->ifa_ifp->if_index; + ifam->ifam_flags = ifa->ifa_flags; + ifam->ifam_metric = ifa->ifa_metric; + ifam->ifam_addrs = info.rti_addrs; + error = SYSCTL_OUT(w->w_req, w->w_tmem, len); + if (error) + return (error); + } + } + ifaaddr = netmask = brdaddr = 0; + } + return (0); +} + +static int +sysctl_rtsock(SYSCTL_HANDLER_ARGS) +{ + int *name = (int *)arg1; + u_int namelen = arg2; + register struct radix_node_head *rnh; + int i, s, error = EINVAL; + u_char af; + struct walkarg w; + + name ++; + namelen--; + if (req->newptr) + return (EPERM); + if (namelen != 3) + return (EINVAL); + af = name[0]; + Bzero(&w, sizeof(w)); + w.w_op = name[1]; + w.w_arg = name[2]; + w.w_req = req; + + s = splnet(); + switch (w.w_op) { + + case NET_RT_DUMP: + case NET_RT_FLAGS: + for (i = 1; i <= AF_MAX; i++) + if ((rnh = rt_tables[i]) && (af == 0 || af == i) && + (error = rnh->rnh_walktree(rnh, + sysctl_dumpentry, &w))) + break; + break; + + case NET_RT_IFLIST: + error = sysctl_iflist(af, &w); + } + splx(s); + if (w.w_tmem) + free(w.w_tmem, M_RTABLE); + return (error); +} +#endif + +SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD, sysctl_rtsock, ""); + /* * Definitions of protocols supported in the ROUTE domain. */
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/if_ether.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/if_ether.c @@ -63,6 +63,7 @@ #include <sys/param.h> #include <sys/queue.h> +#include <sys/sysctl.h> #include <sys/mbuf.h> #include <sys/malloc.h> #include <sys/socket.h> @@ -87,11 +88,21 @@ #define SIN(s) ((struct sockaddr_in *)s) #define SDL(s) ((struct sockaddr_dl *)s) +SYSCTL_DECL(_net_link_ether); +SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, ""); + /* timer values */ static int arpt_prune = (5*60*1); /* walk list every 5 minutes */ static int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */ static int arpt_down = 20; /* once declared down, don't send for 20 sec */ +SYSCTL_INT(_net_link_ether_inet, OID_AUTO, prune_intvl, CTLFLAG_RW, + &arpt_prune, 0, ""); +SYSCTL_INT(_net_link_ether_inet, OID_AUTO, max_age, CTLFLAG_RW, + &arpt_keep, 0, ""); +SYSCTL_INT(_net_link_ether_inet, OID_AUTO, host_down_time, CTLFLAG_RW, + &arpt_down, 0, ""); + #define rt_expire rt_rmx.rmx_expire struct llinfo_arp { @@ -111,6 +122,13 @@ static int arp_maxtries = 5; static int useloopback = 1; /* use loopback interface for local traffic */ static int arp_proxyall = 0; +SYSCTL_INT(_net_link_ether_inet, OID_AUTO, maxtries, CTLFLAG_RW, + &arp_maxtries, 0, ""); +SYSCTL_INT(_net_link_ether_inet, OID_AUTO, useloopback, CTLFLAG_RW, + &useloopback, 0, ""); +SYSCTL_INT(_net_link_ether_inet, OID_AUTO, proxyall, CTLFLAG_RW, + &arp_proxyall, 0, ""); + static void arp_rtrequest __P((int, struct rtentry *, struct sockaddr *)); static void arprequest __P((struct arpcom *, struct in_addr *, struct in_addr *, u_char *)); @@ -503,9 +521,9 @@ arpintr() */ static int log_arp_wrong_iface = 1; -//SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_wrong_iface, CTLFLAG_RW, -// &log_arp_wrong_iface, 0, -// "log arp packets arriving on the wrong interface"); +SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_wrong_iface, CTLFLAG_RW, + &log_arp_wrong_iface, 0, + "log arp packets arriving on the wrong interface"); static void in_arpinput(m)
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/igmp.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/igmp.c @@ -75,6 +75,7 @@ #include <sys/mbuf.h> #include <sys/socket.h> #include <sys/protosw.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/route.h> @@ -92,6 +93,9 @@ static struct router_info * static struct igmpstat igmpstat; +SYSCTL_STRUCT(_net_inet_igmp, IGMPCTL_STATS, stats, CTLFLAG_RD, + &igmpstat, igmpstat, ""); + static int igmp_timers_are_running; static u_long igmp_all_hosts_group; static u_long igmp_all_rtrs_group;
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/in.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/in.c @@ -59,6 +59,7 @@ #include <sys/sockio.h> #include <sys/malloc.h> #include <sys/socket.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/if_types.h> @@ -80,6 +81,8 @@ static int in_ifinit __P((struct ifnet * struct in_ifaddr *, struct sockaddr_in *, int)); static int subnetsarelocal = 0; +SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW, + &subnetsarelocal, 0, ""); struct in_multihead in_multihead; /* XXX BSS initialization */
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/in_pcb.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/in_pcb.c @@ -62,6 +62,7 @@ #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/if_types.h> @@ -94,6 +95,43 @@ int ipport_lastauto = IPPORT_USERRESERV int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 49152 */ int ipport_hilastauto = IPPORT_HILASTAUTO; /* 65535 */ +#define RANGECHK(var, min, max) \ + if ((var) < (min)) { (var) = (min); } \ + else if ((var) > (max)) { (var) = (max); } + +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +static int +sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS) +{ + int error = sysctl_handle_int(oidp, + oidp->oid_arg1, oidp->oid_arg2, req); + if (!error) { + RANGECHK(ipport_lowfirstauto, 1, IPPORT_RESERVED - 1); + RANGECHK(ipport_lowlastauto, 1, IPPORT_RESERVED - 1); + RANGECHK(ipport_firstauto, IPPORT_RESERVED, USHRT_MAX); + RANGECHK(ipport_lastauto, IPPORT_RESERVED, USHRT_MAX); + RANGECHK(ipport_hifirstauto, IPPORT_RESERVED, USHRT_MAX); + RANGECHK(ipport_hilastauto, IPPORT_RESERVED, USHRT_MAX); + } + return error; +} +#endif +#undef RANGECHK + +SYSCTL_NODE(_net_inet_ip, IPPROTO_IP, portrange, CTLFLAG_RW, 0, "IP Ports"); + +SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowfirst, CTLTYPE_INT|CTLFLAG_RW, + &ipport_lowfirstauto, 0, &sysctl_net_ipport_check, "I", ""); +SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowlast, CTLTYPE_INT|CTLFLAG_RW, + &ipport_lowlastauto, 0, &sysctl_net_ipport_check, "I", ""); +SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, first, CTLTYPE_INT|CTLFLAG_RW, + &ipport_firstauto, 0, &sysctl_net_ipport_check, "I", ""); +SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, last, CTLTYPE_INT|CTLFLAG_RW, + &ipport_lastauto, 0, &sysctl_net_ipport_check, "I", ""); +SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hifirst, CTLTYPE_INT|CTLFLAG_RW, + &ipport_hifirstauto, 0, &sysctl_net_ipport_check, "I", ""); +SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hilast, CTLTYPE_INT|CTLFLAG_RW, + &ipport_hilastauto, 0, &sysctl_net_ipport_check, "I", ""); /* * in_pcb.c: manage the Protocol Control Blocks.
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/in_proto.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/in_proto.c @@ -60,6 +60,7 @@ #include <sys/domain.h> #include <sys/protosw.h> #include <sys/queue.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/route.h> @@ -239,3 +240,20 @@ struct domain inetdomain = }; DOMAIN_SET(inet); + +SYSCTL_NODE(_net, PF_INET, inet, CTLFLAG_RW, 0, + "Internet Family"); + +SYSCTL_NODE(_net_inet, IPPROTO_IP, ip, CTLFLAG_RW, 0, "IP"); +SYSCTL_NODE(_net_inet, IPPROTO_ICMP, icmp, CTLFLAG_RW, 0, "ICMP"); +SYSCTL_NODE(_net_inet, IPPROTO_UDP, udp, CTLFLAG_RW, 0, "UDP"); +SYSCTL_NODE(_net_inet, IPPROTO_TCP, tcp, CTLFLAG_RW, 0, "TCP"); +SYSCTL_NODE(_net_inet, IPPROTO_IGMP, igmp, CTLFLAG_RW, 0, "IGMP"); +#ifdef IPSEC +SYSCTL_NODE(_net_inet, IPPROTO_AH, ipsec, CTLFLAG_RW, 0, "IPSEC"); +#endif /* IPSEC */ +SYSCTL_NODE(_net_inet, IPPROTO_RAW, raw, CTLFLAG_RW, 0, "RAW"); +#ifdef IPDIVERT +SYSCTL_NODE(_net_inet, IPPROTO_DIVERT, divert, CTLFLAG_RW, 0, "DIVERT"); +#endif +
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/in_rmx.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/in_rmx.c @@ -64,6 +64,7 @@ */ #include <sys/param.h> +#include <sys/sysctl.h> #include <sys/socket.h> #include <sys/mbuf.h> @@ -179,10 +180,20 @@ in_matroute(void *v_arg, struct radix_no static int rtq_reallyold = 60*60; /* one hour is ``really old'' */ +SYSCTL_INT(_net_inet_ip, IPCTL_RTEXPIRE, rtexpire, CTLFLAG_RW, + &rtq_reallyold , 0, + "Default expiration time on dynamically learned routes"); + static int rtq_minreallyold = 10; /* never automatically crank down to less */ +SYSCTL_INT(_net_inet_ip, IPCTL_RTMINEXPIRE, rtminexpire, CTLFLAG_RW, + &rtq_minreallyold , 0, + "Minimum time to attempt to hold onto dynamically learned routes"); + static int rtq_toomany = 128; - /* 128 cached routes is ``too many'' */ + /* 128 cached routes is ``too many'' */ +SYSCTL_INT(_net_inet_ip, IPCTL_RTMAXCACHE, rtmaxcache, CTLFLAG_RW, + &rtq_toomany , 0, "Upper limit on dynamically learned routes"); /* * On last reference drop, mark the route as belong to us so that it can be
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/ip_flow.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/ip_flow.c @@ -63,6 +63,8 @@ #include <sys/protosw.h> #include <sys/socket.h> +#include <sys/sysctl.h> + #include <net/if.h> #include <net/route.h> @@ -81,6 +83,8 @@ static int ipflow_inuse; #define IPFLOW_MAX 256 static int ipflow_active = 0; +SYSCTL_INT(_net_inet_ip, IPCTL_FASTFORWARDING, fastforwarding, CTLFLAG_RW, + &ipflow_active, 0, "Enable flow-based IP forwarding"); static unsigned ipflow_hash(
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/ip_icmp.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/ip_icmp.c @@ -59,6 +59,7 @@ #include <sys/mbuf.h> #include <sys/protosw.h> #include <sys/socket.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/route.h> @@ -83,10 +84,21 @@ * host table maintenance routines. */ -struct icmpstat icmpstat; +struct icmpstat icmpstat; +SYSCTL_STRUCT(_net_inet_icmp, ICMPCTL_STATS, stats, CTLFLAG_RD, + &icmpstat, icmpstat, ""); + static int icmpmaskrepl = 0; +SYSCTL_INT(_net_inet_icmp, ICMPCTL_MASKREPL, maskrepl, CTLFLAG_RW, + &icmpmaskrepl, 0, ""); + static int drop_redirect = 0; +SYSCTL_INT(_net_inet_icmp, OID_AUTO, drop_redirect, CTLFLAG_RW, + &drop_redirect, 0, ""); + static int log_redirect = 0; +SYSCTL_INT(_net_inet_icmp, OID_AUTO, log_redirect, CTLFLAG_RW, + &log_redirect, 0, ""); #ifdef ICMP_BANDLIM @@ -96,17 +108,24 @@ static int log_redirect = 0; */ static int icmplim = 200; +SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_RW, + &icmplim, 0, ""); #else -/* static int icmplim = -1; */ - -#endif - +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +static int icmplim = -1; +SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_RD, + &icmplim, 0, ""); +#endif +#endif /* * ICMP broadcast echo sysctl */ static int icmpbmcastecho = 0; +SYSCTL_INT(_net_inet_icmp, OID_AUTO, bmcastecho, CTLFLAG_RW, + &icmpbmcastecho, 0, ""); + #ifdef ICMPPRINTFS int icmpprintfs = 0;
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/ip_input.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/ip_input.c @@ -63,6 +63,7 @@ #include <sys/domain.h> #include <sys/protosw.h> #include <sys/socket.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/if_var.h> @@ -97,13 +98,41 @@ static int ip_rsvp_on; struct socket *ip_rsvpd; int ipforwarding = 0; +SYSCTL_INT(_net_inet_ip, IPCTL_FORWARDING, forwarding, CTLFLAG_RW, + &ipforwarding, 0, "Enable IP forwarding between interfaces"); + static int ipsendredirects = 1; /* XXX */ +SYSCTL_INT(_net_inet_ip, IPCTL_SENDREDIRECTS, redirect, CTLFLAG_RW, + &ipsendredirects, 0, "Enable sending IP redirects"); + int ip_defttl = IPDEFTTL; +SYSCTL_INT(_net_inet_ip, IPCTL_DEFTTL, ttl, CTLFLAG_RW, + &ip_defttl, 0, "Maximum TTL on IP packets"); + static int ip_dosourceroute = 0; +SYSCTL_INT(_net_inet_ip, IPCTL_SOURCEROUTE, sourceroute, CTLFLAG_RW, + &ip_dosourceroute, 0, "Enable forwarding source routed IP packets"); + static int ip_acceptsourceroute = 0; -#if defined(NFAITH) && 0 < NFAITH +SYSCTL_INT(_net_inet_ip, IPCTL_ACCEPTSOURCEROUTE, accept_sourceroute, + CTLFLAG_RW, &ip_acceptsourceroute, 0, + "Enable accepting source routed IP packets"); + +#if defined(NFAITH) && 0 < NFAITH || defined(CYGPKG_NET_FREEBSD_SYSCTL) static int ip_keepfaith = 0; #endif + +SYSCTL_INT(_net_inet_ip, IPCTL_KEEPFAITH, keepfaith, CTLFLAG_RW, + &ip_keepfaith, 0, + "Enable packet capture for FAITH IPv4->IPv6 translater daemon"); + +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +static int ip_maxfragpackets; /* initialized in ip_init() */ +#endif +SYSCTL_INT(_net_inet_ip, OID_AUTO, maxfragpackets, CTLFLAG_RW, + &ip_maxfragpackets, 0, + "Maximum number of IPv4 fragment reassembly queue entries"); + static int nipq = 0; /* total # of reass queues */ static int maxnipq; @@ -121,6 +150,8 @@ static int maxnipq; * packets for those addresses are received. */ static int ip_checkinterface = 0; +SYSCTL_INT(_net_inet_ip, OID_AUTO, check_interface, CTLFLAG_RW, + &ip_checkinterface, 0, "Verify packet arrives on correct interface"); #ifdef DIAGNOSTIC static int ipprintfs = 0; @@ -131,7 +162,14 @@ extern struct protosw inetsw[]; u_char ip_protox[IPPROTO_MAX]; static int ipqmaxlen = IFQ_MAXLEN; struct in_ifaddrhead in_ifaddrhead; /* first inet address */ +SYSCTL_INT(_net_inet_ip, IPCTL_INTRQMAXLEN, intr_queue_maxlen, CTLFLAG_RW, + &ipintrq.ifq_maxlen, 0, "Maximum size of the IP input queue"); +SYSCTL_INT(_net_inet_ip, IPCTL_INTRQDROPS, intr_queue_drops, CTLFLAG_RD, + &ipintrq.ifq_drops, 0, "Number of packets dropped from the IP input queue"); + struct ipstat ipstat; +SYSCTL_STRUCT(_net_inet_ip, IPCTL_STATS, stats, CTLFLAG_RD, + &ipstat, ipstat, "IP statistics (struct ipstat, netinet/ip_var.h)"); /* Packet reassembly stuff */ #define IPREASS_NHASH_LOG2 6 @@ -143,8 +181,15 @@ struct ipstat ipstat; static struct ipq ipq[IPREASS_NHASH]; const int ipintrq_present = 1; +#ifdef IPCTL_DEFMTU +SYSCTL_INT(_net_inet_ip, IPCTL_DEFMTU, mtu, CTLFLAG_RW, + &ip_mtu, 0, "Default MTU"); +#endif + #ifdef IPSTEALTH static int ipstealth = 0; +SYSCTL_INT(_net_inet_ip, OID_AUTO, stealth, CTLFLAG_RW, + &ipstealth, 0, ""); #endif
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/raw_ip.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/raw_ip.c @@ -61,6 +61,7 @@ #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/route.h> @@ -468,6 +469,11 @@ rip_ctlinput(cmd, sa, vip) u_long rip_sendspace = RIPSNDQ; u_long rip_recvspace = RIPRCVQ; +SYSCTL_INT(_net_inet_raw, OID_AUTO, maxdgram, CTLFLAG_RW, + &rip_sendspace, 0, "Maximum outgoing raw IP datagram size"); +SYSCTL_INT(_net_inet_raw, OID_AUTO, recvspace, CTLFLAG_RW, + &rip_recvspace, 0, "Maximum incoming raw IP datagram size"); + static int rip_attach(struct socket *so, int proto, struct proc *p) { @@ -591,6 +597,94 @@ rip_send(struct socket *so, int flags, s return rip_output(m, so, dst); } +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +static int +rip_pcblist(SYSCTL_HANDLER_ARGS) +{ + int error, i, n, s; + struct inpcb *inp, **inp_list; + inp_gen_t gencnt; + struct xinpgen xig; + + /* + * The process of preparing the TCB list is too time-consuming and + * resource-intensive to repeat twice on every request. + */ + if (req->oldptr == 0) { + n = ripcbinfo.ipi_count; + req->oldidx = 2 * (sizeof xig) + + (n + n/8) * sizeof(struct xinpcb); + return 0; + } + + if (req->newptr != 0) + return EPERM; + + /* + * OK, now we're committed to doing something. + */ + s = splnet(); + gencnt = ripcbinfo.ipi_gencnt; + n = ripcbinfo.ipi_count; + splx(s); + + xig.xig_len = sizeof xig; + xig.xig_count = n; + xig.xig_gen = gencnt; + xig.xig_sogen = so_gencnt; + error = SYSCTL_OUT(req, &xig, sizeof xig); + if (error) + return error; + + inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK); + if (inp_list == 0) + return ENOMEM; + + s = splnet(); + for (inp = ripcbinfo.listhead->lh_first, i = 0; inp && i < n; + inp = inp->inp_list.le_next) { + if (inp->inp_gencnt <= gencnt) + inp_list[i++] = inp; + } + splx(s); + n = i; + + error = 0; + for (i = 0; i < n; i++) { + inp = inp_list[i]; + if (inp->inp_gencnt <= gencnt) { + struct xinpcb xi; + xi.xi_len = sizeof xi; + /* XXX should avoid extra copy */ + bcopy(inp, &xi.xi_inp, sizeof *inp); + if (inp->inp_socket) + sotoxsocket(inp->inp_socket, &xi.xi_socket); + error = SYSCTL_OUT(req, &xi, sizeof xi); + } + } + if (!error) { + /* + * Give the user an updated idea of our state. + * If the generation differs from what we told + * her before, she knows that something happened + * while we were processing this request, and it + * might be necessary to retry. + */ + s = splnet(); + xig.xig_gen = ripcbinfo.ipi_gencnt; + xig.xig_sogen = so_gencnt; + xig.xig_count = ripcbinfo.ipi_count; + splx(s); + error = SYSCTL_OUT(req, &xig, sizeof xig); + } + free(inp_list, M_TEMP); + return error; +} +#endif + +SYSCTL_PROC(_net_inet_raw, OID_AUTO/*XXX*/, pcblist, CTLFLAG_RD, 0, 0, + rip_pcblist, "S,xinpcb", "List of active raw IP sockets"); + struct pr_usrreqs rip_usrreqs = { rip_abort, pru_accept_notsupp, rip_attach, rip_bind, rip_connect, pru_connect2_notsupp, in_control, rip_detach, rip_disconnect,
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/tcp_input.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/tcp_input.c @@ -60,6 +60,7 @@ #include <sys/mbuf.h> #include <sys/protosw.h> #include <sys/socket.h> +#include <sys/sysctl.h> #include <sys/socketvar.h> #include <net/if.h> @@ -85,6 +86,7 @@ #include <netinet/tcp_seq.h> #include <netinet/tcp_timer.h> #include <netinet/tcp_var.h> + #ifdef INET6 #include <netinet6/tcp6_var.h> #endif @@ -105,13 +107,31 @@ static int tcprexmtthresh = 3; tcp_cc tcp_ccgen; struct tcpstat tcpstat; +SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RD, + &tcpstat , tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)"); + static int log_in_vain = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_RW, + &log_in_vain, 0, "Log all incoming TCP connections"); + static int blackhole = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, blackhole, CTLFLAG_RW, + &blackhole, 0, "Do not send RST when dropping refused connections"); + int tcp_delack_enabled = 1; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_RW, + &tcp_delack_enabled, 0, + "Delay ACK to try and piggyback it onto a data packet"); + int tcp_lq_overflow = 1; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_lq_overflow, CTLFLAG_RW, + &tcp_lq_overflow, 0, + "Listen Queue Overflow"); #ifdef TCP_DROP_SYNFIN static int drop_synfin = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_RW, + &drop_synfin, 0, "Drop TCP packets with SYN+FIN set"); #endif struct inpcbhead tcb;
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/tcp_output.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/tcp_output.c @@ -56,6 +56,7 @@ */ #include <sys/param.h> +#include <sys/sysctl.h> #include <sys/mbuf.h> #include <sys/domain.h> #include <sys/protosw.h> @@ -94,10 +95,20 @@ extern struct mbuf *m_copypack(); #endif static int path_mtu_discovery = 1; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, path_mtu_discovery, CTLFLAG_RW, + &path_mtu_discovery, 1, "Enable Path MTU Discovery"); + int ss_fltsz = 1; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, slowstart_flightsize, CTLFLAG_RW, + &ss_fltsz, 1, "Slow start flight size"); + int ss_fltsz_local = TCP_MAXWIN; /* something large */ +SYSCTL_INT(_net_inet_tcp, OID_AUTO, local_slowstart_flightsize, CTLFLAG_RW, + &ss_fltsz_local, 1, "Slow start flight size for local networks"); + int tcp_do_newreno = 1; - +SYSCTL_INT(_net_inet_tcp, OID_AUTO, newreno, CTLFLAG_RW, &tcp_do_newreno, + 0, "Enable NewReno Algorithms"); /* * Tcp output routine: figure out what should be sent and send it. */
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/tcp_subr.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/tcp_subr.c @@ -57,6 +57,7 @@ #include <sys/param.h> #include <sys/malloc.h> +#include <sys/sysctl.h> #include <sys/mbuf.h> #ifdef INET6 #include <sys/domain.h> @@ -105,22 +106,53 @@ #include <sys/md5.h> int tcp_mssdflt = TCP_MSS; +SYSCTL_INT(_net_inet_tcp, TCPCTL_MSSDFLT, mssdflt, CTLFLAG_RW, + &tcp_mssdflt , 0, "Default TCP Maximum Segment Size"); #ifdef INET6 int tcp_v6mssdflt = TCP6_MSS; +SYSCTL_INT(_net_inet_tcp, TCPCTL_V6MSSDFLT, v6mssdflt, + CTLFLAG_RW, &tcp_v6mssdflt , 0, + "Default TCP Maximum Segment Size for IPv6"); #endif #if 0 static int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ; +SYSCTL_INT(_net_inet_tcp, TCPCTL_RTTDFLT, rttdflt, CTLFLAG_RW, + &tcp_rttdflt , 0, "Default maximum TCP Round Trip Time"); #endif static int tcp_do_rfc1323 = 1; +SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1323, rfc1323, CTLFLAG_RW, + &tcp_do_rfc1323 , 0, "Enable rfc1323 (high performance TCP) extensions"); + static int tcp_do_rfc1644 = 0; +SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1644, rfc1644, CTLFLAG_RW, + &tcp_do_rfc1644 , 0, "Enable rfc1644 (TTCP) extensions"); + static int tcp_tcbhashsize = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RD, + &tcp_tcbhashsize, 0, "Size of TCP control-block hashtable"); + static int do_tcpdrain = 1; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_tcpdrain, CTLFLAG_RW, &do_tcpdrain, 0, + "Enable tcp_drain routine for extra help when low on mbufs"); + +SYSCTL_INT(_net_inet_tcp, OID_AUTO, pcbcount, CTLFLAG_RD, + &tcbinfo.ipi_count, 0, "Number of active PCBs"); + static int icmp_may_rst = 1; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_may_rst, CTLFLAG_RW, &icmp_may_rst, 0, + "Certain ICMP unreachable messages may abort connections in SYN_SENT"); + static int tcp_strict_rfc1948 = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, strict_rfc1948, CTLFLAG_RW, + &tcp_strict_rfc1948, 0, "Determines if RFC1948 is followed exactly"); + static int tcp_isn_reseed_interval = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, isn_reseed_interval, CTLFLAG_RW, + &tcp_isn_reseed_interval, 0, "Seconds between reseeding of ISN secret"); + static void tcp_cleartaocache __P((void)); static void tcp_notify __P((struct inpcb *, int)); @@ -784,6 +816,100 @@ tcp_notify(inp, error) #endif } +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +static int +tcp_pcblist(SYSCTL_HANDLER_ARGS) +{ + int error, i, n, s; + struct inpcb *inp, **inp_list; + inp_gen_t gencnt; + struct xinpgen xig; + + /* + * The process of preparing the TCB list is too time-consuming and + * resource-intensive to repeat twice on every request. + */ + if (req->oldptr == 0) { + n = tcbinfo.ipi_count; + req->oldidx = 2 * (sizeof xig) + + (n + n/8) * sizeof(struct xtcpcb); + return 0; + } + + if (req->newptr != 0) + return EPERM; + + /* + * OK, now we're committed to doing something. + */ + s = splnet(); + gencnt = tcbinfo.ipi_gencnt; + n = tcbinfo.ipi_count; + splx(s); + + xig.xig_len = sizeof xig; + xig.xig_count = n; + xig.xig_gen = gencnt; + xig.xig_sogen = so_gencnt; + error = SYSCTL_OUT(req, &xig, sizeof xig); + if (error) + return error; + + inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK); + if (inp_list == 0) + return ENOMEM; + + s = splnet(); + for (inp = LIST_FIRST(tcbinfo.listhead), i = 0; inp && i < n; + inp = LIST_NEXT(inp, inp_list)) { + if (inp->inp_gencnt <= gencnt) + inp_list[i++] = inp; + } + splx(s); + n = i; + + error = 0; + for (i = 0; i < n; i++) { + inp = inp_list[i]; + if (inp->inp_gencnt <= gencnt) { + struct xtcpcb xt; + caddr_t inp_ppcb; + xt.xt_len = sizeof xt; + /* XXX should avoid extra copy */ + bcopy(inp, &xt.xt_inp, sizeof *inp); + inp_ppcb = inp->inp_ppcb; + if (inp_ppcb != NULL) + bcopy(inp_ppcb, &xt.xt_tp, sizeof xt.xt_tp); + else + bzero((char *) &xt.xt_tp, sizeof xt.xt_tp); + if (inp->inp_socket) + sotoxsocket(inp->inp_socket, &xt.xt_socket); + error = SYSCTL_OUT(req, &xt, sizeof xt); + } + } + if (!error) { + /* + * Give the user an updated idea of our state. + * If the generation differs from what we told + * her before, she knows that something happened + * while we were processing this request, and it + * might be necessary to retry. + */ + s = splnet(); + xig.xig_gen = tcbinfo.ipi_gencnt; + xig.xig_sogen = so_gencnt; + xig.xig_count = tcbinfo.ipi_count; + splx(s); + error = SYSCTL_OUT(req, &xig, sizeof xig); + } + free(inp_list, M_TEMP); + return error; +} +#endif + +SYSCTL_PROC(_net_inet_tcp, TCPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0, + tcp_pcblist, "S,xtcpcb", "List of active TCP connections"); + void tcp_ctlinput(cmd, sa, vip) int cmd;
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/tcp_timer.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/tcp_timer.c @@ -56,6 +56,7 @@ */ #include <sys/param.h> +#include <sys/sysctl.h> #include <sys/mbuf.h> #include <sys/socket.h> #include <sys/socketvar.h> @@ -80,12 +81,52 @@ #include <netinet/tcp_debug.h> #endif +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +static int +sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS) +{ + int error, s, tt; + + tt = *(int *)oidp->oid_arg1; + s = tt * 1000 / hz; + + error = sysctl_handle_int(oidp, &s, 0, req); + if (error || !req->newptr) + return (error); + + tt = s * hz / 1000; + if (tt < 1) + return (EINVAL); + + *(int *)oidp->oid_arg1 = tt; + return (0); +} +#endif int tcp_keepinit; +SYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPINIT, keepinit, CTLTYPE_INT|CTLFLAG_RW, + &tcp_keepinit, 0, sysctl_msec_to_ticks, "I", ""); + int tcp_keepidle; +SYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPIDLE, keepidle, CTLTYPE_INT|CTLFLAG_RW, + &tcp_keepidle, 0, sysctl_msec_to_ticks, "I", ""); + int tcp_keepintvl; +SYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPINTVL, keepintvl, CTLTYPE_INT|CTLFLAG_RW, + &tcp_keepintvl, 0, sysctl_msec_to_ticks, "I", ""); + int tcp_delacktime; +SYSCTL_PROC(_net_inet_tcp, TCPCTL_DELACKTIME, delacktime, + CTLTYPE_INT|CTLFLAG_RW, &tcp_delacktime, 0, sysctl_msec_to_ticks, "I", + "Time before a delayed ACK is sent"); + int tcp_msl; +SYSCTL_PROC(_net_inet_tcp, OID_AUTO, msl, CTLTYPE_INT|CTLFLAG_RW, + &tcp_msl, 0, sysctl_msec_to_ticks, "I", "Maximum segment lifetime"); + static int always_keepalive = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, always_keepalive, CTLFLAG_RW, + &always_keepalive , 0, "Assume SO_KEEPALIVE on all TCP connections"); + static int tcp_keepcnt = TCPTV_KEEPCNT; /* max idle probes */ int tcp_maxpersistidle;
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/tcp_usrreq.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/tcp_usrreq.c @@ -56,6 +56,7 @@ */ #include <sys/param.h> +#include <sys/sysctl.h> #include <sys/mbuf.h> #ifdef INET6 #include <sys/domain.h> @@ -996,7 +997,11 @@ tcp_ctloutput(so, sopt) * be set by the route). */ u_long tcp_sendspace = 1024*16; +SYSCTL_INT(_net_inet_tcp, TCPCTL_SENDSPACE, sendspace, CTLFLAG_RW, + &tcp_sendspace , 0, "Maximum outgoing TCP datagram size"); u_long tcp_recvspace = 1024*16; +SYSCTL_INT(_net_inet_tcp, TCPCTL_RECVSPACE, recvspace, CTLFLAG_RW, + &tcp_recvspace , 0, "Maximum incoming TCP datagram size"); /* * Attach TCP protocol to socket, allocating
--- a/packages/net/bsd_tcpip/current/src/sys/netinet/udp_usrreq.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet/udp_usrreq.c @@ -62,6 +62,7 @@ #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/route.h> @@ -96,9 +97,17 @@ int udpcksum = 1; #else int udpcksum = 0; /* XXX */ #endif +SYSCTL_INT(_net_inet_udp, UDPCTL_CHECKSUM, checksum, CTLFLAG_RW, + &udpcksum, 0, ""); int log_in_vain = 0; +SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_RW, + &log_in_vain, 0, "Log all incoming UDP packets"); + static int blackhole = 0; +SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_RW, + &blackhole, 0, "Do not send port unreachables for refused connects"); + struct inpcbhead udb; /* from udp_var.h */ #define udb6 udb /* for KAME src sync over BSD*'s */ @@ -109,6 +118,9 @@ struct inpcbinfo udbinfo; #endif struct udpstat udpstat; /* from udp_var.h */ +SYSCTL_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RD, + &udpstat, udpstat, "UDP statistics (struct udpstat, netinet/udp_var.h)"); + static struct sockaddr_in udp_in = { sizeof(udp_in), AF_INET }; #ifdef INET6 @@ -558,6 +570,93 @@ udp_ctlinput(cmd, sa, vip) } else in_pcbnotifyall(&udb, faddr, inetctlerrmap[cmd], notify); } +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +static int +udp_pcblist(SYSCTL_HANDLER_ARGS) +{ + int error, i, n, s; + struct inpcb *inp, **inp_list; + inp_gen_t gencnt; + struct xinpgen xig; + + /* + * The process of preparing the TCB list is too time-consuming and + * resource-intensive to repeat twice on every request. + */ + if (req->oldptr == 0) { + n = udbinfo.ipi_count; + req->oldidx = 2 * (sizeof xig) + + (n + n/8) * sizeof(struct xinpcb); + return 0; + } + + if (req->newptr != 0) + return EPERM; + + /* + * OK, now we're committed to doing something. + */ + s = splnet(); + gencnt = udbinfo.ipi_gencnt; + n = udbinfo.ipi_count; + splx(s); + + xig.xig_len = sizeof xig; + xig.xig_count = n; + xig.xig_gen = gencnt; + xig.xig_sogen = so_gencnt; + error = SYSCTL_OUT(req, &xig, sizeof xig); + if (error) + return error; + + inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK); + if (inp_list == 0) + return ENOMEM; + + s = splnet(); + for (inp = LIST_FIRST(udbinfo.listhead), i = 0; inp && i < n; + inp = LIST_NEXT(inp, inp_list)) { + if (inp->inp_gencnt <= gencnt) + inp_list[i++] = inp; + } + splx(s); + n = i; + + error = 0; + for (i = 0; i < n; i++) { + inp = inp_list[i]; + if (inp->inp_gencnt <= gencnt) { + struct xinpcb xi; + xi.xi_len = sizeof xi; + /* XXX should avoid extra copy */ + bcopy(inp, &xi.xi_inp, sizeof *inp); + if (inp->inp_socket) + sotoxsocket(inp->inp_socket, &xi.xi_socket); + error = SYSCTL_OUT(req, &xi, sizeof xi); + } + } + if (!error) { + /* + * Give the user an updated idea of our state. + * If the generation differs from what we told + * her before, she knows that something happened + * while we were processing this request, and it + * might be necessary to retry. + */ + s = splnet(); + xig.xig_gen = udbinfo.ipi_gencnt; + xig.xig_sogen = so_gencnt; + xig.xig_count = udbinfo.ipi_count; + splx(s); + error = SYSCTL_OUT(req, &xig, sizeof xig); + } + free(inp_list, M_TEMP); + return error; +} +#endif + +SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0, + udp_pcblist, "S,xinpcb", "List of active UDP sockets"); static int udp_output(inp, m, addr, control, p) @@ -668,6 +767,9 @@ release: u_long udp_sendspace = 9216; /* really max datagram size */ /* 40 1K datagrams */ +SYSCTL_INT(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW, + &udp_sendspace, 0, "Maximum outgoing UDP datagram size"); + u_long udp_recvspace = 40 * (1024 + #ifdef INET6 sizeof(struct sockaddr_in6) @@ -675,6 +777,8 @@ u_long udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in) #endif ); +SYSCTL_INT(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW, + &udp_recvspace, 0, "Maximum incoming UDP datagram size"); static int udp_abort(struct socket *so)
--- a/packages/net/bsd_tcpip/current/src/sys/netinet6/in6.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet6/in6.c @@ -894,6 +894,10 @@ in6_control(so, cmd, data, ifp) return(0); } +#ifdef __ECOS +extern void _show_ifp(struct ifnet *ifp); +#endif + /* * Update parameters of an IPv6 interface address. * If necessary, a new entry is created and linked into address chains.
--- a/packages/net/bsd_tcpip/current/src/sys/netinet6/in6_ifattach.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet6/in6_ifattach.c @@ -606,6 +606,10 @@ success: return 0; } +#ifdef __ECOS +extern void _show_ifp(struct ifnet *ifp); +#endif + static int in6_ifattach_linklocal(ifp, altifp) struct ifnet *ifp;
--- a/packages/net/bsd_tcpip/current/src/sys/netinet6/in6_pcb.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet6/in6_pcb.c @@ -748,7 +748,7 @@ in6_pcbnotify(head, dst, fport_arg, src, struct sockaddr_in6 sa6_src, *sa6_dst; u_short fport = fport_arg, lport = lport_arg; u_int32_t flowinfo; - int errno, s; + int _errno, s; if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET6) return; @@ -779,7 +779,7 @@ in6_pcbnotify(head, dst, fport_arg, src, if (cmd != PRC_HOSTDEAD) notify = in6_rtchange; } - errno = inet6ctlerrmap[cmd]; + _errno = inet6ctlerrmap[cmd]; s = splnet(); for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) { ninp = LIST_NEXT(inp, inp_list); @@ -829,7 +829,7 @@ in6_pcbnotify(head, dst, fport_arg, src, do_notify: if (notify) - (*notify)(inp, errno); + (*notify)(inp, _errno); } splx(s); }
--- a/packages/net/bsd_tcpip/current/src/sys/netinet6/in6_proto.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet6/in6_proto.c @@ -91,6 +91,7 @@ #include <sys/protosw.h> #include <sys/domain.h> #include <sys/mbuf.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/radix.h> @@ -279,7 +280,7 @@ struct ip6protosw inet6sw[] = { }, #endif /* TCP6 */ { SOCK_RAW, &inet6domain, IPPROTO_RAW, PR_ATOMIC|PR_ADDR, - rip6_input, rip6_output, rip6_ctlinput, rip6_ctloutput, + rip6_input, rip6_output, rip6_ctlinput, rip6_ctloutput, #if defined(__FreeBSD__) && __FreeBSD__ >= 3 0, #else @@ -637,3 +638,132 @@ int tcp6_roundfrac = TCP6_ROUNDFRAC; int udp6_sendspace = 9216; /* really max datagram size */ int udp6_recvspace = 40 * (1024 + sizeof(struct sockaddr_in6)); /* 40 1K datagrams */ +/* + * sysctl related items. + */ +SYSCTL_NODE(_net, PF_INET6, inet6, CTLFLAG_RW, 0, + "Internet6 Family"); + +/* net.inet6 */ +SYSCTL_NODE(_net_inet6, IPPROTO_IPV6, ip6, CTLFLAG_RW, 0, "IP6"); +SYSCTL_NODE(_net_inet6, IPPROTO_ICMPV6, icmp6, CTLFLAG_RW, 0, "ICMP6"); +SYSCTL_NODE(_net_inet6, IPPROTO_UDP, udp6, CTLFLAG_RW, 0, "UDP6"); +SYSCTL_NODE(_net_inet6, IPPROTO_TCP, tcp6, CTLFLAG_RW, 0, "TCP6"); +#ifdef IPSEC +SYSCTL_NODE(_net_inet6, IPPROTO_ESP, ipsec6, CTLFLAG_RW, 0, "IPSEC6"); +#endif /* IPSEC */ + +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +/* net.inet6.ip6 */ +static int +sysctl_ip6_temppltime(SYSCTL_HANDLER_ARGS) +{ + int error = 0; + int old; + + error = SYSCTL_OUT(req, arg1, sizeof(int)); + if (error || !req->newptr) + return (error); + old = ip6_temp_preferred_lifetime; + error = SYSCTL_IN(req, arg1, sizeof(int)); + if (ip6_temp_preferred_lifetime < + ip6_desync_factor + ip6_temp_regen_advance) { + ip6_temp_preferred_lifetime = old; + return(EINVAL); + } + return(error); +} + +static int +sysctl_ip6_tempvltime(SYSCTL_HANDLER_ARGS) +{ + int error = 0; + int old; + + error = SYSCTL_OUT(req, arg1, sizeof(int)); + if (error || !req->newptr) + return (error); + old = ip6_temp_valid_lifetime; + error = SYSCTL_IN(req, arg1, sizeof(int)); + if (ip6_temp_valid_lifetime < ip6_temp_preferred_lifetime) { + ip6_temp_preferred_lifetime = old; + return(EINVAL); + } + return(error); +} +#endif +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_FORWARDING, + forwarding, CTLFLAG_RW, &ip6_forwarding, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_SENDREDIRECTS, + redirect, CTLFLAG_RW, &ip6_sendredirects, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFHLIM, + hlim, CTLFLAG_RW, &ip6_defhlim, 0, ""); +SYSCTL_STRUCT(_net_inet6_ip6, IPV6CTL_STATS, stats, CTLFLAG_RD, + &ip6stat, ip6stat, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGPACKETS, + maxfragpackets, CTLFLAG_RW, &ip6_maxfragpackets, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_ACCEPT_RTADV, + accept_rtadv, CTLFLAG_RW, &ip6_accept_rtadv, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_KEEPFAITH, + keepfaith, CTLFLAG_RW, &ip6_keepfaith, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_LOG_INTERVAL, + log_interval, CTLFLAG_RW, &ip6_log_interval, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_HDRNESTLIMIT, + hdrnestlimit, CTLFLAG_RW, &ip6_hdrnestlimit, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DAD_COUNT, + dad_count, CTLFLAG_RW, &ip6_dad_count, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_AUTO_FLOWLABEL, + auto_flowlabel, CTLFLAG_RW, &ip6_auto_flowlabel, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFMCASTHLIM, + defmcasthlim, CTLFLAG_RW, &ip6_defmcasthlim, 0, ""); +#ifndef __ECOS /* We don't support gif at the moment */ +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM, + gifhlim, CTLFLAG_RW, &ip6_gif_hlim, 0, ""); +#endif +SYSCTL_STRING(_net_inet6_ip6, IPV6CTL_KAME_VERSION, + kame_version, CTLFLAG_RD, __KAME_VERSION, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_USE_DEPRECATED, + use_deprecated, CTLFLAG_RW, &ip6_use_deprecated, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_RR_PRUNE, + rr_prune, CTLFLAG_RW, &ip6_rr_prune, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_USETEMPADDR, + use_tempaddr, CTLFLAG_RW, &ip6_use_tempaddr, 0, ""); +SYSCTL_OID(_net_inet6_ip6, IPV6CTL_TEMPPLTIME, temppltime, + CTLTYPE_INT|CTLFLAG_RW, &ip6_temp_preferred_lifetime, 0, + sysctl_ip6_temppltime, "I", ""); +SYSCTL_OID(_net_inet6_ip6, IPV6CTL_TEMPVLTIME, tempvltime, + CTLTYPE_INT|CTLFLAG_RW, &ip6_temp_valid_lifetime, 0, + sysctl_ip6_tempvltime, "I", ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_V6ONLY, + v6only, CTLFLAG_RW, &ip6_v6only, 0, ""); +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_AUTO_LINKLOCAL, + auto_linklocal, CTLFLAG_RW, &ip6_auto_linklocal, 0, ""); +SYSCTL_STRUCT(_net_inet6_ip6, IPV6CTL_RIP6STATS, rip6stats, CTLFLAG_RD, + &rip6stat, rip6stat, ""); + +/* net.inet6.icmp6 */ +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRACCEPT, + rediraccept, CTLFLAG_RW, &icmp6_rediraccept, 0, ""); +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRTIMEOUT, + redirtimeout, CTLFLAG_RW, &icmp6_redirtimeout, 0, ""); +SYSCTL_STRUCT(_net_inet6_icmp6, ICMPV6CTL_STATS, stats, CTLFLAG_RD, + &icmp6stat, icmp6stat, ""); +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_PRUNE, + nd6_prune, CTLFLAG_RW, &nd6_prune, 0, ""); +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_DELAY, + nd6_delay, CTLFLAG_RW, &nd6_delay, 0, ""); +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_UMAXTRIES, + nd6_umaxtries, CTLFLAG_RW, &nd6_umaxtries, 0, ""); +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MMAXTRIES, + nd6_mmaxtries, CTLFLAG_RW, &nd6_mmaxtries, 0, ""); +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_USELOOPBACK, + nd6_useloopback, CTLFLAG_RW, &nd6_useloopback, 0, ""); +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_NODEINFO, + nodeinfo, CTLFLAG_RW, &icmp6_nodeinfo, 0, ""); +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ERRPPSLIMIT, + errppslimit, CTLFLAG_RW, &icmp6errppslim, 0, ""); +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXNUDHINT, + nd6_maxnudhint, CTLFLAG_RW, &nd6_maxnudhint, 0, ""); +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_DEBUG, + nd6_debug, CTLFLAG_RW, &nd6_debug, 0, ""); +
--- a/packages/net/bsd_tcpip/current/src/sys/netinet6/in6_rmx.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet6/in6_rmx.c @@ -94,6 +94,7 @@ */ #include <sys/param.h> +#include <sys/sysctl.h> #include <sys/queue.h> #include <sys/socket.h> #include <sys/socketvar.h> @@ -275,12 +276,22 @@ in6_matroute(void *v_arg, struct radix_n return rn; } +SYSCTL_DECL(_net_inet6_ip6); + static int rtq_reallyold = 60*60; /* one hour is ``really old'' */ +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_RTEXPIRE, rtexpire, + CTLFLAG_RW, &rtq_reallyold , 0, ""); + static int rtq_minreallyold = 10; /* never automatically crank down to less */ +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_RTMINEXPIRE, rtminexpire, + CTLFLAG_RW, &rtq_minreallyold , 0, ""); + static int rtq_toomany = 128; /* 128 cached routes is ``too many'' */ +SYSCTL_INT(_net_inet6_ip6, IPV6CTL_RTMAXCACHE, rtmaxcache, + CTLFLAG_RW, &rtq_toomany , 0, ""); /* * On last reference drop, mark the route as belong to us so that it can be
--- a/packages/net/bsd_tcpip/current/src/sys/netinet6/nd6.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet6/nd6.c @@ -66,6 +66,7 @@ #include <sys/protosw.h> #include <sys/errno.h> #include <sys/queue.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/if_dl.h> @@ -2390,3 +2391,133 @@ nd6_storelladdr(ifp, rt, m, dst, desten) bcopy(LLADDR(sdl), desten, sdl->sdl_alen); return(1); } + +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +static int nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS); +static int nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS); +#endif +#ifdef SYSCTL_DECL +SYSCTL_DECL(_net_inet6_icmp6); +#endif +SYSCTL_NODE(_net_inet6_icmp6, ICMPV6CTL_ND6_DRLIST, nd6_drlist, + CTLFLAG_RD, nd6_sysctl_drlist, ""); +SYSCTL_NODE(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist, + CTLFLAG_RD, nd6_sysctl_prlist, ""); + +#ifdef CYGPKG_NET_FREEBSD_SYSCTL +static int +nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS) +{ + int error; + char buf[1024]; + struct in6_defrouter *d, *de; + struct nd_defrouter *dr; + + if (req->newptr) + return EPERM; + error = 0; + + for (dr = TAILQ_FIRST(&nd_defrouter); + dr; + dr = TAILQ_NEXT(dr, dr_entry)) { + d = (struct in6_defrouter *)buf; + de = (struct in6_defrouter *)(buf + sizeof(buf)); + + if (d + 1 <= de) { + bzero(d, sizeof(*d)); + d->rtaddr.sin6_family = AF_INET6; + d->rtaddr.sin6_len = sizeof(d->rtaddr); + if (in6_recoverscope(&d->rtaddr, &dr->rtaddr, + dr->ifp) != 0) + log(LOG_ERR, + "scope error in " + "default router list (%s)\n", + ip6_sprintf(&dr->rtaddr)); + d->flags = dr->flags; + d->rtlifetime = dr->rtlifetime; + d->expire = dr->expire; + d->if_index = dr->ifp->if_index; + } else + panic("buffer too short"); + + error = SYSCTL_OUT(req, buf, sizeof(*d)); + if (error) + break; + } + return error; +} + +static int +nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS) +{ + int error; + char buf[1024]; + struct in6_prefix *p, *pe; + struct nd_prefix *pr; + + if (req->newptr) + return EPERM; + error = 0; + + for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { + u_short advrtrs=0; + size_t advance; + struct sockaddr_in6 *sin6, *s6; + struct nd_pfxrouter *pfr; + + p = (struct in6_prefix *)buf; + pe = (struct in6_prefix *)(buf + sizeof(buf)); + + if (p + 1 <= pe) { + bzero(p, sizeof(*p)); + sin6 = (struct sockaddr_in6 *)(p + 1); + + p->prefix = pr->ndpr_prefix; + if (in6_recoverscope(&p->prefix, + &p->prefix.sin6_addr, pr->ndpr_ifp) != 0) + log(LOG_ERR, + "scope error in prefix list (%s)\n", + ip6_sprintf(&p->prefix.sin6_addr)); + p->raflags = pr->ndpr_raf; + p->prefixlen = pr->ndpr_plen; + p->vltime = pr->ndpr_vltime; + p->pltime = pr->ndpr_pltime; + p->if_index = pr->ndpr_ifp->if_index; + p->expire = pr->ndpr_expire; + p->refcnt = pr->ndpr_refcnt; + p->flags = pr->ndpr_stateflags; + p->origin = PR_ORIG_RA; + advrtrs = 0; + for (pfr = pr->ndpr_advrtrs.lh_first; + pfr; + pfr = pfr->pfr_next) { + if ((void *)&sin6[advrtrs + 1] > + (void *)pe) { + advrtrs++; + continue; + } + s6 = &sin6[advrtrs]; + bzero(s6, sizeof(*s6)); + s6->sin6_family = AF_INET6; + s6->sin6_len = sizeof(*sin6); + if (in6_recoverscope(s6, + &pfr->router->rtaddr, + pfr->router->ifp) != 0) + log(LOG_ERR, + "scope error in " + "prefix list (%s)\n", + ip6_sprintf(&pfr->router->rtaddr)); + advrtrs++; + } + p->advrtrs = advrtrs; + } else + panic("buffer too short"); + + advance = sizeof(*p) + sizeof(*sin6) * advrtrs; + error = SYSCTL_OUT(req, buf, advance); + if (error) + break; + } + return error; +} +#endif
--- a/packages/net/bsd_tcpip/current/src/sys/netinet6/udp6_output.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet6/udp6_output.c @@ -91,6 +91,7 @@ #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> +#include <sys/sysctl.h> #include <sys/errno.h> #include <net/if.h>
--- a/packages/net/bsd_tcpip/current/src/sys/netinet6/udp6_usrreq.c +++ b/packages/net/bsd_tcpip/current/src/sys/netinet6/udp6_usrreq.c @@ -91,6 +91,7 @@ #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> +#include <sys/sysctl.h> #include <sys/errno.h> #include <net/if.h> @@ -717,3 +718,4 @@ struct pr_usrreqs udp6_usrreqs = { pru_rcvoob_notsupp, udp6_send, pru_sense_null, udp_shutdown, in6_mapped_sockaddr, sosend, soreceive, sopoll }; +
new file mode 100644 --- /dev/null +++ b/packages/net/bsd_tcpip/current/tests/sysctl1.c @@ -0,0 +1,217 @@ +//========================================================================== +// +// tests/sysctl1.c +// +// Simple test of sysclt API +// +//========================================================================== +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from FreeBSD or other sources, +// and are covered by the appropriate copyright disclaimers included herein. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): andrew lunn +// Contributors: andrew lunn +// Date: 2003-06-28 +// Purpose: +// Description: +// +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include <network.h> +#include <sys/sysctl.h> + +#include <cyg/infra/testcase.h> +#ifndef NELEM +#define NELEM(x) sizeof(x)/sizeof(*x) +#endif + +#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x1000) +static char stack[STACK_SIZE]; +static cyg_thread thread_data; +static cyg_handle_t thread_handle; + +static int mib_name[] = { CTL_DEBUG, 1 }; +static int mib_next[] = { CTL_DEBUG, 2 }; +static int mib_name2oid[] = { CTL_DEBUG, 3 }; +static int mib_oidfmt[] = { CTL_DEBUG, 4 }; +static int mib_name_debug_name[] = { CTL_DEBUG, 1, CTL_DEBUG, 1 }; +static int mib[10]; +static char name2oid[] = "sysctl.name2oid"; +void +net_test(cyg_addrword_t q) +{ + char oldbuff[128]; + size_t oldbuffsize; + char pbuff[128], name[64], *p; + int *new_oid; + size_t num_elem; + int ret, i, oid_kind; + + diag_printf("Start sysctl1 test\n"); + + // init_all_network_interfaces(); + + /* Test the OID to name function of sysctl*/ + oldbuffsize = sizeof(oldbuff); + ret = sysctl(mib_name_debug_name, NELEM(mib_name_debug_name), + oldbuff, &oldbuffsize, NULL, 0); + if (ret == -1) CYG_TEST_FAIL("sysclt(mib_name) failed"); + CYG_TEST_INFO(oldbuff); + CYG_TEST_PASS_FAIL(!strcmp(oldbuff, "sysctl.name"), "sysctl.name"); + + /* Test the name to OID function of sysclt */ + oldbuffsize = sizeof(oldbuff); + ret = sysctl(mib_name2oid, NELEM(mib_name2oid), oldbuff, &oldbuffsize, + name2oid, sizeof(name2oid)); + if (ret == -1) CYG_TEST_FAIL("sysclt(mib_name) failed"); + CYG_TEST_PASS_FAIL(((ret == 8 ) && + (((int *)&oldbuff)[0] == CTL_DEBUG) && + (((int *)&oldbuff)[1] == 3)), + "sysctl.name2oid"); + + /* Walk the table using the next function of sysclt */ + num_elem = NELEM(mib_next)+1; + new_oid = mib + NELEM(mib_next); + mib[2] = 0; + do { + memcpy(mib,mib_next,sizeof(mib_next)); + oldbuffsize = sizeof(mib) - sizeof(mib_next); + ret = sysctl(mib, num_elem, new_oid, &oldbuffsize, NULL, 0); + if (ret == -1) { + if (errno != ENOENT) { + CYG_TEST_FAIL_FINISH("sysclt(mib_name) failed"); + } else { + break; + } + } + p = pbuff; + num_elem = NELEM(mib_next) + (ret / 4); + i=0; + while (ret > 0) { + p+=diag_sprintf(p, "%d ",new_oid[i++]); + ret -= sizeof(int); + } + /* Get the name of this oid */ + oldbuffsize = sizeof(name); + memcpy(mib,mib_name,sizeof(mib_name)); + ret = sysctl(mib, num_elem, name, &oldbuffsize, NULL, 0); + if (ret == -1) CYG_TEST_FAIL("sysclt(mib2name) failed"); + name[ret] = 0; + p += diag_sprintf(p, "= %s (", name); + + /* Get the find and format */ + memcpy(mib,mib_oidfmt,sizeof(mib_oidfmt)); + ret = sysctl(mib, num_elem, name, &oldbuffsize, NULL, 0); + if (ret == -1) CYG_TEST_FAIL("sysclt(mib2name) failed"); + oid_kind = *(int *)name; + switch (oid_kind & CTLTYPE) { + case CTLTYPE_NODE: + p += diag_sprintf(p, "NODE"); + break; + case CTLTYPE_INT: + p += diag_sprintf(p, "INT"); + break; + case CTLTYPE_STRING: + p += diag_sprintf(p, "STRING"); + break; + case CTLTYPE_QUAD: + p += diag_sprintf(p, "QUAD"); + break; + case CTLTYPE_STRUCT: + p += diag_sprintf(p, "STRUCT"); + break; + case CTLTYPE_UINT: + p += diag_sprintf(p, "UINT"); + break; + case CTLTYPE_LONG: + p += diag_sprintf(p, "LONG"); + break; + case CTLTYPE_ULONG: + p += diag_sprintf(p, "ULONG"); + break; + default: + p += diag_sprintf(p,"Unknown type! (%d)", oid_kind & CTLTYPE); + } + if (oid_kind & CTLFLAG_RD) + p += diag_sprintf(p," Read"); + if (oid_kind & CTLFLAG_WR) + p += diag_sprintf(p," Write"); + if (oid_kind & CTLFLAG_NOLOCK) + p += diag_sprintf(p," Nolock"); + if (oid_kind & CTLFLAG_ANYBODY) + p += diag_sprintf(p," Anybody"); + if (oid_kind & CTLFLAG_SECURE) + p += diag_sprintf(p," Secure"); + if (oid_kind & CTLFLAG_PRISON) + p += diag_sprintf(p," Prison"); + if (oid_kind & CTLFLAG_DYN) + p += diag_sprintf(p," Dynamic"); + + p += diag_sprintf(p," )"); + + p += diag_sprintf(p,"{%d}", num_elem); + CYG_TEST_INFO(pbuff); + } while (ret != -1); + + /* Tests for sysctlnametomib */ + num_elem = NELEM(mib); + ret = sysctlnametomib(name2oid, mib,&num_elem); + if (ret == -1) CYG_TEST_FAIL("sysctlnametomib failed"); + CYG_TEST_PASS_FAIL(((num_elem == 2 ) && + (((int *)&oldbuff)[0] == CTL_DEBUG) && + (((int *)&oldbuff)[1] == 3)), + "sysctlnametooid1"); + + /* This time with to small a results buffer */ + num_elem = 1; + ret = sysctlnametomib(name2oid, mib,&num_elem); + CYG_TEST_PASS_FAIL((ret == -1) && (errno = ENOMEM), + "sysctlnametooid2"); + /* This time with an unknown name */ + num_elem = NELEM(mib); + ret = sysctlnametomib("unknown.unknown", mib,&num_elem); + CYG_TEST_PASS_FAIL((ret == -1) && (errno = ENOENT), + "sysctlnametooid3"); + + /* Tests for sysctlbyname */ + oldbuffsize = sizeof(oldbuff); + ret = sysctlbyname("sysctl.name2oid", oldbuff, &oldbuffsize, + name2oid, sizeof(name2oid)); + if (ret == -1) CYG_TEST_FAIL("sysclt(mib_name) failed"); + CYG_TEST_PASS_FAIL(((ret == 8 ) && + (((int *)&oldbuff)[0] == CTL_DEBUG) && + (((int *)&oldbuff)[1] == 3)), + "sysctlbyname"); +} + +void +cyg_start(void) +{ + CYG_TEST_INIT(); + + // Create a main thread, so we can run the scheduler and have time 'pass' + cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY-4,// Priority - just a number + net_test, // entry + 0, // entry parameter + "Loopback ping test", // Name + &stack[0], // Stack + STACK_SIZE, // Size + &thread_handle, // Handle + &thread_data // Thread data structure + ); + cyg_thread_resume(thread_handle); // Start it + cyg_scheduler_start(); +} +
