diff --git a/Changelog.md b/Changelog.md index e69de29b..a5c72841 100644 --- a/Changelog.md +++ b/Changelog.md @@ -0,0 +1,17 @@ +# Changelog + +## Version 1.1.0 + +* Fixed a race condition in HID causing sporadic incorrect key-releases when using hidKeysHeld(). +* Unix socket API is now supported. +* Time support, currently only UTC. +* Added hidMouseRead(). +* Added settings-services support. +* Added gfxSetDrawFlip() and gfxConfigureTransform(). +* Proper (libnx-side) RomFS support. Initial fsStorage support / other fs(dev) changes. +* The console font is now 16x16. +* Fixed args parsing with quotes. +* Various audio adjustments + added audoutWaitPlayFinish(). +* More irs (irsensor) support. +* Added usleep(). +* General system stability improvements to enhance the user's experience. diff --git a/nx/Makefile b/nx/Makefile index 05c4fa20..5e97e960 100644 --- a/nx/Makefile +++ b/nx/Makefile @@ -9,7 +9,7 @@ endif include $(DEVKITPRO)/devkitA64/base_rules export LIBNX_MAJOR := 1 -export LIBNX_MINOR := 0 +export LIBNX_MINOR := 1 export LIBNX_PATCH := 0 @@ -26,7 +26,7 @@ TARGET := nx #BUILD := build SOURCES := source/arm source/kernel source/services source/display source/nvidia source/nvidia/gpu source/nvidia/ioctl source/runtime source/runtime/devices source/runtime/util/utf DATA := data -INCLUDES := include +INCLUDES := include external/bsd/include #--------------------------------------------------------------------------------- # options for code generation @@ -80,8 +80,10 @@ else endif #--------------------------------------------------------------------------------- -export OFILES := $(addsuffix .o,$(BINFILES)) \ - $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SRC) +export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ @@ -94,10 +96,10 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ all: lib/libnx.a lib/libnxd.a dist-bin: all - @tar --exclude=*~ -cjf libnx-$(VERSION).tar.bz2 include lib default_icon.jpg switch_rules switch.ld switch.specs + @tar --exclude=*~ -cjf libnx-$(VERSION).tar.bz2 include lib default_icon.jpg switch_rules switch.ld switch.specs -C external/bsd include dist-src: - @tar --exclude=*~ -cjf libnx-src-$(VERSION).tar.bz2 include source data Makefile default_icon.jpg switch_rules switch.ld switch.specs + @tar --exclude=*~ -cjf libnx-src-$(VERSION).tar.bz2 include source data external Makefile default_icon.jpg switch_rules switch.ld switch.specs dist: dist-src dist-bin @@ -147,8 +149,10 @@ DEPENDS := $(OFILES:.o=.d) #--------------------------------------------------------------------------------- $(OUTPUT) : $(OFILES) +$(OFILES_SRC) : $(HFILES) + #--------------------------------------------------------------------------------- -%.bin.o : %.bin +%_bin.h %.bin.o : %.bin #--------------------------------------------------------------------------------- @echo $(notdir $<) @$(bin2o) diff --git a/nx/external/bsd/include/arpa/inet.h b/nx/external/bsd/include/arpa/inet.h new file mode 100644 index 00000000..9d3e162e --- /dev/null +++ b/nx/external/bsd/include/arpa/inet.h @@ -0,0 +1,41 @@ +// FreeBSD's header was so full of s*it, I just picked libctru's version of + +#pragma once + +#include +#include + +static inline uint32_t htonl(uint32_t hostlong) +{ + return __builtin_bswap32(hostlong); +} + +static inline uint16_t htons(uint16_t hostshort) +{ + return __builtin_bswap16(hostshort); +} + +static inline uint32_t ntohl(uint32_t netlong) +{ + return __builtin_bswap32(netlong); +} + +static inline uint16_t ntohs(uint16_t netshort) +{ + return __builtin_bswap16(netshort); +} + +#ifdef __cplusplus +extern "C" { +#endif + + in_addr_t inet_addr(const char *cp); + int inet_aton(const char *cp, struct in_addr *inp); + char* inet_ntoa(struct in_addr in); + + const char *inet_ntop(int af, const void * src, char * dst, socklen_t size); + int inet_pton(int af, const char * src, void * dst); + +#ifdef __cplusplus +} +#endif diff --git a/nx/external/bsd/include/net/bpf.h b/nx/external/bsd/include/net/bpf.h new file mode 100644 index 00000000..bc3c2e62 --- /dev/null +++ b/nx/external/bsd/include/net/bpf.h @@ -0,0 +1,484 @@ +// TuxSH: removed definitions under _KERNEL ifdef blocks, modify the prototype of some functions, some other cleanup, etc. +#ifndef __BSD_VISIBLE +#define __BSD_VISIBLE 1 +#endif + +// Stubbed some stuff + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1990, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * 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. 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. + * + * @(#)bpf.h 8.1 (Berkeley) 6/10/93 + * @(#)bpf.h 1.34 (LBL) 6/16/96 + * + * $FreeBSD$ + */ + +#ifndef _NET_BPF_H_ +#define _NET_BPF_H_ + +#include +#include + +/* BSD style release date */ +#define BPF_RELEASE 199606 + +typedef int32_t bpf_int32; +typedef u_int32_t bpf_u_int32; +typedef int64_t bpf_int64; +typedef u_int64_t bpf_u_int64; + +/* + * Alignment macros. BPF_WORDALIGN rounds up to the next + * even multiple of BPF_ALIGNMENT. + */ +#define BPF_ALIGNMENT sizeof(long) +#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) + +#define BPF_MAXINSNS 512 +#define BPF_MAXBUFSIZE 0x80000 +#define BPF_MINBUFSIZE 32 + +/* + * Structure for BIOCSETF. + */ +struct bpf_program { + u_int bf_len; + struct bpf_insn *bf_insns; +}; + +/* + * Struct returned by BIOCGSTATS. + */ +struct bpf_stat { + u_int bs_recv; /* number of packets received */ + u_int bs_drop; /* number of packets dropped */ +}; + +/* + * Struct return by BIOCVERSION. This represents the version number of + * the filter language described by the instruction encodings below. + * bpf understands a program iff kernel_major == filter_major && + * kernel_minor >= filter_minor, that is, if the value returned by the + * running kernel has the same major number and a minor number equal + * equal to or less than the filter being downloaded. Otherwise, the + * results are undefined, meaning an error may be returned or packets + * may be accepted haphazardly. + * It has nothing to do with the source code version. + */ +struct bpf_version { + u_short bv_major; + u_short bv_minor; +}; +/* Current version number of filter architecture. */ +#define BPF_MAJOR_VERSION 1 +#define BPF_MINOR_VERSION 1 + +/* + * Historically, BPF has supported a single buffering model, first using mbuf + * clusters in kernel, and later using malloc(9) buffers in kernel. We now + * support multiple buffering modes, which may be queried and set using + * BIOCGETBUFMODE and BIOCSETBUFMODE. So as to avoid handling the complexity + * of changing modes while sniffing packets, the mode becomes fixed once an + * interface has been attached to the BPF descriptor. + */ +#define BPF_BUFMODE_BUFFER 1 /* Kernel buffers with read(). */ +#define BPF_BUFMODE_ZBUF 2 /* Zero-copy buffers. */ + +/*- + * Struct used by BIOCSETZBUF, BIOCROTZBUF: describes up to two zero-copy + * buffer as used by BPF. + */ +struct bpf_zbuf { + void *bz_bufa; /* Location of 'a' zero-copy buffer. */ + void *bz_bufb; /* Location of 'b' zero-copy buffer. */ + size_t bz_buflen; /* Size of zero-copy buffers. */ +}; + +#define BIOCGBLEN _IOR('B', 102, u_int) +#define BIOCSBLEN _IOWR('B', 102, u_int) +#define BIOCSETF _IOW('B', 103, struct bpf_program) +#define BIOCFLUSH _IO('B', 104) +#define BIOCPROMISC _IO('B', 105) +#define BIOCGDLT _IOR('B', 106, u_int) +#define BIOCGETIF _IOR('B', 107, struct ifreq) +#define BIOCSETIF _IOW('B', 108, struct ifreq) +#define BIOCSRTIMEOUT _IOW('B', 109, struct timeval) +#define BIOCGRTIMEOUT _IOR('B', 110, struct timeval) +#define BIOCGSTATS _IOR('B', 111, struct bpf_stat) +#define BIOCIMMEDIATE _IOW('B', 112, u_int) +#define BIOCVERSION _IOR('B', 113, struct bpf_version) +#define BIOCGRSIG _IOR('B', 114, u_int) +#define BIOCSRSIG _IOW('B', 115, u_int) +#define BIOCGHDRCMPLT _IOR('B', 116, u_int) +#define BIOCSHDRCMPLT _IOW('B', 117, u_int) +#define BIOCGDIRECTION _IOR('B', 118, u_int) +#define BIOCSDIRECTION _IOW('B', 119, u_int) +#define BIOCSDLT _IOW('B', 120, u_int) +#define BIOCGDLTLIST _IOWR('B', 121, struct bpf_dltlist) +#define BIOCLOCK _IO('B', 122) +#define BIOCSETWF _IOW('B', 123, struct bpf_program) +#define BIOCFEEDBACK _IOW('B', 124, u_int) +#define BIOCGETBUFMODE _IOR('B', 125, u_int) +#define BIOCSETBUFMODE _IOW('B', 126, u_int) +#define BIOCGETZMAX _IOR('B', 127, size_t) +#define BIOCROTZBUF _IOR('B', 128, struct bpf_zbuf) +#define BIOCSETZBUF _IOW('B', 129, struct bpf_zbuf) +#define BIOCSETFNR _IOW('B', 130, struct bpf_program) +#define BIOCGTSTAMP _IOR('B', 131, u_int) +#define BIOCSTSTAMP _IOW('B', 132, u_int) + +// Nintendo bullshit: +#define BIOCSETF_SERIALIZED _IOW('B', 103, struct bpf_program_serialized) +#define BIOCSETWF_SERIALIZED _IOW('B', 123, struct bpf_program_serialized) +#define BIOCSETFNR_SERIALIZED _IOW('B', 130, struct bpf_program_serialized) + +/* Obsolete */ +#define BIOCGSEESENT BIOCGDIRECTION +#define BIOCSSEESENT BIOCSDIRECTION + +/* Packet directions */ +enum bpf_direction { + BPF_D_IN, /* See incoming packets */ + BPF_D_INOUT, /* See incoming and outgoing packets */ + BPF_D_OUT /* See outgoing packets */ +}; + +/* Time stamping functions */ +#define BPF_T_MICROTIME 0x0000 +#define BPF_T_NANOTIME 0x0001 +#define BPF_T_BINTIME 0x0002 +#define BPF_T_NONE 0x0003 +#define BPF_T_FORMAT_MASK 0x0003 +#define BPF_T_NORMAL 0x0000 +#define BPF_T_FAST 0x0100 +#define BPF_T_MONOTONIC 0x0200 +#define BPF_T_MONOTONIC_FAST (BPF_T_FAST | BPF_T_MONOTONIC) +#define BPF_T_FLAG_MASK 0x0300 +#define BPF_T_FORMAT(t) ((t) & BPF_T_FORMAT_MASK) +#define BPF_T_FLAG(t) ((t) & BPF_T_FLAG_MASK) +#define BPF_T_VALID(t) \ + ((t) == BPF_T_NONE || (BPF_T_FORMAT(t) != BPF_T_NONE && \ + ((t) & ~(BPF_T_FORMAT_MASK | BPF_T_FLAG_MASK)) == 0)) + +#define BPF_T_MICROTIME_FAST (BPF_T_MICROTIME | BPF_T_FAST) +#define BPF_T_NANOTIME_FAST (BPF_T_NANOTIME | BPF_T_FAST) +#define BPF_T_BINTIME_FAST (BPF_T_BINTIME | BPF_T_FAST) +#define BPF_T_MICROTIME_MONOTONIC (BPF_T_MICROTIME | BPF_T_MONOTONIC) +#define BPF_T_NANOTIME_MONOTONIC (BPF_T_NANOTIME | BPF_T_MONOTONIC) +#define BPF_T_BINTIME_MONOTONIC (BPF_T_BINTIME | BPF_T_MONOTONIC) +#define BPF_T_MICROTIME_MONOTONIC_FAST (BPF_T_MICROTIME | BPF_T_MONOTONIC_FAST) +#define BPF_T_NANOTIME_MONOTONIC_FAST (BPF_T_NANOTIME | BPF_T_MONOTONIC_FAST) +#define BPF_T_BINTIME_MONOTONIC_FAST (BPF_T_BINTIME | BPF_T_MONOTONIC_FAST) + +/* + * Structure prepended to each packet. + */ +struct bpf_ts { + bpf_int64 bt_sec; /* seconds */ + bpf_u_int64 bt_frac; /* fraction */ +}; +struct bpf_xhdr { + struct bpf_ts bh_tstamp; /* time stamp */ + bpf_u_int32 bh_caplen; /* length of captured portion */ + bpf_u_int32 bh_datalen; /* original length of packet */ + u_short bh_hdrlen; /* length of bpf header (this struct + plus alignment padding) */ +}; +/* Obsolete */ +struct bpf_hdr { + struct timeval bh_tstamp; /* time stamp */ + bpf_u_int32 bh_caplen; /* length of captured portion */ + bpf_u_int32 bh_datalen; /* original length of packet */ + u_short bh_hdrlen; /* length of bpf header (this struct + plus alignment padding) */ +}; + +/* + * When using zero-copy BPF buffers, a shared memory header is present + * allowing the kernel BPF implementation and user process to synchronize + * without using system calls. This structure defines that header. When + * accessing these fields, appropriate atomic operation and memory barriers + * are required in order not to see stale or out-of-order data; see bpf(4) + * for reference code to access these fields from userspace. + * + * The layout of this structure is critical, and must not be changed; if must + * fit in a single page on all architectures. + */ +struct bpf_zbuf_header { + volatile u_int bzh_kernel_gen; /* Kernel generation number. */ + volatile u_int bzh_kernel_len; /* Length of data in the buffer. */ + volatile u_int bzh_user_gen; /* User generation number. */ + u_int _bzh_pad[5]; +}; + +/* Pull in data-link level type codes. */ +#include + +/* + * The instruction encodings. + * + * Please inform tcpdump-workers@lists.tcpdump.org if you use any + * of the reserved values, so that we can note that they're used + * (and perhaps implement it in the reference BPF implementation + * and encourage its implementation elsewhere). + */ + +/* + * The upper 8 bits of the opcode aren't used. BSD/OS used 0x8000. + */ + +/* instruction classes */ +#define BPF_CLASS(code) ((code) & 0x07) +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +/* ld/ldx fields */ +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +/* 0x18 reserved; used by BSD/OS */ +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 +/* 0xc0 reserved; used by BSD/OS */ +/* 0xe0 reserved; used by BSD/OS */ + +/* alu/jmp fields */ +#define BPF_OP(code) ((code) & 0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_MOD 0x90 +#define BPF_XOR 0xa0 +/* 0xb0 reserved */ +/* 0xc0 reserved */ +/* 0xd0 reserved */ +/* 0xe0 reserved */ +/* 0xf0 reserved */ + +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +/* 0x50 reserved; used on BSD/OS */ +/* 0x60 reserved */ +/* 0x70 reserved */ +/* 0x80 reserved */ +/* 0x90 reserved */ +/* 0xa0 reserved */ +/* 0xb0 reserved */ +/* 0xc0 reserved */ +/* 0xd0 reserved */ +/* 0xe0 reserved */ +/* 0xf0 reserved */ +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 + +/* ret - BPF_K and BPF_X also apply */ +#define BPF_RVAL(code) ((code) & 0x18) +#define BPF_A 0x10 +/* 0x18 reserved */ + +/* misc */ +#define BPF_MISCOP(code) ((code) & 0xf8) +#define BPF_TAX 0x00 +/* 0x08 reserved */ +/* 0x10 reserved */ +/* 0x18 reserved */ +/* #define BPF_COP 0x20 NetBSD "coprocessor" extensions */ +/* 0x28 reserved */ +/* 0x30 reserved */ +/* 0x38 reserved */ +/* #define BPF_COPX 0x40 NetBSD "coprocessor" extensions */ +/* also used on BSD/OS */ +/* 0x48 reserved */ +/* 0x50 reserved */ +/* 0x58 reserved */ +/* 0x60 reserved */ +/* 0x68 reserved */ +/* 0x70 reserved */ +/* 0x78 reserved */ +#define BPF_TXA 0x80 +/* 0x88 reserved */ +/* 0x90 reserved */ +/* 0x98 reserved */ +/* 0xa0 reserved */ +/* 0xa8 reserved */ +/* 0xb0 reserved */ +/* 0xb8 reserved */ +/* 0xc0 reserved; used on BSD/OS */ +/* 0xc8 reserved */ +/* 0xd0 reserved */ +/* 0xd8 reserved */ +/* 0xe0 reserved */ +/* 0xe8 reserved */ +/* 0xf0 reserved */ +/* 0xf8 reserved */ + +/* + * The instruction data structure. + */ +struct bpf_insn { + u_short code; + u_char jt; + u_char jf; + bpf_u_int32 k; +}; + +// Nintendo's bullshit +struct bpf_program_serialized { + u_int bf_len; + struct bpf_insn bf_insns[BPF_MAXINSNS]; +}; + +/* + * Macros for insn array initializers. + */ +#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } +#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + +/* + * Structure to retrieve available DLTs for the interface. + */ +struct bpf_dltlist { + u_int bfl_len; /* number of bfd_list array */ + u_int *bfl_list; /* array of DLTs */ +}; + +/* + * Rotate the packet buffers in descriptor d. Move the store buffer into the + * hold slot, and the free buffer into the store slot. Zero the length of the + * new store buffer. Descriptor lock should be held. One must be careful to + * not rotate the buffers twice, i.e. if fbuf != NULL. + */ +#define ROTATE_BUFFERS(d) do { \ + (d)->bd_hbuf = (d)->bd_sbuf; \ + (d)->bd_hlen = (d)->bd_slen; \ + (d)->bd_sbuf = (d)->bd_fbuf; \ + (d)->bd_slen = 0; \ + (d)->bd_fbuf = NULL; \ + bpf_bufheld(d); \ +} while (0) + +/* + * Descriptor associated with each attached hardware interface. + * Part of this structure is exposed to external callers to speed up + * bpf_peers_present() calls. + */ +struct bpf_if; + +struct bpf_if_ext; // Removed definition, if you need it, PR + +/* [TuxSH] if you need those, PR; + +void bpf_bufheld(struct bpf_d *d); +int bpf_validate(const struct bpf_insn *, int); +void bpf_tap(struct bpf_if *, u_char *, u_int); +void bpf_mtap(struct bpf_if *, struct mbuf *); +void bpf_mtap2(struct bpf_if *, void *, u_int, struct mbuf *); +void bpfattach(struct ifnet *, u_int, u_int); +void bpfattach2(struct ifnet *, u_int, u_int, struct bpf_if **); +void bpfdetach(struct ifnet *); +#ifdef VIMAGE +int bpf_get_bp_params(struct bpf_if *, u_int *, u_int *); +#endif + +void bpfilterattach(int); +u_int bpf_filter(const struct bpf_insn *, u_char *, u_int, u_int); + +static __inline int +bpf_peers_present(struct bpf_if *bpf) +{ + struct bpf_if_ext *ext; + + ext = (struct bpf_if_ext *)bpf; + if (!LIST_EMPTY(&ext->bif_dlist)) + return (1); + return (0); +} + +#define BPF_TAP(_ifp,_pkt,_pktlen) do { \ + if (bpf_peers_present((_ifp)->if_bpf)) \ + bpf_tap((_ifp)->if_bpf, (_pkt), (_pktlen)); \ +} while (0) +#define BPF_MTAP(_ifp,_m) do { \ + if (bpf_peers_present((_ifp)->if_bpf)) { \ + M_ASSERTVALID(_m); \ + bpf_mtap((_ifp)->if_bpf, (_m)); \ + } \ +} while (0) +#define BPF_MTAP2(_ifp,_data,_dlen,_m) do { \ + if (bpf_peers_present((_ifp)->if_bpf)) { \ + M_ASSERTVALID(_m); \ + bpf_mtap2((_ifp)->if_bpf,(_data),(_dlen),(_m)); \ + } \ +} while (0) +#endif +*/ + +/* + * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). + */ +#define BPF_MEMWORDS 16 + +#if 0 //def _SYS_EVENTHANDLER_H_ +/* BPF attach/detach events */ +struct ifnet; +typedef void (*bpf_track_fn)(void *, struct ifnet *, int /* dlt */, + int /* 1 =>'s attach */); +EVENTHANDLER_DECLARE(bpf_track, bpf_track_fn); +#endif /* _SYS_EVENTHANDLER_H_ */ + +#endif /* _NET_BPF_H_ */ diff --git a/nx/external/bsd/include/net/dlt.h b/nx/external/bsd/include/net/dlt.h new file mode 100644 index 00000000..dc818521 --- /dev/null +++ b/nx/external/bsd/include/net/dlt.h @@ -0,0 +1,1338 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * 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. 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. + * + * @(#)bpf.h 7.1 (Berkeley) 5/7/91 + * + * $FreeBSD$ + */ + +#ifndef _NET_DLT_H_ +#define _NET_DLT_H_ + +/* + * Link-layer header type codes. + * + * Do *NOT* add new values to this list without asking + * "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run + * the risk of using a value that's already being used for some other + * purpose, and of having tools that read libpcap-format captures not + * being able to handle captures with your new DLT_ value, with no hope + * that they will ever be changed to do so (as that would destroy their + * ability to read captures using that value for that other purpose). + * + * See + * + * http://www.tcpdump.org/linktypes.html + * + * for detailed descriptions of some of these link-layer header types. + */ + +/* + * These are the types that are the same on all platforms, and that + * have been defined by for ages. + */ +#define DLT_NULL 0 /* BSD loopback encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* 802.5 Token Ring */ +#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ + +/* + * These are types that are different on some platforms, and that + * have been defined by for ages. We use #ifdefs to + * detect the BSDs that define them differently from the traditional + * libpcap + * + * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, + * but I don't know what the right #define is for BSD/OS. + */ +#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ + +#ifdef __OpenBSD__ +#define DLT_RAW 14 /* raw IP */ +#else +#define DLT_RAW 12 /* raw IP */ +#endif + +/* + * Given that the only OS that currently generates BSD/OS SLIP or PPP + * is, well, BSD/OS, arguably everybody should have chosen its values + * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they + * didn't. So it goes. + */ +#if defined(__NetBSD__) || defined(__FreeBSD__) +#ifndef DLT_SLIP_BSDOS +#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ +#endif +#else +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ +#endif + +/* + * 17 was used for DLT_PFLOG in OpenBSD; it no longer is. + * + * It was DLT_LANE8023 in SuSE 6.3, so we defined LINKTYPE_PFLOG + * as 117 so that pflog captures would use a link-layer header type + * value that didn't collide with any other values. On all + * platforms other than OpenBSD, we defined DLT_PFLOG as 117, + * and we mapped between LINKTYPE_PFLOG and DLT_PFLOG. + * + * OpenBSD eventually switched to using 117 for DLT_PFLOG as well. + * + * Don't use 17 for anything else. + */ + +/* + * 18 is used for DLT_PFSYNC in OpenBSD, NetBSD, DragonFly BSD and + * Mac OS X; don't use it for anything else. (FreeBSD uses 121, + * which collides with DLT_HHDLC, even though it doesn't use 18 + * for anything and doesn't appear to have ever used it for anything.) + * + * We define it as 18 on those platforms; it is, unfortunately, used + * for DLT_CIP in Suse 6.3, so we don't define it as DLT_PFSYNC + * in general. As the packet format for it, like that for + * DLT_PFLOG, is not only OS-dependent but OS-version-dependent, + * we don't support printing it in tcpdump except on OSes that + * have the relevant header files, so it's not that useful on + * other platforms. + */ +#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__) +#define DLT_PFSYNC 18 +#endif + +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + +/* + * Apparently Redback uses this for its SmartEdge 400/800. I hope + * nobody else decided to use it, too. + */ +#define DLT_REDBACK_SMARTEDGE 32 + +/* + * These values are defined by NetBSD; other platforms should refrain from + * using them for other purposes, so that NetBSD savefiles with link + * types of 50 or 51 can be read as this type on all platforms. + */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ +#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + +/* + * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses + * a link-layer type of 99 for the tcpdump it supplies. The link-layer + * header has 6 bytes of unknown data, something that appears to be an + * Ethernet type, and 36 bytes that appear to be 0 in at least one capture + * I've seen. + */ +#define DLT_SYMANTEC_FIREWALL 99 + +/* + * Values between 100 and 103 are used in capture file headers as + * link-layer header type LINKTYPE_ values corresponding to DLT_ types + * that differ between platforms; don't use those values for new DLT_ + * new types. + */ + +/* + * Values starting with 104 are used for newly-assigned link-layer + * header type values; for those link-layer header types, the DLT_ + * value returned by pcap_datalink() and passed to pcap_open_dead(), + * and the LINKTYPE_ value that appears in capture files, are the + * same. + * + * DLT_MATCHING_MIN is the lowest such value; DLT_MATCHING_MAX is + * the highest such value. + */ +#define DLT_MATCHING_MIN 104 + +/* + * This value was defined by libpcap 0.5; platforms that have defined + * it with a different value should define it here with that value - + * a link type of 104 in a save file will be mapped to DLT_C_HDLC, + * whatever value that happens to be, so programs will correctly + * handle files with that link type regardless of the value of + * DLT_C_HDLC. + * + * The name DLT_C_HDLC was used by BSD/OS; we use that name for source + * compatibility with programs written for BSD/OS. + * + * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, + * for source compatibility with programs written for libpcap 0.5. + */ +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC + +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + +/* + * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, + * except when it isn't. (I.e., sometimes it's just raw IP, and + * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, + * so that we don't have to worry about the link-layer header.) + */ + +/* + * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides + * with other values. + * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header + * (DLCI, etc.). + */ +#define DLT_FRELAY 107 + +/* + * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except + * that the AF_ type in the link-layer header is in network byte order. + * + * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so + * we don't use 12 for it in OSes other than OpenBSD. + */ +#ifdef __OpenBSD__ +#define DLT_LOOP 12 +#else +#define DLT_LOOP 108 +#endif + +/* + * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's + * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other + * than OpenBSD. + */ +#ifdef __OpenBSD__ +#define DLT_ENC 13 +#else +#define DLT_ENC 109 +#endif + +/* + * Values between 110 and 112 are reserved for use in capture file headers + * as link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ types + * other than the corresponding DLT_ types. + */ + +/* + * This is for Linux cooked sockets. + */ +#define DLT_LINUX_SLL 113 + +/* + * Apple LocalTalk hardware. + */ +#define DLT_LTALK 114 + +/* + * Acorn Econet. + */ +#define DLT_ECONET 115 + +/* + * Reserved for use with OpenBSD ipfilter. + */ +#define DLT_IPFILTER 116 + +/* + * OpenBSD DLT_PFLOG. + */ +#define DLT_PFLOG 117 + +/* + * Registered for Cisco-internal use. + */ +#define DLT_CISCO_IOS 118 + +/* + * For 802.11 cards using the Prism II chips, with a link-layer + * header including Prism monitor mode information plus an 802.11 + * header. + */ +#define DLT_PRISM_HEADER 119 + +/* + * Reserved for Aironet 802.11 cards, with an Aironet link-layer header + * (see Doug Ambrisko's FreeBSD patches). + */ +#define DLT_AIRONET_HEADER 120 + +/* + * Sigh. + * + * 121 was reserved for Siemens HiPath HDLC on 2002-01-25, as + * requested by Tomas Kukosa. + * + * On 2004-02-25, a FreeBSD checkin to sys/net/bpf.h was made that + * assigned 121 as DLT_PFSYNC. In current versions, its libpcap + * does DLT_ <-> LINKTYPE_ mapping, mapping DLT_PFSYNC to a + * LINKTYPE_PFSYNC value of 246, so it should write out DLT_PFSYNC + * dump files with 246 as the link-layer header type. (Earlier + * versions might not have done mapping, in which case they would + * have written them out with a link-layer header type of 121.) + * + * OpenBSD, from which pf came, however, uses 18 for DLT_PFSYNC; + * its libpcap does no DLT_ <-> LINKTYPE_ mapping, so it would + * write out DLT_PFSYNC dump files with use 18 as the link-layer + * header type. + * + * NetBSD, DragonFly BSD, and Darwin also use 18 for DLT_PFSYNC; in + * current versions, their libpcaps do DLT_ <-> LINKTYPE_ mapping, + * mapping DLT_PFSYNC to a LINKTYPE_PFSYNC value of 246, so they + * should write out DLT_PFSYNC dump files with 246 as the link-layer + * header type. (Earlier versions might not have done mapping, + * in which case they'd work the same way OpenBSD does, writing + * them out with a link-layer header type of 18.) + * + * We'll define DLT_PFSYNC as: + * + * 18 on NetBSD, OpenBSD, DragonFly BSD, and Darwin; + * + * 121 on FreeBSD; + * + * 246 everywhere else. + * + * We'll define DLT_HHDLC as 121 on everything except for FreeBSD; + * anybody who wants to compile, on FreeBSD, code that uses DLT_HHDLC + * is out of luck. + * + * We'll define LINKTYPE_PFSYNC as 246 on *all* platforms, so that + * savefiles written using *this* code won't use 18 or 121 for PFSYNC, + * they'll all use 246. + * + * Code that uses pcap_datalink() to determine the link-layer header + * type of a savefile won't, when built and run on FreeBSD, be able + * to distinguish between LINKTYPE_PFSYNC and LINKTYPE_HHDLC capture + * files, as pcap_datalink() will give 121 for both of them. Code + * that doesn't, such as the code in Wireshark, will be able to + * distinguish between them. + * + * FreeBSD's libpcap won't map a link-layer header type of 18 - i.e., + * DLT_PFSYNC files from OpenBSD and possibly older versions of NetBSD, + * DragonFly BSD, and OS X - to DLT_PFSYNC, so code built with FreeBSD's + * libpcap won't treat those files as DLT_PFSYNC files. + * + * Other libpcaps won't map a link-layer header type of 121 to DLT_PFSYNC; + * this means they can read DLT_HHDLC files, if any exist, but won't + * treat pcap files written by any older versions of FreeBSD libpcap that + * didn't map to 246 as DLT_PFSYNC files. + */ +#ifdef __FreeBSD__ +#define DLT_PFSYNC 121 +#else +#define DLT_HHDLC 121 +#endif + +/* + * This is for RFC 2625 IP-over-Fibre Channel. + * + * This is not for use with raw Fibre Channel, where the link-layer + * header starts with a Fibre Channel frame header; it's for IP-over-FC, + * where the link-layer header starts with an RFC 2625 Network_Header + * field. + */ +#define DLT_IP_OVER_FC 122 + +/* + * This is for Full Frontal ATM on Solaris with SunATM, with a + * pseudo-header followed by an AALn PDU. + * + * There may be other forms of Full Frontal ATM on other OSes, + * with different pseudo-headers. + * + * If ATM software returns a pseudo-header with VPI/VCI information + * (and, ideally, packet type information, e.g. signalling, ILMI, + * LANE, LLC-multiplexed traffic, etc.), it should not use + * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump + * and the like don't have to infer the presence or absence of a + * pseudo-header and the form of the pseudo-header. + */ +#define DLT_SUNATM 123 /* Solaris+SunATM */ + +/* + * Reserved as per request from Kent Dahlgren + * for private use. + */ +#define DLT_RIO 124 /* RapidIO */ +#define DLT_PCI_EXP 125 /* PCI Express */ +#define DLT_AURORA 126 /* Xilinx Aurora link layer */ + +/* + * Header for 802.11 plus a number of bits of link-layer information + * including radio information, used by some recent BSD drivers as + * well as the madwifi Atheros driver for Linux. + */ +#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ + +/* + * Reserved for the TZSP encapsulation, as per request from + * Chris Waters + * TZSP is a generic encapsulation for any other link type, + * which includes a means to include meta-information + * with the packet, e.g. signal strength and channel + * for 802.11 packets. + */ +#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ + +/* + * BSD's ARCNET headers have the source host, destination host, + * and type at the beginning of the packet; that's what's handed + * up to userland via BPF. + * + * Linux's ARCNET headers, however, have a 2-byte offset field + * between the host IDs and the type; that's what's handed up + * to userland via PF_PACKET sockets. + * + * We therefore have to have separate DLT_ values for them. + */ +#define DLT_ARCNET_LINUX 129 /* ARCNET */ + +/* + * Juniper-private data link types, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MLPPP 130 +#define DLT_JUNIPER_MLFR 131 +#define DLT_JUNIPER_ES 132 +#define DLT_JUNIPER_GGSN 133 +#define DLT_JUNIPER_MFR 134 +#define DLT_JUNIPER_ATM2 135 +#define DLT_JUNIPER_SERVICES 136 +#define DLT_JUNIPER_ATM1 137 + +/* + * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund + * . The header that's presented is an Ethernet-like + * header: + * + * #define FIREWIRE_EUI64_LEN 8 + * struct firewire_header { + * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; + * u_char firewire_shost[FIREWIRE_EUI64_LEN]; + * u_short firewire_type; + * }; + * + * with "firewire_type" being an Ethernet type value, rather than, + * for example, raw GASP frames being handed up. + */ +#define DLT_APPLE_IP_OVER_IEEE1394 138 + +/* + * Various SS7 encapsulations, as per a request from Jeff Morriss + * and subsequent discussions. + */ +#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ +#define DLT_MTP2 140 /* MTP2, without pseudo-header */ +#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ +#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ + +/* + * DOCSIS MAC frames. + */ +#define DLT_DOCSIS 143 + +/* + * Linux-IrDA packets. Protocol defined at http://www.irda.org. + * Those packets include IrLAP headers and above (IrLMP...), but + * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy + * framing can be handled by the hardware and depend on the bitrate. + * This is exactly the format you would get capturing on a Linux-IrDA + * interface (irdaX), but not on a raw serial port. + * Note the capture is done in "Linux-cooked" mode, so each packet include + * a fake packet header (struct sll_header). This is because IrDA packet + * decoding is dependant on the direction of the packet (incomming or + * outgoing). + * When/if other platform implement IrDA capture, we may revisit the + * issue and define a real DLT_IRDA... + * Jean II + */ +#define DLT_LINUX_IRDA 144 + +/* + * Reserved for IBM SP switch and IBM Next Federation switch. + */ +#define DLT_IBM_SP 145 +#define DLT_IBM_SN 146 + +/* + * Reserved for private use. If you have some link-layer header type + * that you want to use within your organization, with the capture files + * using that link-layer header type not ever be sent outside your + * organization, you can use these values. + * + * No libpcap release will use these for any purpose, nor will any + * tcpdump release use them, either. + * + * Do *NOT* use these in capture files that you expect anybody not using + * your private versions of capture-file-reading tools to read; in + * particular, do *NOT* use them in products, otherwise you may find that + * people won't be able to use tcpdump, or snort, or Ethereal, or... to + * read capture files from your firewall/intrusion detection/traffic + * monitoring/etc. appliance, or whatever product uses that DLT_ value, + * and you may also find that the developers of those applications will + * not accept patches to let them read those files. + * + * Also, do not use them if somebody might send you a capture using them + * for *their* private type and tools using them for *your* private type + * would have to read them. + * + * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, + * as per the comment above, and use the type you're given. + */ +#define DLT_USER0 147 +#define DLT_USER1 148 +#define DLT_USER2 149 +#define DLT_USER3 150 +#define DLT_USER4 151 +#define DLT_USER5 152 +#define DLT_USER6 153 +#define DLT_USER7 154 +#define DLT_USER8 155 +#define DLT_USER9 156 +#define DLT_USER10 157 +#define DLT_USER11 158 +#define DLT_USER12 159 +#define DLT_USER13 160 +#define DLT_USER14 161 +#define DLT_USER15 162 + +/* + * For future use with 802.11 captures - defined by AbsoluteValue + * Systems to store a number of bits of link-layer information + * including radio information: + * + * http://www.shaftnet.org/~pizza/software/capturefrm.txt + * + * but it might be used by some non-AVS drivers now or in the + * future. + */ +#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MONITOR 164 + +/* + * BACnet MS/TP frames. + */ +#define DLT_BACNET_MS_TP 165 + +/* + * Another PPP variant as per request from Karsten Keil . + * + * This is used in some OSes to allow a kernel socket filter to distinguish + * between incoming and outgoing packets, on a socket intended to + * supply pppd with outgoing packets so it can do dial-on-demand and + * hangup-on-lack-of-demand; incoming packets are filtered out so they + * don't cause pppd to hold the connection up (you don't want random + * input packets such as port scans, packets from old lost connections, + * etc. to force the connection to stay up). + * + * The first byte of the PPP header (0xff03) is modified to accomodate + * the direction - 0x00 = IN, 0x01 = OUT. + */ +#define DLT_PPP_PPPD 166 + +/* + * Names for backwards compatibility with older versions of some PPP + * software; new software should use DLT_PPP_PPPD. + */ +#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD +#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, cookies, etc.. + */ +#define DLT_JUNIPER_PPPOE 167 +#define DLT_JUNIPER_PPPOE_ATM 168 + +#define DLT_GPRS_LLC 169 /* GPRS LLC */ +#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ +#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ + +/* + * Requested by Oolan Zimmer for use in Gcom's T1/E1 line + * monitoring equipment. + */ +#define DLT_GCOM_T1E1 172 +#define DLT_GCOM_SERIAL 173 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_ is used + * for internal communication to Physical Interface Cards (PIC) + */ +#define DLT_JUNIPER_PIC_PEER 174 + +/* + * Link types requested by Gregor Maier of Endace + * Measurement Systems. They add an ERF header (see + * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of + * the link-layer header. + */ +#define DLT_ERF_ETH 175 /* Ethernet */ +#define DLT_ERF_POS 176 /* Packet-over-SONET */ + +/* + * Requested by Daniele Orlandi for raw LAPD + * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header + * includes additional information before the LAPD header, so it's + * not necessarily a generic LAPD header. + */ +#define DLT_LINUX_LAPD 177 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ are used for prepending meta-information + * like interface index, interface name + * before standard Ethernet, PPP, Frelay & C-HDLC Frames + */ +#define DLT_JUNIPER_ETHER 178 +#define DLT_JUNIPER_PPP 179 +#define DLT_JUNIPER_FRELAY 180 +#define DLT_JUNIPER_CHDLC 181 + +/* + * Multi Link Frame Relay (FRF.16) + */ +#define DLT_MFR 182 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for internal communication with a + * voice Adapter Card (PIC) + */ +#define DLT_JUNIPER_VP 183 + +/* + * Arinc 429 frames. + * DLT_ requested by Gianluca Varenni . + * Every frame contains a 32bit A429 label. + * More documentation on Arinc 429 can be found at + * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf + */ +#define DLT_A429 184 + +/* + * Arinc 653 Interpartition Communication messages. + * DLT_ requested by Gianluca Varenni . + * Please refer to the A653-1 standard for more information. + */ +#define DLT_A653_ICM 185 + +/* + * This used to be "USB packets, beginning with a USB setup header; + * requested by Paolo Abeni ." + * + * However, that header didn't work all that well - it left out some + * useful information - and was abandoned in favor of the DLT_USB_LINUX + * header. + * + * This is now used by FreeBSD for its BPF taps for USB; that has its + * own headers. So it is written, so it is done. + * + * For source-code compatibility, we also define DLT_USB to have this + * value. We do it numerically so that, if code that includes this + * file (directly or indirectly) also includes an OS header that also + * defines DLT_USB as 186, we don't get a redefinition warning. + * (NetBSD 7 does that.) + */ +#define DLT_USB_FREEBSD 186 +#define DLT_USB 186 + +/* + * Bluetooth HCI UART transport layer (part H:4); requested by + * Paolo Abeni. + */ +#define DLT_BLUETOOTH_HCI_H4 187 + +/* + * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz + * . + */ +#define DLT_IEEE802_16_MAC_CPS 188 + +/* + * USB packets, beginning with a Linux USB header; requested by + * Paolo Abeni . + */ +#define DLT_USB_LINUX 189 + +/* + * Controller Area Network (CAN) v. 2.0B packets. + * DLT_ requested by Gianluca Varenni . + * Used to dump CAN packets coming from a CAN Vector board. + * More documentation on the CAN v2.0B frames can be found at + * http://www.can-cia.org/downloads/?269 + */ +#define DLT_CAN20B 190 + +/* + * IEEE 802.15.4, with address fields padded, as is done by Linux + * drivers; requested by Juergen Schimmer. + */ +#define DLT_IEEE802_15_4_LINUX 191 + +/* + * Per Packet Information encapsulated packets. + * DLT_ requested by Gianluca Varenni . + */ +#define DLT_PPI 192 + +/* + * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; + * requested by Charles Clancy. + */ +#define DLT_IEEE802_16_MAC_CPS_RADIO 193 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for internal communication with a + * integrated service module (ISM). + */ +#define DLT_JUNIPER_ISM 194 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing); requested by Mikko Saarnivala . + * For this one, we expect the FCS to be present at the end of the frame; + * if the frame has no FCS, DLT_IEEE802_15_4_NOFCS should be used. + */ +#define DLT_IEEE802_15_4 195 + +/* + * Various link-layer types, with a pseudo-header, for SITA + * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). + */ +#define DLT_SITA 196 + +/* + * Various link-layer types, with a pseudo-header, for Endace DAG cards; + * encapsulates Endace ERF records. Requested by Stephen Donnelly + * . + */ +#define DLT_ERF 197 + +/* + * Special header prepended to Ethernet packets when capturing from a + * u10 Networks board. Requested by Phil Mulholland + * . + */ +#define DLT_RAIF1 198 + +/* + * IPMB packet for IPMI, beginning with the I2C slave address, followed + * by the netFn and LUN, etc.. Requested by Chanthy Toeung + * . + */ +#define DLT_IPMB 199 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for capturing data on a secure tunnel interface. + */ +#define DLT_JUNIPER_ST 200 + +/* + * Bluetooth HCI UART transport layer (part H:4), with pseudo-header + * that includes direction information; requested by Paolo Abeni. + */ +#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 + +/* + * AX.25 packet with a 1-byte KISS header; see + * + * http://www.ax25.net/kiss.htm + * + * as per Richard Stearn . + */ +#define DLT_AX25_KISS 202 + +/* + * LAPD packets from an ISDN channel, starting with the address field, + * with no pseudo-header. + * Requested by Varuna De Silva . + */ +#define DLT_LAPD 203 + +/* + * Variants of various link-layer headers, with a one-byte direction + * pseudo-header prepended - zero means "received by this host", + * non-zero (any non-zero value) means "sent by this host" - as per + * Will Barker . + */ +#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ +#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ +#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ +#define DLT_LAPB_WITH_DIR 207 /* LAPB */ + +/* + * 208 is reserved for an as-yet-unspecified proprietary link-layer + * type, as requested by Will Barker. + */ + +/* + * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman + * . + */ +#define DLT_IPMB_LINUX 209 + +/* + * FlexRay automotive bus - http://www.flexray.com/ - as requested + * by Hannes Kaelber . + */ +#define DLT_FLEXRAY 210 + +/* + * Media Oriented Systems Transport (MOST) bus for multimedia + * transport - http://www.mostcooperation.com/ - as requested + * by Hannes Kaelber . + */ +#define DLT_MOST 211 + +/* + * Local Interconnect Network (LIN) bus for vehicle networks - + * http://www.lin-subbus.org/ - as requested by Hannes Kaelber + * . + */ +#define DLT_LIN 212 + +/* + * X2E-private data link type used for serial line capture, + * as requested by Hannes Kaelber . + */ +#define DLT_X2E_SERIAL 213 + +/* + * X2E-private data link type used for the Xoraya data logger + * family, as requested by Hannes Kaelber . + */ +#define DLT_X2E_XORAYA 214 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing), but with the PHY-level data for non-ASK PHYs (4 octets + * of 0 as preamble, one octet of SFD, one octet of frame length+ + * reserved bit, and then the MAC-layer data, starting with the + * frame control field). + * + * Requested by Max Filippov . + */ +#define DLT_IEEE802_15_4_NONASK_PHY 215 + +/* + * David Gibson requested this for + * captures from the Linux kernel /dev/input/eventN devices. This + * is used to communicate keystrokes and mouse movements from the + * Linux kernel to display systems, such as Xorg. + */ +#define DLT_LINUX_EVDEV 216 + +/* + * GSM Um and Abis interfaces, preceded by a "gsmtap" header. + * + * Requested by Harald Welte . + */ +#define DLT_GSMTAP_UM 217 +#define DLT_GSMTAP_ABIS 218 + +/* + * MPLS, with an MPLS label as the link-layer header. + * Requested by Michele Marchetto on behalf + * of OpenBSD. + */ +#define DLT_MPLS 219 + +/* + * USB packets, beginning with a Linux USB header, with the USB header + * padded to 64 bytes; required for memory-mapped access. + */ +#define DLT_USB_LINUX_MMAPPED 220 + +/* + * DECT packets, with a pseudo-header; requested by + * Matthias Wenzel . + */ +#define DLT_DECT 221 + +/* + * From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" + * Date: Mon, 11 May 2009 11:18:30 -0500 + * + * DLT_AOS. We need it for AOS Space Data Link Protocol. + * I have already written dissectors for but need an OK from + * legal before I can submit a patch. + * + */ +#define DLT_AOS 222 + +/* + * Wireless HART (Highway Addressable Remote Transducer) + * From the HART Communication Foundation + * IES/PAS 62591 + * + * Requested by Sam Roberts . + */ +#define DLT_WIHART 223 + +/* + * Fibre Channel FC-2 frames, beginning with a Frame_Header. + * Requested by Kahou Lei . + */ +#define DLT_FC_2 224 + +/* + * Fibre Channel FC-2 frames, beginning with an encoding of the + * SOF, and ending with an encoding of the EOF. + * + * The encodings represent the frame delimiters as 4-byte sequences + * representing the corresponding ordered sets, with K28.5 + * represented as 0xBC, and the D symbols as the corresponding + * byte values; for example, SOFi2, which is K28.5 - D21.5 - D1.2 - D21.2, + * is represented as 0xBC 0xB5 0x55 0x55. + * + * Requested by Kahou Lei . + */ +#define DLT_FC_2_WITH_FRAME_DELIMS 225 + +/* + * Solaris ipnet pseudo-header; requested by Darren Reed . + * + * The pseudo-header starts with a one-byte version number; for version 2, + * the pseudo-header is: + * + * struct dl_ipnetinfo { + * u_int8_t dli_version; + * u_int8_t dli_family; + * u_int16_t dli_htype; + * u_int32_t dli_pktlen; + * u_int32_t dli_ifindex; + * u_int32_t dli_grifindex; + * u_int32_t dli_zsrc; + * u_int32_t dli_zdst; + * }; + * + * dli_version is 2 for the current version of the pseudo-header. + * + * dli_family is a Solaris address family value, so it's 2 for IPv4 + * and 26 for IPv6. + * + * dli_htype is a "hook type" - 0 for incoming packets, 1 for outgoing + * packets, and 2 for packets arriving from another zone on the same + * machine. + * + * dli_pktlen is the length of the packet data following the pseudo-header + * (so the captured length minus dli_pktlen is the length of the + * pseudo-header, assuming the entire pseudo-header was captured). + * + * dli_ifindex is the interface index of the interface on which the + * packet arrived. + * + * dli_grifindex is the group interface index number (for IPMP interfaces). + * + * dli_zsrc is the zone identifier for the source of the packet. + * + * dli_zdst is the zone identifier for the destination of the packet. + * + * A zone number of 0 is the global zone; a zone number of 0xffffffff + * means that the packet arrived from another host on the network, not + * from another zone on the same machine. + * + * An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates + * which of those it is. + */ +#define DLT_IPNET 226 + +/* + * CAN (Controller Area Network) frames, with a pseudo-header as supplied + * by Linux SocketCAN, and with multi-byte numerical fields in that header + * in big-endian byte order. + * + * See Documentation/networking/can.txt in the Linux source. + * + * Requested by Felix Obenhuber . + */ +#define DLT_CAN_SOCKETCAN 227 + +/* + * Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies + * whether it's v4 or v6. Requested by Darren Reed . + */ +#define DLT_IPV4 228 +#define DLT_IPV6 229 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing), and with no FCS at the end of the frame; requested by + * Jon Smirl . + */ +#define DLT_IEEE802_15_4_NOFCS 230 + +/* + * Raw D-Bus: + * + * http://www.freedesktop.org/wiki/Software/dbus + * + * messages: + * + * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages + * + * starting with the endianness flag, followed by the message type, etc., + * but without the authentication handshake before the message sequence: + * + * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol + * + * Requested by Martin Vidner . + */ +#define DLT_DBUS 231 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + */ +#define DLT_JUNIPER_VS 232 +#define DLT_JUNIPER_SRX_E2E 233 +#define DLT_JUNIPER_FIBRECHANNEL 234 + +/* + * DVB-CI (DVB Common Interface for communication between a PC Card + * module and a DVB receiver). See + * + * http://www.kaiser.cx/pcap-dvbci.html + * + * for the specification. + * + * Requested by Martin Kaiser . + */ +#define DLT_DVB_CI 235 + +/* + * Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but + * *not* the same as, 27.010). Requested by Hans-Christoph Schemmel + * . + */ +#define DLT_MUX27010 236 + +/* + * STANAG 5066 D_PDUs. Requested by M. Baris Demiray + * . + */ +#define DLT_STANAG_5066_D_PDU 237 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + */ +#define DLT_JUNIPER_ATM_CEMIC 238 + +/* + * NetFilter LOG messages + * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets) + * + * Requested by Jakub Zawadzki + */ +#define DLT_NFLOG 239 + +/* + * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type + * for Ethernet packets with a 4-byte pseudo-header and always + * with the payload including the FCS, as supplied by their + * netANALYZER hardware and software. + * + * Requested by Holger P. Frommer + */ +#define DLT_NETANALYZER 240 + +/* + * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type + * for Ethernet packets with a 4-byte pseudo-header and FCS and + * with the Ethernet header preceded by 7 bytes of preamble and + * 1 byte of SFD, as supplied by their netANALYZER hardware and + * software. + * + * Requested by Holger P. Frommer + */ +#define DLT_NETANALYZER_TRANSPARENT 241 + +/* + * IP-over-InfiniBand, as specified by RFC 4391. + * + * Requested by Petr Sumbera . + */ +#define DLT_IPOIB 242 + +/* + * MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0). + * + * Requested by Guy Martin . + */ +#define DLT_MPEG_2_TS 243 + +/* + * ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as + * used by their ng40 protocol tester. + * + * Requested by Jens Grimmer . + */ +#define DLT_NG40 244 + +/* + * Pseudo-header giving adapter number and flags, followed by an NFC + * (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU, + * as specified by NFC Forum Logical Link Control Protocol Technical + * Specification LLCP 1.1. + * + * Requested by Mike Wakerly . + */ +#define DLT_NFC_LLCP 245 + +/* + * 246 is used as LINKTYPE_PFSYNC; do not use it for any other purpose. + * + * DLT_PFSYNC has different values on different platforms, and all of + * them collide with something used elsewhere. On platforms that + * don't already define it, define it as 246. + */ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__APPLE__) +#define DLT_PFSYNC 246 +#endif + +/* + * Raw InfiniBand packets, starting with the Local Routing Header. + * + * Requested by Oren Kladnitsky . + */ +#define DLT_INFINIBAND 247 + +/* + * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6). + * + * Requested by Michael Tuexen . + */ +#define DLT_SCTP 248 + +/* + * USB packets, beginning with a USBPcap header. + * + * Requested by Tomasz Mon + */ +#define DLT_USBPCAP 249 + +/* + * Schweitzer Engineering Laboratories "RTAC" product serial-line + * packets. + * + * Requested by Chris Bontje . + */ +#define DLT_RTAC_SERIAL 250 + +/* + * Bluetooth Low Energy air interface link-layer packets. + * + * Requested by Mike Kershaw . + */ +#define DLT_BLUETOOTH_LE_LL 251 + +/* + * DLT type for upper-protocol layer PDU saves from wireshark. + * + * the actual contents are determined by two TAGs stored with each + * packet: + * EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the + * original packet. + * + * EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector + * that can make sense of the data stored. + */ +#define DLT_WIRESHARK_UPPER_PDU 252 + +/* + * DLT type for the netlink protocol (nlmon devices). + */ +#define DLT_NETLINK 253 + +/* + * Bluetooth Linux Monitor headers for the BlueZ stack. + */ +#define DLT_BLUETOOTH_LINUX_MONITOR 254 + +/* + * Bluetooth Basic Rate/Enhanced Data Rate baseband packets, as + * captured by Ubertooth. + */ +#define DLT_BLUETOOTH_BREDR_BB 255 + +/* + * Bluetooth Low Energy link layer packets, as captured by Ubertooth. + */ +#define DLT_BLUETOOTH_LE_LL_WITH_PHDR 256 + +/* + * PROFIBUS data link layer. + */ +#define DLT_PROFIBUS_DL 257 + +/* + * Apple's DLT_PKTAP headers. + * + * Sadly, the folks at Apple either had no clue that the DLT_USERn values + * are for internal use within an organization and partners only, and + * didn't know that the right way to get a link-layer header type is to + * ask tcpdump.org for one, or knew and didn't care, so they just + * used DLT_USER2, which causes problems for everything except for + * their version of tcpdump. + * + * So I'll just give them one; hopefully this will show up in a + * libpcap release in time for them to get this into 10.10 Big Sur + * or whatever Mavericks' successor is called. LINKTYPE_PKTAP + * will be 258 *even on OS X*; that is *intentional*, so that + * PKTAP files look the same on *all* OSes (different OSes can have + * different numerical values for a given DLT_, but *MUST NOT* have + * different values for what goes in a file, as files can be moved + * between OSes!). + * + * When capturing, on a system with a Darwin-based OS, on a device + * that returns 149 (DLT_USER2 and Apple's DLT_PKTAP) with this + * version of libpcap, the DLT_ value for the pcap_t will be DLT_PKTAP, + * and that will continue to be DLT_USER2 on Darwin-based OSes. That way, + * binary compatibility with Mavericks is preserved for programs using + * this version of libpcap. This does mean that if you were using + * DLT_USER2 for some capture device on OS X, you can't do so with + * this version of libpcap, just as you can't with Apple's libpcap - + * on OS X, they define DLT_PKTAP to be DLT_USER2, so programs won't + * be able to distinguish between PKTAP and whatever you were using + * DLT_USER2 for. + * + * If the program saves the capture to a file using this version of + * libpcap's pcap_dump code, the LINKTYPE_ value in the file will be + * LINKTYPE_PKTAP, which will be 258, even on Darwin-based OSes. + * That way, the file will *not* be a DLT_USER2 file. That means + * that the latest version of tcpdump, when built with this version + * of libpcap, and sufficiently recent versions of Wireshark will + * be able to read those files and interpret them correctly; however, + * Apple's version of tcpdump in OS X 10.9 won't be able to handle + * them. (Hopefully, Apple will pick up this version of libpcap, + * and the corresponding version of tcpdump, so that tcpdump will + * be able to handle the old LINKTYPE_USER2 captures *and* the new + * LINKTYPE_PKTAP captures.) + */ +#ifdef __APPLE__ +#define DLT_PKTAP DLT_USER2 +#else +#define DLT_PKTAP 258 +#endif + +/* + * Ethernet packets preceded by a header giving the last 6 octets + * of the preamble specified by 802.3-2012 Clause 65, section + * 65.1.3.2 "Transmit". + */ +#define DLT_EPON 259 + +/* + * IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" + * in the PICMG HPM.2 specification. + */ +#define DLT_IPMI_HPM_2 260 + +/* + * per Joshua Wright , formats for Zwave captures. + */ +#define DLT_ZWAVE_R1_R2 261 +#define DLT_ZWAVE_R3 262 + +/* + * per Steve Karg , formats for Wattstopper + * Digital Lighting Management room bus serial protocol captures. + */ +#define DLT_WATTSTOPPER_DLM 263 + +/* + * ISO 14443 contactless smart card messages. + */ +#define DLT_ISO_14443 264 + +/* + * Radio data system (RDS) groups. IEC 62106. + * Per Jonathan Brucker . + */ +#define DLT_RDS 265 + +/* + * In case the code that includes this file (directly or indirectly) + * has also included OS files that happen to define DLT_MATCHING_MAX, + * with a different value (perhaps because that OS hasn't picked up + * the latest version of our DLT definitions), we undefine the + * previous value of DLT_MATCHING_MAX. + */ +#ifdef DLT_MATCHING_MAX +#undef DLT_MATCHING_MAX +#endif +#define DLT_MATCHING_MAX 265 /* highest value in the "matching" range */ + +/* + * DLT and savefile link type values are split into a class and + * a member of that class. A class value of 0 indicates a regular + * DLT_/LINKTYPE_ value. + */ +#define DLT_CLASS(x) ((x) & 0x03ff0000) + +/* + * NetBSD-specific generic "raw" link type. The class value indicates + * that this is the generic raw type, and the lower 16 bits are the + * address family we're dealing with. Those values are NetBSD-specific; + * do not assume that they correspond to AF_ values for your operating + * system. + */ +#define DLT_CLASS_NETBSD_RAWAF 0x02240000 +#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) +#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) +#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) + +#endif /* !_NET_DLT_H_ */ diff --git a/nx/external/bsd/include/net/if.h b/nx/external/bsd/include/net/if.h new file mode 100644 index 00000000..dde9eaac --- /dev/null +++ b/nx/external/bsd/include/net/if.h @@ -0,0 +1,547 @@ +// Removed kernel stuff, use anon unions + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1982, 1986, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * @(#)if.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD$ + */ + +#ifndef _NET_IF_H_ +#define _NET_IF_H_ + +#include + +#if __BSD_VISIBLE +/* + * does not depend on on most other systems. This + * helps userland compatibility. (struct timeval ifi_lastchange) + * The same holds for . (struct sockaddr ifru_addr) + */ +#include +#include +#endif + +/* + * Length of interface external name, including terminating '\0'. + * Note: this is the same size as a generic device's external name. + */ +#define IF_NAMESIZE 16 +#if __BSD_VISIBLE +#define IFNAMSIZ IF_NAMESIZE +#define IF_MAXUNIT 0x7fff /* historical value */ +#endif +#if __BSD_VISIBLE + +/* + * Structure used to query names of interface cloners. + */ + +struct if_clonereq { + int ifcr_total; /* total cloners (out) */ + int ifcr_count; /* room for this many in user buffer */ + char *ifcr_buffer; /* buffer for cloner names */ +}; + +/* + * Structure describing information about an interface + * which may be of interest to management entities. + */ +struct if_data { + /* generic interface information */ + uint8_t ifi_type; /* ethernet, tokenring, etc */ + uint8_t ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */ + uint8_t ifi_addrlen; /* media address length */ + uint8_t ifi_hdrlen; /* media header length */ + uint8_t ifi_link_state; /* current link state */ + uint8_t ifi_vhid; /* carp vhid */ + uint16_t ifi_datalen; /* length of this data struct */ + uint32_t ifi_mtu; /* maximum transmission unit */ + uint32_t ifi_metric; /* routing metric (external only) */ + uint64_t ifi_baudrate; /* linespeed */ + /* volatile statistics */ + uint64_t ifi_ipackets; /* packets received on interface */ + uint64_t ifi_ierrors; /* input errors on interface */ + uint64_t ifi_opackets; /* packets sent on interface */ + uint64_t ifi_oerrors; /* output errors on interface */ + uint64_t ifi_collisions; /* collisions on csma interfaces */ + uint64_t ifi_ibytes; /* total number of octets received */ + uint64_t ifi_obytes; /* total number of octets sent */ + uint64_t ifi_imcasts; /* packets received via multicast */ + uint64_t ifi_omcasts; /* packets sent via multicast */ + uint64_t ifi_iqdrops; /* dropped on input */ + uint64_t ifi_oqdrops; /* dropped on output */ + uint64_t ifi_noproto; /* destined for unsupported protocol */ + uint64_t ifi_hwassist; /* HW offload capabilities, see IFCAP */ + + time_t ifi_epoch; /* uptime at attach or stat reset */ + struct timeval ifi_lastchange; /* time of last administrative change */ +}; + +/*- + * Interface flags are of two types: network stack owned flags, and driver + * owned flags. Historically, these values were stored in the same ifnet + * flags field, but with the advent of fine-grained locking, they have been + * broken out such that the network stack is responsible for synchronizing + * the stack-owned fields, and the device driver the device-owned fields. + * Both halves can perform lockless reads of the other half's field, subject + * to accepting the involved races. + * + * Both sets of flags come from the same number space, and should not be + * permitted to conflict, as they are exposed to user space via a single + * field. + * + * The following symbols identify read and write requirements for fields: + * + * (i) if_flags field set by device driver before attach, read-only there + * after. + * (n) if_flags field written only by the network stack, read by either the + * stack or driver. + * (d) if_drv_flags field written only by the device driver, read by either + * the stack or driver. + */ +#define IFF_UP 0x1 /* (n) interface is up */ +#define IFF_BROADCAST 0x2 /* (i) broadcast address valid */ +#define IFF_DEBUG 0x4 /* (n) turn on debugging */ +#define IFF_LOOPBACK 0x8 /* (i) is a loopback net */ +#define IFF_POINTOPOINT 0x10 /* (i) is a point-to-point link */ +/* 0x20 was IFF_SMART */ +#define IFF_DRV_RUNNING 0x40 /* (d) resources allocated */ +#define IFF_NOARP 0x80 /* (n) no address resolution protocol */ +#define IFF_PROMISC 0x100 /* (n) receive all packets */ +#define IFF_ALLMULTI 0x200 /* (n) receive all multicast packets */ +#define IFF_DRV_OACTIVE 0x400 /* (d) tx hardware queue is full */ +#define IFF_SIMPLEX 0x800 /* (i) can't hear own transmissions */ +#define IFF_LINK0 0x1000 /* per link layer defined bit */ +#define IFF_LINK1 0x2000 /* per link layer defined bit */ +#define IFF_LINK2 0x4000 /* per link layer defined bit */ +#define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */ +#define IFF_MULTICAST 0x8000 /* (i) supports multicast */ +#define IFF_CANTCONFIG 0x10000 /* (i) unconfigurable using ioctl(2) */ +#define IFF_PPROMISC 0x20000 /* (n) user-requested promisc mode */ +#define IFF_MONITOR 0x40000 /* (n) user-requested monitor mode */ +#define IFF_STATICARP 0x80000 /* (n) static ARP */ +#define IFF_DYING 0x200000 /* (n) interface is winding down */ +#define IFF_RENAMING 0x400000 /* (n) interface is being renamed */ +/* + * Old names for driver flags so that user space tools can continue to use + * the old (portable) names. + */ +#define IFF_RUNNING IFF_DRV_RUNNING +#define IFF_OACTIVE IFF_DRV_OACTIVE + +/* flags set internally only: */ +#define IFF_CANTCHANGE \ + (IFF_BROADCAST|IFF_POINTOPOINT|IFF_DRV_RUNNING|IFF_DRV_OACTIVE|\ + IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_PROMISC|\ + IFF_DYING|IFF_CANTCONFIG) + +/* + * Values for if_link_state. + */ +#define LINK_STATE_UNKNOWN 0 /* link invalid/unknown */ +#define LINK_STATE_DOWN 1 /* link is down */ +#define LINK_STATE_UP 2 /* link is up */ + +/* + * Some convenience macros used for setting ifi_baudrate. + * XXX 1000 vs. 1024? --thorpej@netbsd.org + */ +#define IF_Kbps(x) ((uintmax_t)(x) * 1000) /* kilobits/sec. */ +#define IF_Mbps(x) (IF_Kbps((x) * 1000)) /* megabits/sec. */ +#define IF_Gbps(x) (IF_Mbps((x) * 1000)) /* gigabits/sec. */ + +/* + * Capabilities that interfaces can advertise. + * + * struct ifnet.if_capabilities + * contains the optional features & capabilities a particular interface + * supports (not only the driver but also the detected hw revision). + * Capabilities are defined by IFCAP_* below. + * struct ifnet.if_capenable + * contains the enabled (either by default or through ifconfig) optional + * features & capabilities on this interface. + * Capabilities are defined by IFCAP_* below. + * struct if_data.ifi_hwassist in mbuf CSUM_ flag form, controlled by above + * contains the enabled optional feature & capabilites that can be used + * individually per packet and are specified in the mbuf pkthdr.csum_flags + * field. IFCAP_* and CSUM_* do not match one to one and CSUM_* may be + * more detailed or differenciated than IFCAP_*. + * Hwassist features are defined CSUM_* in sys/mbuf.h + * + * Capabilities that cannot be arbitrarily changed with ifconfig/ioctl + * are listed in IFCAP_CANTCHANGE, similar to IFF_CANTCHANGE. + * This is not strictly necessary because the common code never + * changes capabilities, and it is left to the individual driver + * to do the right thing. However, having the filter here + * avoids replication of the same code in all individual drivers. + */ +#define IFCAP_RXCSUM 0x00001 /* can offload checksum on RX */ +#define IFCAP_TXCSUM 0x00002 /* can offload checksum on TX */ +#define IFCAP_NETCONS 0x00004 /* can be a network console */ +#define IFCAP_VLAN_MTU 0x00008 /* VLAN-compatible MTU */ +#define IFCAP_VLAN_HWTAGGING 0x00010 /* hardware VLAN tag support */ +#define IFCAP_JUMBO_MTU 0x00020 /* 9000 byte MTU supported */ +#define IFCAP_POLLING 0x00040 /* driver supports polling */ +#define IFCAP_VLAN_HWCSUM 0x00080 /* can do IFCAP_HWCSUM on VLANs */ +#define IFCAP_TSO4 0x00100 /* can do TCP Segmentation Offload */ +#define IFCAP_TSO6 0x00200 /* can do TCP6 Segmentation Offload */ +#define IFCAP_LRO 0x00400 /* can do Large Receive Offload */ +#define IFCAP_WOL_UCAST 0x00800 /* wake on any unicast frame */ +#define IFCAP_WOL_MCAST 0x01000 /* wake on any multicast frame */ +#define IFCAP_WOL_MAGIC 0x02000 /* wake on any Magic Packet */ +#define IFCAP_TOE4 0x04000 /* interface can offload TCP */ +#define IFCAP_TOE6 0x08000 /* interface can offload TCP6 */ +#define IFCAP_VLAN_HWFILTER 0x10000 /* interface hw can filter vlan tag */ +/* available 0x20000 */ +#define IFCAP_VLAN_HWTSO 0x40000 /* can do IFCAP_TSO on VLANs */ +#define IFCAP_LINKSTATE 0x80000 /* the runtime link state is dynamic */ +#define IFCAP_NETMAP 0x100000 /* netmap mode supported/enabled */ +#define IFCAP_RXCSUM_IPV6 0x200000 /* can offload checksum on IPv6 RX */ +#define IFCAP_TXCSUM_IPV6 0x400000 /* can offload checksum on IPv6 TX */ +#define IFCAP_HWSTATS 0x800000 /* manages counters internally */ +#define IFCAP_TXRTLMT 0x1000000 /* hardware supports TX rate limiting */ +#define IFCAP_HWRXTSTMP 0x2000000 /* hardware rx timestamping */ + +#define IFCAP_HWCSUM_IPV6 (IFCAP_RXCSUM_IPV6 | IFCAP_TXCSUM_IPV6) + +#define IFCAP_HWCSUM (IFCAP_RXCSUM | IFCAP_TXCSUM) +#define IFCAP_TSO (IFCAP_TSO4 | IFCAP_TSO6) +#define IFCAP_WOL (IFCAP_WOL_UCAST | IFCAP_WOL_MCAST | IFCAP_WOL_MAGIC) +#define IFCAP_TOE (IFCAP_TOE4 | IFCAP_TOE6) + +#define IFCAP_CANTCHANGE (IFCAP_NETMAP) + +#define IFQ_MAXLEN 50 +#define IFNET_SLOWHZ 1 /* granularity is 1 second */ + +/* + * Message format for use in obtaining information about interfaces + * from getkerninfo and the routing socket + * For the new, extensible interface see struct if_msghdrl below. + */ +struct if_msghdr { + u_short ifm_msglen; /* to skip over non-understood messages */ + u_char ifm_version; /* future binary compatibility */ + u_char ifm_type; /* message type */ + int ifm_addrs; /* like rtm_addrs */ + int ifm_flags; /* value of if_flags */ + u_short ifm_index; /* index for associated ifp */ + struct if_data ifm_data;/* statistics and other data about if */ +}; + +/* + * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL. It is + * extensible after ifm_data_off or within ifm_data. Both the if_msghdr and + * if_data now have a member field detailing the struct length in addition to + * the routing message length. Macros are provided to find the start of + * ifm_data and the start of the socket address strucutres immediately following + * struct if_msghdrl given a pointer to struct if_msghdrl. + */ +#define IF_MSGHDRL_IFM_DATA(_l) \ + (struct if_data *)((char *)(_l) + (_l)->ifm_data_off) +#define IF_MSGHDRL_RTA(_l) \ + (void *)((uintptr_t)(_l) + (_l)->ifm_len) +struct if_msghdrl { + u_short ifm_msglen; /* to skip over non-understood messages */ + u_char ifm_version; /* future binary compatibility */ + u_char ifm_type; /* message type */ + int ifm_addrs; /* like rtm_addrs */ + int ifm_flags; /* value of if_flags */ + u_short ifm_index; /* index for associated ifp */ + u_short _ifm_spare1; /* spare space to grow if_index, see if_var.h */ + u_short ifm_len; /* length of if_msghdrl incl. if_data */ + u_short ifm_data_off; /* offset of if_data from beginning */ + struct if_data ifm_data;/* statistics and other data about if */ +}; + +/* + * Message format for use in obtaining information about interface addresses + * from getkerninfo and the routing socket + * For the new, extensible interface see struct ifa_msghdrl below. + */ +struct ifa_msghdr { + u_short ifam_msglen; /* to skip over non-understood messages */ + u_char ifam_version; /* future binary compatibility */ + u_char ifam_type; /* message type */ + int ifam_addrs; /* like rtm_addrs */ + int ifam_flags; /* value of ifa_flags */ + u_short ifam_index; /* index for associated ifp */ + int ifam_metric; /* value of ifa_ifp->if_metric */ +}; + +/* + * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL. It is + * extensible after ifam_metric or within ifam_data. Both the ifa_msghdrl and + * if_data now have a member field detailing the struct length in addition to + * the routing message length. Macros are provided to find the start of + * ifm_data and the start of the socket address strucutres immediately following + * struct ifa_msghdrl given a pointer to struct ifa_msghdrl. + */ +#define IFA_MSGHDRL_IFAM_DATA(_l) \ + (struct if_data *)((char *)(_l) + (_l)->ifam_data_off) +#define IFA_MSGHDRL_RTA(_l) \ + (void *)((uintptr_t)(_l) + (_l)->ifam_len) +struct ifa_msghdrl { + u_short ifam_msglen; /* to skip over non-understood messages */ + u_char ifam_version; /* future binary compatibility */ + u_char ifam_type; /* message type */ + int ifam_addrs; /* like rtm_addrs */ + int ifam_flags; /* value of ifa_flags */ + u_short ifam_index; /* index for associated ifp */ + u_short _ifam_spare1; /* spare space to grow if_index, see if_var.h */ + u_short ifam_len; /* length of ifa_msghdrl incl. if_data */ + u_short ifam_data_off; /* offset of if_data from beginning */ + int ifam_metric; /* value of ifa_ifp->if_metric */ + struct if_data ifam_data;/* statistics and other data about if or + * address */ +}; + +/* + * Message format for use in obtaining information about multicast addresses + * from the routing socket + */ +struct ifma_msghdr { + u_short ifmam_msglen; /* to skip over non-understood messages */ + u_char ifmam_version; /* future binary compatibility */ + u_char ifmam_type; /* message type */ + int ifmam_addrs; /* like rtm_addrs */ + int ifmam_flags; /* value of ifa_flags */ + u_short ifmam_index; /* index for associated ifp */ +}; + +/* + * Message format announcing the arrival or departure of a network interface. + */ +struct if_announcemsghdr { + u_short ifan_msglen; /* to skip over non-understood messages */ + u_char ifan_version; /* future binary compatibility */ + u_char ifan_type; /* message type */ + u_short ifan_index; /* index for associated ifp */ + char ifan_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + u_short ifan_what; /* what type of announcement */ +}; + +#define IFAN_ARRIVAL 0 /* interface arrival */ +#define IFAN_DEPARTURE 1 /* interface departure */ + +/* + * Buffer with length to be used in SIOCGIFDESCR/SIOCSIFDESCR requests + */ +struct ifreq_buffer { + size_t length; + void *buffer; +}; + +/* + * Interface request structure used for socket + * ioctl's. All interface ioctl's must have parameter + * definitions which begin with ifr_name. The + * remainder may be interface specific. + */ +struct ifreq { + char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + union { + struct sockaddr ifr_addr; /* address */ + struct sockaddr ifr_dstaddr; /* other end of p-to-p link */ + struct sockaddr ifr_broadaddr; /* broadcast address */ + struct ifreq_buffer ifr_buffer; /* user supplied buffer with its length */ + short ifr_flags[2]; /* flags (low 16 bits) */ + short ifr_index; /* interface index */ + int ifr_jid; /* jail/vnet */ + int ifr_metric; /* metric */ + int ifr_mtu; /* mtu */ + int ifr_phys; /* physical wire */ + int ifr_media; /* physical media */ + caddr_t ifr_data; /* for use by interface */ + int ifr_cap[2]; /* requested/current capabilities */ + u_int ifr_fib; /* interface fib */ + u_char ifr_vlan_pcp; /* VLAN priority */ + }; +}; + +#define _SIZEOF_ADDR_IFREQ(ifr) \ + ((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \ + (sizeof(struct ifreq) - sizeof(struct sockaddr) + \ + (ifr).ifr_addr.sa_len) : sizeof(struct ifreq)) + +struct ifaliasreq { + char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + struct sockaddr ifra_addr; + struct sockaddr ifra_broadaddr; + struct sockaddr ifra_mask; + int ifra_vhid; +}; + +/* 9.x compat */ +struct oifaliasreq { + char ifra_name[IFNAMSIZ]; + struct sockaddr ifra_addr; + struct sockaddr ifra_broadaddr; + struct sockaddr ifra_mask; +}; + +struct ifmediareq { + char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + int ifm_current; /* current media options */ + int ifm_mask; /* don't care mask */ + int ifm_status; /* media status */ + int ifm_active; /* active options */ + int ifm_count; /* # entries in ifm_ulist array */ + int *ifm_ulist; /* media words */ +}; + +struct ifdrv { + char ifd_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + unsigned long ifd_cmd; + size_t ifd_len; + void *ifd_data; +}; + +/* + * Structure used to retrieve aux status data from interfaces. + * Kernel suppliers to this interface should respect the formatting + * needed by ifconfig(8): each line starts with a TAB and ends with + * a newline. The canonical example to copy and paste is in if_tun.c. + */ + +#define IFSTATMAX 800 /* 10 lines of text */ +struct ifstat { + char ifs_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + char ascii[IFSTATMAX + 1]; +}; + +/* + * Structure used in SIOCGIFCONF request. + * Used to retrieve interface configuration + * for machine (useful for programs which + * must know all networks accessible). + */ +struct ifconf { + int ifc_len; /* size of associated buffer */ + union { + caddr_t ifc_buf; /* buffer address */ + struct ifreq *ifc_req; /* array of structures returned */ + }; +}; + +/* + * interface groups + */ + +#define IFG_ALL "all" /* group contains all interfaces */ +/* XXX: will we implement this? */ +#define IFG_EGRESS "egress" /* if(s) default route(s) point to */ + +struct ifg_req { + union { + char ifgrq_group[IFNAMSIZ]; + char ifgrq_member[IFNAMSIZ]; + }; +}; + +/* + * Used to lookup groups for an interface + */ +struct ifgroupreq { + char ifgr_name[IFNAMSIZ]; + u_int ifgr_len; + union { + char ifgr_group[IFNAMSIZ]; + struct ifg_req *ifgr_groups; + }; +}; + +/* + * Structure used to request i2c data + * from interface transceivers. + */ +struct ifi2creq { + uint8_t dev_addr; /* i2c address (0xA0, 0xA2) */ + uint8_t offset; /* read offset */ + uint8_t len; /* read length */ + uint8_t spare0; + uint32_t spare1; + uint8_t data[8]; /* read buffer */ +}; + +/* + * RSS hash. + */ + +#define RSS_FUNC_NONE 0 /* RSS disabled */ +#define RSS_FUNC_PRIVATE 1 /* non-standard */ +#define RSS_FUNC_TOEPLITZ 2 + +#define RSS_TYPE_IPV4 0x00000001 +#define RSS_TYPE_TCP_IPV4 0x00000002 +#define RSS_TYPE_IPV6 0x00000004 +#define RSS_TYPE_IPV6_EX 0x00000008 +#define RSS_TYPE_TCP_IPV6 0x00000010 +#define RSS_TYPE_TCP_IPV6_EX 0x00000020 +#define RSS_TYPE_UDP_IPV4 0x00000040 +#define RSS_TYPE_UDP_IPV6 0x00000080 +#define RSS_TYPE_UDP_IPV6_EX 0x00000100 + +#define RSS_KEYLEN 128 + +struct ifrsskey { + char ifrk_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + uint8_t ifrk_func; /* RSS_FUNC_ */ + uint8_t ifrk_spare0; + uint16_t ifrk_keylen; + uint8_t ifrk_key[RSS_KEYLEN]; +}; + +struct ifrsshash { + char ifrh_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + uint8_t ifrh_func; /* RSS_FUNC_ */ + uint8_t ifrh_spare0; + uint16_t ifrh_spare1; + uint32_t ifrh_types; /* RSS_TYPE_ */ +}; + +#endif /* __BSD_VISIBLE */ + + +struct if_nameindex { + unsigned int if_index; /* 1, 2, ... */ + char *if_name; /* null terminated name: "le0", ... */ +}; + +/* +__BEGIN_DECLS +void if_freenameindex(struct if_nameindex *); +char *if_indextoname(unsigned int, char *); +struct if_nameindex *if_nameindex(void); +unsigned int if_nametoindex(const char *); +__END_DECLS */ + +#endif /* !_NET_IF_H_ */ diff --git a/nx/external/bsd/include/net/if_arp.h b/nx/external/bsd/include/net/if_arp.h new file mode 100644 index 00000000..baaadefd --- /dev/null +++ b/nx/external/bsd/include/net/if_arp.h @@ -0,0 +1,118 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * @(#)if_arp.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD$ + */ + +#ifndef _NET_IF_ARP_H_ +#define _NET_IF_ARP_H_ + +/* + * Address Resolution Protocol. + * + * See RFC 826 for protocol description. ARP packets are variable + * in size; the arphdr structure defines the fixed-length portion. + * Protocol type values are the same as those for 10 Mb/s Ethernet. + * It is followed by the variable-sized fields ar_sha, arp_spa, + * arp_tha and arp_tpa in that order, according to the lengths + * specified. Field names used correspond to RFC 826. + */ +struct arphdr { + u_short ar_hrd; /* format of hardware address */ +#define ARPHRD_ETHER 1 /* ethernet hardware format */ +#define ARPHRD_IEEE802 6 /* token-ring hardware format */ +#define ARPHRD_ARCNET 7 /* arcnet hardware format */ +#define ARPHRD_FRELAY 15 /* frame relay hardware format */ +#define ARPHRD_IEEE1394 24 /* firewire hardware format */ +#define ARPHRD_INFINIBAND 32 /* infiniband hardware format */ + u_short ar_pro; /* format of protocol address */ + u_char ar_hln; /* length of hardware address */ + u_char ar_pln; /* length of protocol address */ + u_short ar_op; /* one of: */ +#define ARPOP_REQUEST 1 /* request to resolve address */ +#define ARPOP_REPLY 2 /* response to previous request */ +#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */ +#define ARPOP_REVREPLY 4 /* response giving protocol address */ +#define ARPOP_INVREQUEST 8 /* request to identify peer */ +#define ARPOP_INVREPLY 9 /* response identifying peer */ +/* + * The remaining fields are variable in size, + * according to the sizes above. + */ +#ifdef COMMENT_ONLY + u_char ar_sha[]; /* sender hardware address */ + u_char ar_spa[]; /* sender protocol address */ + u_char ar_tha[]; /* target hardware address */ + u_char ar_tpa[]; /* target protocol address */ +#endif +}; + +#define ar_sha(ap) (((caddr_t)((ap)+1)) + 0) +#define ar_spa(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln) +#define ar_tha(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln + (ap)->ar_pln) +#define ar_tpa(ap) (((caddr_t)((ap)+1)) + 2*(ap)->ar_hln + (ap)->ar_pln) + +#define arphdr_len2(ar_hln, ar_pln) \ + (sizeof(struct arphdr) + 2*(ar_hln) + 2*(ar_pln)) +#define arphdr_len(ap) (arphdr_len2((ap)->ar_hln, (ap)->ar_pln)) + +/* + * ARP ioctl request + */ +struct arpreq { + struct sockaddr arp_pa; /* protocol address */ + struct sockaddr arp_ha; /* hardware address */ + int arp_flags; /* flags */ +}; +/* arp_flags and at_flags field values */ +#define ATF_INUSE 0x01 /* entry in use */ +#define ATF_COM 0x02 /* completed entry (enaddr valid) */ +#define ATF_PERM 0x04 /* permanent entry */ +#define ATF_PUBL 0x08 /* publish entry (respond for other host) */ +#define ATF_USETRAILERS 0x10 /* has requested trailers */ + +struct arpstat { + /* Normal things that happen: */ + uint64_t txrequests; /* # of ARP requests sent by this host. */ + uint64_t txreplies; /* # of ARP replies sent by this host. */ + uint64_t rxrequests; /* # of ARP requests received by this host. */ + uint64_t rxreplies; /* # of ARP replies received by this host. */ + uint64_t received; /* # of ARP packets received by this host. */ + + uint64_t arp_spares[4]; /* For either the upper or lower half. */ + /* Abnormal event and error counting: */ + uint64_t dropped; /* # of packets dropped waiting for a reply. */ + uint64_t timeouts; /* # of times with entries removed */ + /* due to timeout. */ + uint64_t dupips; /* # of duplicate IPs detected. */ +}; + +#endif /* !_NET_IF_ARP_H_ */ diff --git a/nx/external/bsd/include/net/if_dl.h b/nx/external/bsd/include/net/if_dl.h new file mode 100644 index 00000000..aff0ad69 --- /dev/null +++ b/nx/external/bsd/include/net/if_dl.h @@ -0,0 +1,91 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * @(#)if_dl.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD$ + */ + +#ifndef _NET_IF_DL_H_ +#define _NET_IF_DL_H_ + +#include // changed + +/* + * A Link-Level Sockaddr may specify the interface in one of two + * ways: either by means of a system-provided index number (computed + * anew and possibly differently on every reboot), or by a human-readable + * string such as "il0" (for managerial convenience). + * + * Census taking actions, such as something akin to SIOCGCONF would return + * both the index and the human name. + * + * High volume transactions (such as giving a link-level ``from'' address + * in a recvfrom or recvmsg call) may be likely only to provide the indexed + * form, (which requires fewer copy operations and less space). + * + * The form and interpretation of the link-level address is purely a matter + * of convention between the device driver and its consumers; however, it is + * expected that all drivers for an interface of a given if_type will agree. + */ + +/* + * Structure of a Link-Level sockaddr: + */ +struct sockaddr_dl { + u_char sdl_len; /* Total length of sockaddr */ + u_char sdl_family; /* AF_LINK */ + u_short sdl_index; /* if != 0, system given index for interface */ + u_char sdl_type; /* interface type */ + u_char sdl_nlen; /* interface name length, no trailing 0 reqd. */ + u_char sdl_alen; /* link level address length */ + u_char sdl_slen; /* link layer selector length */ + char sdl_data[46]; /* minimum work area, can be larger; + contains both if name and ll address */ +}; + +#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen)) +#define CLLADDR(s) ((c_caddr_t)((s)->sdl_data + (s)->sdl_nlen)) +#define LLINDEX(s) ((s)->sdl_index) + + +struct ifnet; +/*struct sockaddr_dl *link_alloc_sdl(size_t, int); +void link_free_sdl(struct sockaddr *sa); +struct sockaddr_dl *link_init_sdl(struct ifnet *, struct sockaddr *, u_char);*/ + +#include + +/* +__BEGIN_DECLS +void link_addr(const char *, struct sockaddr_dl *); +char *link_ntoa(const struct sockaddr_dl *); +__END_DECLS */ + +#endif diff --git a/nx/external/bsd/include/net/if_media.h b/nx/external/bsd/include/net/if_media.h new file mode 100644 index 00000000..a1768676 --- /dev/null +++ b/nx/external/bsd/include/net/if_media.h @@ -0,0 +1,794 @@ +/* $NetBSD: if_media.h,v 1.3 1997/03/26 01:19:27 thorpej Exp $ */ +/* $FreeBSD$ */ + +/*- + * SPDX-License-Identifier: BSD-4-Clause + * + * Copyright (c) 1997 + * Jonathan Stone and Jason R. Thorpe. All rights reserved. + * + * This software is derived from information provided by Matt Thomas. + * + * 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 Jonathan Stone + * and Jason R. Thorpe for the NetBSD Project. + * 4. The names of the authors may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHOR 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. + */ + +#ifndef _NET_IF_MEDIA_H_ +#define _NET_IF_MEDIA_H_ + +/* + * Prototypes and definitions for BSD/OS-compatible network interface + * media selection. + * + * Where it is safe to do so, this code strays slightly from the BSD/OS + * design. Software which uses the API (device drivers, basically) + * shouldn't notice any difference. + * + * Many thanks to Matt Thomas for providing the information necessary + * to implement this interface. +*/ + +/* + * if_media Options word: + * Bits Use + * ---- ------- + * 0-4 Media variant + * 5-7 Media type + * 8-15 Type specific options (includes added variant bits on Ethernet) + * 16-18 Mode (for multi-mode devices) + * 19 RFU + * 20-27 Shared (global) options + * 28-31 Instance + */ + +/* + * Ethernet + * In order to use more than 31 subtypes, Ethernet uses some of the option + * bits as part of the subtype field. See the options section below for + * relevant definitions + */ +#define IFM_ETHER 0x00000020 +#define IFM_ETHER_SUBTYPE(x) (((x) & IFM_TMASK) | \ + (((x) & (IFM_ETH_XTYPE >> IFM_ETH_XSHIFT)) << IFM_ETH_XSHIFT)) +#define IFM_X(x) IFM_ETHER_SUBTYPE(x) /* internal shorthand */ +#define IFM_ETHER_SUBTYPE_SET(x) (IFM_ETHER_SUBTYPE(x) | IFM_ETHER) +#define IFM_ETHER_SUBTYPE_GET(x) ((x) & (IFM_TMASK|IFM_ETH_XTYPE)) +#define IFM_ETHER_IS_EXTENDED(x) ((x) & IFM_ETH_XTYPE) + +#define IFM_10_T 3 /* 10BaseT - RJ45 */ +#define IFM_10_2 4 /* 10Base2 - Thinnet */ +#define IFM_10_5 5 /* 10Base5 - AUI */ +#define IFM_100_TX 6 /* 100BaseTX - RJ45 */ +#define IFM_100_FX 7 /* 100BaseFX - Fiber */ +#define IFM_100_T4 8 /* 100BaseT4 - 4 pair cat 3 */ +#define IFM_100_VG 9 /* 100VG-AnyLAN */ +#define IFM_100_T2 10 /* 100BaseT2 */ +#define IFM_1000_SX 11 /* 1000BaseSX - multi-mode fiber */ +#define IFM_10_STP 12 /* 10BaseT over shielded TP */ +#define IFM_10_FL 13 /* 10BaseFL - Fiber */ +#define IFM_1000_LX 14 /* 1000baseLX - single-mode fiber */ +#define IFM_1000_CX 15 /* 1000baseCX - 150ohm STP */ +#define IFM_1000_T 16 /* 1000baseT - 4 pair cat 5 */ +#define IFM_HPNA_1 17 /* HomePNA 1.0 (1Mb/s) */ +#define IFM_10G_LR 18 /* 10GBase-LR 1310nm Single-mode */ +#define IFM_10G_SR 19 /* 10GBase-SR 850nm Multi-mode */ +#define IFM_10G_CX4 20 /* 10GBase CX4 copper */ +#define IFM_2500_SX 21 /* 2500BaseSX - multi-mode fiber */ +#define IFM_10G_TWINAX 22 /* 10GBase Twinax copper */ +#define IFM_10G_TWINAX_LONG 23 /* 10GBase Twinax Long copper */ +#define IFM_10G_LRM 24 /* 10GBase-LRM 850nm Multi-mode */ +#define IFM_UNKNOWN 25 /* media types not defined yet */ +#define IFM_10G_T 26 /* 10GBase-T - RJ45 */ +#define IFM_40G_CR4 27 /* 40GBase-CR4 */ +#define IFM_40G_SR4 28 /* 40GBase-SR4 */ +#define IFM_40G_LR4 29 /* 40GBase-LR4 */ +#define IFM_1000_KX 30 /* 1000Base-KX backplane */ +#define IFM_OTHER 31 /* Other: one of the following */ + +/* following types are not visible to old binaries using only IFM_TMASK */ +#define IFM_10G_KX4 IFM_X(32) /* 10GBase-KX4 backplane */ +#define IFM_10G_KR IFM_X(33) /* 10GBase-KR backplane */ +#define IFM_10G_CR1 IFM_X(34) /* 10GBase-CR1 Twinax splitter */ +#define IFM_20G_KR2 IFM_X(35) /* 20GBase-KR2 backplane */ +#define IFM_2500_KX IFM_X(36) /* 2500Base-KX backplane */ +#define IFM_2500_T IFM_X(37) /* 2500Base-T - RJ45 (NBaseT) */ +#define IFM_5000_T IFM_X(38) /* 5000Base-T - RJ45 (NBaseT) */ +#define IFM_50G_PCIE IFM_X(39) /* 50G Ethernet over PCIE */ +#define IFM_25G_PCIE IFM_X(40) /* 25G Ethernet over PCIE */ +#define IFM_1000_SGMII IFM_X(41) /* 1G media interface */ +#define IFM_10G_SFI IFM_X(42) /* 10G media interface */ +#define IFM_40G_XLPPI IFM_X(43) /* 40G media interface */ +#define IFM_1000_CX_SGMII IFM_X(44) /* 1000Base-CX-SGMII */ +#define IFM_40G_KR4 IFM_X(45) /* 40GBase-KR4 */ +#define IFM_10G_ER IFM_X(46) /* 10GBase-ER */ +#define IFM_100G_CR4 IFM_X(47) /* 100GBase-CR4 */ +#define IFM_100G_SR4 IFM_X(48) /* 100GBase-SR4 */ +#define IFM_100G_KR4 IFM_X(49) /* 100GBase-KR4 */ +#define IFM_100G_LR4 IFM_X(50) /* 100GBase-LR4 */ +#define IFM_56G_R4 IFM_X(51) /* 56GBase-R4 */ +#define IFM_100_T IFM_X(52) /* 100BaseT - RJ45 */ +#define IFM_25G_CR IFM_X(53) /* 25GBase-CR */ +#define IFM_25G_KR IFM_X(54) /* 25GBase-KR */ +#define IFM_25G_SR IFM_X(55) /* 25GBase-SR */ +#define IFM_50G_CR2 IFM_X(56) /* 50GBase-CR2 */ +#define IFM_50G_KR2 IFM_X(57) /* 50GBase-KR2 */ +#define IFM_25G_LR IFM_X(58) /* 25GBase-LR */ +#define IFM_10G_AOC IFM_X(59) /* 10G active optical cable */ +#define IFM_25G_ACC IFM_X(60) /* 25G active copper cable */ +#define IFM_25G_AOC IFM_X(61) /* 25G active optical cable */ + +/* + * Please update ieee8023ad_lacp.c:lacp_compose_key() + * after adding new Ethernet media types. + */ +/* Note IFM_X(511) is the max! */ + +/* Ethernet option values; includes bits used for extended variant field */ +#define IFM_ETH_MASTER 0x00000100 /* master mode (1000baseT) */ +#define IFM_ETH_RXPAUSE 0x00000200 /* receive PAUSE frames */ +#define IFM_ETH_TXPAUSE 0x00000400 /* transmit PAUSE frames */ +#define IFM_ETH_XTYPE 0x00007800 /* extended media variants */ +#define IFM_ETH_XSHIFT 6 /* shift XTYPE next to TMASK */ + +/* + * Token ring + */ +#define IFM_TOKEN 0x00000040 +#define IFM_TOK_STP4 3 /* Shielded twisted pair 4m - DB9 */ +#define IFM_TOK_STP16 4 /* Shielded twisted pair 16m - DB9 */ +#define IFM_TOK_UTP4 5 /* Unshielded twisted pair 4m - RJ45 */ +#define IFM_TOK_UTP16 6 /* Unshielded twisted pair 16m - RJ45 */ +#define IFM_TOK_STP100 7 /* Shielded twisted pair 100m - DB9 */ +#define IFM_TOK_UTP100 8 /* Unshielded twisted pair 100m - RJ45 */ +#define IFM_TOK_ETR 0x00000200 /* Early token release */ +#define IFM_TOK_SRCRT 0x00000400 /* Enable source routing features */ +#define IFM_TOK_ALLR 0x00000800 /* All routes / Single route bcast */ +#define IFM_TOK_DTR 0x00002000 /* Dedicated token ring */ +#define IFM_TOK_CLASSIC 0x00004000 /* Classic token ring */ +#define IFM_TOK_AUTO 0x00008000 /* Automatic Dedicate/Classic token ring */ + +/* + * FDDI + */ +#define IFM_FDDI 0x00000060 +#define IFM_FDDI_SMF 3 /* Single-mode fiber */ +#define IFM_FDDI_MMF 4 /* Multi-mode fiber */ +#define IFM_FDDI_UTP 5 /* CDDI / UTP */ +#define IFM_FDDI_DA 0x00000100 /* Dual attach / single attach */ + +/* + * IEEE 802.11 Wireless + */ +#define IFM_IEEE80211 0x00000080 +/* NB: 0,1,2 are auto, manual, none defined below */ +#define IFM_IEEE80211_FH1 3 /* Frequency Hopping 1Mbps */ +#define IFM_IEEE80211_FH2 4 /* Frequency Hopping 2Mbps */ +#define IFM_IEEE80211_DS1 5 /* Direct Sequence 1Mbps */ +#define IFM_IEEE80211_DS2 6 /* Direct Sequence 2Mbps */ +#define IFM_IEEE80211_DS5 7 /* Direct Sequence 5.5Mbps */ +#define IFM_IEEE80211_DS11 8 /* Direct Sequence 11Mbps */ +#define IFM_IEEE80211_DS22 9 /* Direct Sequence 22Mbps */ +#define IFM_IEEE80211_OFDM6 10 /* OFDM 6Mbps */ +#define IFM_IEEE80211_OFDM9 11 /* OFDM 9Mbps */ +#define IFM_IEEE80211_OFDM12 12 /* OFDM 12Mbps */ +#define IFM_IEEE80211_OFDM18 13 /* OFDM 18Mbps */ +#define IFM_IEEE80211_OFDM24 14 /* OFDM 24Mbps */ +#define IFM_IEEE80211_OFDM36 15 /* OFDM 36Mbps */ +#define IFM_IEEE80211_OFDM48 16 /* OFDM 48Mbps */ +#define IFM_IEEE80211_OFDM54 17 /* OFDM 54Mbps */ +#define IFM_IEEE80211_OFDM72 18 /* OFDM 72Mbps */ +#define IFM_IEEE80211_DS354k 19 /* Direct Sequence 354Kbps */ +#define IFM_IEEE80211_DS512k 20 /* Direct Sequence 512Kbps */ +#define IFM_IEEE80211_OFDM3 21 /* OFDM 3Mbps */ +#define IFM_IEEE80211_OFDM4 22 /* OFDM 4.5Mbps */ +#define IFM_IEEE80211_OFDM27 23 /* OFDM 27Mbps */ +/* NB: not enough bits to express MCS fully */ +#define IFM_IEEE80211_MCS 24 /* HT MCS rate */ +#define IFM_IEEE80211_VHT 25 /* HT MCS rate */ + +#define IFM_IEEE80211_ADHOC 0x00000100 /* Operate in Adhoc mode */ +#define IFM_IEEE80211_HOSTAP 0x00000200 /* Operate in Host AP mode */ +#define IFM_IEEE80211_IBSS 0x00000400 /* Operate in IBSS mode */ +#define IFM_IEEE80211_WDS 0x00000800 /* Operate in WDS mode */ +#define IFM_IEEE80211_TURBO 0x00001000 /* Operate in turbo mode */ +#define IFM_IEEE80211_MONITOR 0x00002000 /* Operate in monitor mode */ +#define IFM_IEEE80211_MBSS 0x00004000 /* Operate in MBSS mode */ + +/* operating mode for multi-mode devices */ +#define IFM_IEEE80211_11A 0x00010000 /* 5Ghz, OFDM mode */ +#define IFM_IEEE80211_11B 0x00020000 /* Direct Sequence mode */ +#define IFM_IEEE80211_11G 0x00030000 /* 2Ghz, CCK mode */ +#define IFM_IEEE80211_FH 0x00040000 /* 2Ghz, GFSK mode */ +#define IFM_IEEE80211_11NA 0x00050000 /* 5Ghz, HT mode */ +#define IFM_IEEE80211_11NG 0x00060000 /* 2Ghz, HT mode */ +#define IFM_IEEE80211_VHT5G 0x00070000 /* 5Ghz, VHT mode */ +#define IFM_IEEE80211_VHT2G 0x00080000 /* 2Ghz, VHT mode */ + +/* + * ATM + */ +#define IFM_ATM 0x000000a0 +#define IFM_ATM_UNKNOWN 3 +#define IFM_ATM_UTP_25 4 +#define IFM_ATM_TAXI_100 5 +#define IFM_ATM_TAXI_140 6 +#define IFM_ATM_MM_155 7 +#define IFM_ATM_SM_155 8 +#define IFM_ATM_UTP_155 9 +#define IFM_ATM_MM_622 10 +#define IFM_ATM_SM_622 11 +#define IFM_ATM_VIRTUAL 12 +#define IFM_ATM_SDH 0x00000100 /* SDH instead of SONET */ +#define IFM_ATM_NOSCRAMB 0x00000200 /* no scrambling */ +#define IFM_ATM_UNASSIGNED 0x00000400 /* unassigned cells */ + +/* + * Shared media sub-types + */ +#define IFM_AUTO 0 /* Autoselect best media */ +#define IFM_MANUAL 1 /* Jumper/dipswitch selects media */ +#define IFM_NONE 2 /* Deselect all media */ + +/* + * Shared options + */ +#define IFM_FDX 0x00100000 /* Force full duplex */ +#define IFM_HDX 0x00200000 /* Force half duplex */ +#define IFM_FLOW 0x00400000 /* enable hardware flow control */ +#define IFM_FLAG0 0x01000000 /* Driver defined flag */ +#define IFM_FLAG1 0x02000000 /* Driver defined flag */ +#define IFM_FLAG2 0x04000000 /* Driver defined flag */ +#define IFM_LOOP 0x08000000 /* Put hardware in loopback */ + +/* + * Masks + */ +#define IFM_NMASK 0x000000e0 /* Network type */ +#define IFM_TMASK 0x0000001f /* Media sub-type */ +#define IFM_IMASK 0xf0000000 /* Instance */ +#define IFM_ISHIFT 28 /* Instance shift */ +#define IFM_OMASK 0x0000ff00 /* Type specific options */ +#define IFM_MMASK 0x00070000 /* Mode */ +#define IFM_MSHIFT 16 /* Mode shift */ +#define IFM_GMASK 0x0ff00000 /* Global options */ + +/* Ethernet flow control mask */ +#define IFM_ETH_FMASK (IFM_FLOW | IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE) + +/* + * Status bits + */ +#define IFM_AVALID 0x00000001 /* Active bit valid */ +#define IFM_ACTIVE 0x00000002 /* Interface attached to working net */ + +/* Mask of "status valid" bits, for ifconfig(8). */ +#define IFM_STATUS_VALID IFM_AVALID + +/* List of "status valid" bits, for ifconfig(8). */ +#define IFM_STATUS_VALID_LIST { \ + IFM_AVALID, \ + 0 \ +} + +/* + * Macros to extract various bits of information from the media word. + */ +#define IFM_TYPE(x) ((x) & IFM_NMASK) +#define IFM_SUBTYPE(x) \ + (IFM_TYPE(x) == IFM_ETHER ? IFM_ETHER_SUBTYPE_GET(x) : ((x) & IFM_TMASK)) +#define IFM_TYPE_MATCH(x,y) \ + (IFM_TYPE(x) == IFM_TYPE(y) && IFM_SUBTYPE(x) == IFM_SUBTYPE(y)) +#define IFM_TYPE_OPTIONS(x) ((x) & IFM_OMASK) +#define IFM_INST(x) (((x) & IFM_IMASK) >> IFM_ISHIFT) +#define IFM_OPTIONS(x) ((x) & (IFM_OMASK | IFM_GMASK)) +#define IFM_MODE(x) ((x) & IFM_MMASK) + +#define IFM_INST_MAX IFM_INST(IFM_IMASK) + +/* + * Macro to create a media word. + */ +#define IFM_MAKEWORD(type, subtype, options, instance) \ + ((type) | (subtype) | (options) | ((instance) << IFM_ISHIFT)) +#define IFM_MAKEMODE(mode) \ + (((mode) << IFM_MSHIFT) & IFM_MMASK) + +/* + * NetBSD extension not defined in the BSDI API. This is used in various + * places to get the canonical description for a given type/subtype. + * + * NOTE: all but the top-level type descriptions must contain NO whitespace! + * Otherwise, parsing these in ifconfig(8) would be a nightmare. + */ +struct ifmedia_description { + int ifmt_word; /* word value; may be masked */ + const char *ifmt_string; /* description */ +}; + +#define IFM_TYPE_DESCRIPTIONS { \ + { IFM_ETHER, "Ethernet" }, \ + { IFM_TOKEN, "Token ring" }, \ + { IFM_FDDI, "FDDI" }, \ + { IFM_IEEE80211, "IEEE 802.11 Wireless Ethernet" }, \ + { IFM_ATM, "ATM" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_ETHERNET_DESCRIPTIONS { \ + { IFM_10_T, "10baseT/UTP" }, \ + { IFM_10_2, "10base2/BNC" }, \ + { IFM_10_5, "10base5/AUI" }, \ + { IFM_100_TX, "100baseTX" }, \ + { IFM_100_FX, "100baseFX" }, \ + { IFM_100_T4, "100baseT4" }, \ + { IFM_100_VG, "100baseVG" }, \ + { IFM_100_T2, "100baseT2" }, \ + { IFM_10_STP, "10baseSTP" }, \ + { IFM_10_FL, "10baseFL" }, \ + { IFM_1000_SX, "1000baseSX" }, \ + { IFM_1000_LX, "1000baseLX" }, \ + { IFM_1000_CX, "1000baseCX" }, \ + { IFM_1000_T, "1000baseT" }, \ + { IFM_HPNA_1, "homePNA" }, \ + { IFM_10G_LR, "10Gbase-LR" }, \ + { IFM_10G_SR, "10Gbase-SR" }, \ + { IFM_10G_CX4, "10Gbase-CX4" }, \ + { IFM_2500_SX, "2500BaseSX" }, \ + { IFM_10G_LRM, "10Gbase-LRM" }, \ + { IFM_10G_TWINAX, "10Gbase-Twinax" }, \ + { IFM_10G_TWINAX_LONG, "10Gbase-Twinax-Long" }, \ + { IFM_UNKNOWN, "Unknown" }, \ + { IFM_10G_T, "10Gbase-T" }, \ + { IFM_40G_CR4, "40Gbase-CR4" }, \ + { IFM_40G_SR4, "40Gbase-SR4" }, \ + { IFM_40G_LR4, "40Gbase-LR4" }, \ + { IFM_1000_KX, "1000Base-KX" }, \ + { IFM_OTHER, "Other" }, \ + { IFM_10G_KX4, "10GBase-KX4" }, \ + { IFM_10G_KR, "10GBase-KR" }, \ + { IFM_10G_CR1, "10GBase-CR1" }, \ + { IFM_20G_KR2, "20GBase-KR2" }, \ + { IFM_2500_KX, "2500Base-KX" }, \ + { IFM_2500_T, "2500Base-T" }, \ + { IFM_5000_T, "5000Base-T" }, \ + { IFM_50G_PCIE, "PCIExpress-50G" }, \ + { IFM_25G_PCIE, "PCIExpress-25G" }, \ + { IFM_1000_SGMII, "1000Base-SGMII" }, \ + { IFM_10G_SFI, "10GBase-SFI" }, \ + { IFM_40G_XLPPI, "40GBase-XLPPI" }, \ + { IFM_1000_CX_SGMII, "1000Base-CX-SGMII" }, \ + { IFM_40G_KR4, "40GBase-KR4" }, \ + { IFM_10G_ER, "10GBase-ER" }, \ + { IFM_100G_CR4, "100GBase-CR4" }, \ + { IFM_100G_SR4, "100GBase-SR4" }, \ + { IFM_100G_KR4, "100GBase-KR4" }, \ + { IFM_100G_LR4, "100GBase-LR4" }, \ + { IFM_56G_R4, "56GBase-R4" }, \ + { IFM_100_T, "100BaseT" }, \ + { IFM_25G_CR, "25GBase-CR" }, \ + { IFM_25G_KR, "25GBase-KR" }, \ + { IFM_25G_SR, "25GBase-SR" }, \ + { IFM_50G_CR2, "50GBase-CR2" }, \ + { IFM_50G_KR2, "50GBase-KR2" }, \ + { IFM_25G_LR, "25GBase-LR" }, \ + { IFM_10G_AOC, "10GBase-AOC" }, \ + { IFM_25G_ACC, "25GBase-ACC" }, \ + { IFM_25G_AOC, "25GBase-AOC" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_ETHERNET_ALIASES { \ + { IFM_10_T, "10baseT" }, \ + { IFM_10_T, "UTP" }, \ + { IFM_10_T, "10UTP" }, \ + { IFM_10_2, "BNC" }, \ + { IFM_10_2, "10BNC" }, \ + { IFM_10_5, "AUI" }, \ + { IFM_10_5, "10AUI" }, \ + { IFM_100_TX, "100TX" }, \ + { IFM_100_T4, "100T4" }, \ + { IFM_100_VG, "100VG" }, \ + { IFM_100_T2, "100T2" }, \ + { IFM_10_STP, "10STP" }, \ + { IFM_10_FL, "10FL" }, \ + { IFM_1000_SX, "1000SX" }, \ + { IFM_1000_LX, "1000LX" }, \ + { IFM_1000_CX, "1000CX" }, \ + { IFM_1000_T, "1000baseTX" }, \ + { IFM_1000_T, "1000TX" }, \ + { IFM_1000_T, "1000T" }, \ + { IFM_2500_SX, "2500SX" }, \ + \ + /* \ + * Shorthands for common media+option combinations as announced \ + * by miibus(4) \ + */ \ + { IFM_10_T | IFM_FDX, "10baseT-FDX" }, \ + { IFM_10_T | IFM_FDX | IFM_FLOW, "10baseT-FDX-flow" }, \ + { IFM_100_TX | IFM_FDX, "100baseTX-FDX" }, \ + { IFM_100_TX | IFM_FDX | IFM_FLOW, "100baseTX-FDX-flow" }, \ + { IFM_1000_T | IFM_FDX, "1000baseT-FDX" }, \ + { IFM_1000_T | IFM_FDX | IFM_FLOW, "1000baseT-FDX-flow" }, \ + { IFM_1000_T | IFM_FDX | IFM_FLOW | IFM_ETH_MASTER, \ + "1000baseT-FDX-flow-master" }, \ + { IFM_1000_T | IFM_FDX | IFM_ETH_MASTER, \ + "1000baseT-FDX-master" }, \ + { IFM_1000_T | IFM_ETH_MASTER, "1000baseT-master" }, \ + \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS { \ + { IFM_ETH_MASTER, "master" }, \ + { IFM_ETH_RXPAUSE, "rxpause" }, \ + { IFM_ETH_TXPAUSE, "txpause" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_TOKENRING_DESCRIPTIONS { \ + { IFM_TOK_STP4, "DB9/4Mbit" }, \ + { IFM_TOK_STP16, "DB9/16Mbit" }, \ + { IFM_TOK_UTP4, "UTP/4Mbit" }, \ + { IFM_TOK_UTP16, "UTP/16Mbit" }, \ + { IFM_TOK_STP100, "STP/100Mbit" }, \ + { IFM_TOK_UTP100, "UTP/100Mbit" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_TOKENRING_ALIASES { \ + { IFM_TOK_STP4, "4STP" }, \ + { IFM_TOK_STP16, "16STP" }, \ + { IFM_TOK_UTP4, "4UTP" }, \ + { IFM_TOK_UTP16, "16UTP" }, \ + { IFM_TOK_STP100, "100STP" }, \ + { IFM_TOK_UTP100, "100UTP" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS { \ + { IFM_TOK_ETR, "EarlyTokenRelease" }, \ + { IFM_TOK_SRCRT, "SourceRouting" }, \ + { IFM_TOK_ALLR, "AllRoutes" }, \ + { IFM_TOK_DTR, "Dedicated" }, \ + { IFM_TOK_CLASSIC,"Classic" }, \ + { IFM_TOK_AUTO, " " }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_FDDI_DESCRIPTIONS { \ + { IFM_FDDI_SMF, "Single-mode" }, \ + { IFM_FDDI_MMF, "Multi-mode" }, \ + { IFM_FDDI_UTP, "UTP" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_FDDI_ALIASES { \ + { IFM_FDDI_SMF, "SMF" }, \ + { IFM_FDDI_MMF, "MMF" }, \ + { IFM_FDDI_UTP, "CDDI" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS { \ + { IFM_FDDI_DA, "Dual-attach" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_IEEE80211_DESCRIPTIONS { \ + { IFM_IEEE80211_FH1, "FH/1Mbps" }, \ + { IFM_IEEE80211_FH2, "FH/2Mbps" }, \ + { IFM_IEEE80211_DS1, "DS/1Mbps" }, \ + { IFM_IEEE80211_DS2, "DS/2Mbps" }, \ + { IFM_IEEE80211_DS5, "DS/5.5Mbps" }, \ + { IFM_IEEE80211_DS11, "DS/11Mbps" }, \ + { IFM_IEEE80211_DS22, "DS/22Mbps" }, \ + { IFM_IEEE80211_OFDM6, "OFDM/6Mbps" }, \ + { IFM_IEEE80211_OFDM9, "OFDM/9Mbps" }, \ + { IFM_IEEE80211_OFDM12, "OFDM/12Mbps" }, \ + { IFM_IEEE80211_OFDM18, "OFDM/18Mbps" }, \ + { IFM_IEEE80211_OFDM24, "OFDM/24Mbps" }, \ + { IFM_IEEE80211_OFDM36, "OFDM/36Mbps" }, \ + { IFM_IEEE80211_OFDM48, "OFDM/48Mbps" }, \ + { IFM_IEEE80211_OFDM54, "OFDM/54Mbps" }, \ + { IFM_IEEE80211_OFDM72, "OFDM/72Mbps" }, \ + { IFM_IEEE80211_DS354k, "DS/354Kbps" }, \ + { IFM_IEEE80211_DS512k, "DS/512Kbps" }, \ + { IFM_IEEE80211_OFDM3, "OFDM/3Mbps" }, \ + { IFM_IEEE80211_OFDM4, "OFDM/4.5Mbps" }, \ + { IFM_IEEE80211_OFDM27, "OFDM/27Mbps" }, \ + { IFM_IEEE80211_MCS, "MCS" }, \ + { IFM_IEEE80211_VHT, "VHT" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_IEEE80211_ALIASES { \ + { IFM_IEEE80211_FH1, "FH1" }, \ + { IFM_IEEE80211_FH2, "FH2" }, \ + { IFM_IEEE80211_FH1, "FrequencyHopping/1Mbps" }, \ + { IFM_IEEE80211_FH2, "FrequencyHopping/2Mbps" }, \ + { IFM_IEEE80211_DS1, "DS1" }, \ + { IFM_IEEE80211_DS2, "DS2" }, \ + { IFM_IEEE80211_DS5, "DS5.5" }, \ + { IFM_IEEE80211_DS11, "DS11" }, \ + { IFM_IEEE80211_DS22, "DS22" }, \ + { IFM_IEEE80211_DS1, "DirectSequence/1Mbps" }, \ + { IFM_IEEE80211_DS2, "DirectSequence/2Mbps" }, \ + { IFM_IEEE80211_DS5, "DirectSequence/5.5Mbps" }, \ + { IFM_IEEE80211_DS11, "DirectSequence/11Mbps" }, \ + { IFM_IEEE80211_DS22, "DirectSequence/22Mbps" }, \ + { IFM_IEEE80211_OFDM6, "OFDM6" }, \ + { IFM_IEEE80211_OFDM9, "OFDM9" }, \ + { IFM_IEEE80211_OFDM12, "OFDM12" }, \ + { IFM_IEEE80211_OFDM18, "OFDM18" }, \ + { IFM_IEEE80211_OFDM24, "OFDM24" }, \ + { IFM_IEEE80211_OFDM36, "OFDM36" }, \ + { IFM_IEEE80211_OFDM48, "OFDM48" }, \ + { IFM_IEEE80211_OFDM54, "OFDM54" }, \ + { IFM_IEEE80211_OFDM72, "OFDM72" }, \ + { IFM_IEEE80211_DS1, "CCK1" }, \ + { IFM_IEEE80211_DS2, "CCK2" }, \ + { IFM_IEEE80211_DS5, "CCK5.5" }, \ + { IFM_IEEE80211_DS11, "CCK11" }, \ + { IFM_IEEE80211_DS354k, "DS354K" }, \ + { IFM_IEEE80211_DS354k, "DirectSequence/354Kbps" }, \ + { IFM_IEEE80211_DS512k, "DS512K" }, \ + { IFM_IEEE80211_DS512k, "DirectSequence/512Kbps" }, \ + { IFM_IEEE80211_OFDM3, "OFDM3" }, \ + { IFM_IEEE80211_OFDM4, "OFDM4.5" }, \ + { IFM_IEEE80211_OFDM27, "OFDM27" }, \ + { IFM_IEEE80211_MCS, "MCS" }, \ + { IFM_IEEE80211_VHT, "VHT" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS { \ + { IFM_IEEE80211_ADHOC, "adhoc" }, \ + { IFM_IEEE80211_HOSTAP, "hostap" }, \ + { IFM_IEEE80211_IBSS, "ibss" }, \ + { IFM_IEEE80211_WDS, "wds" }, \ + { IFM_IEEE80211_TURBO, "turbo" }, \ + { IFM_IEEE80211_MONITOR, "monitor" }, \ + { IFM_IEEE80211_MBSS, "mesh" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS { \ + { IFM_AUTO, "autoselect" }, \ + { IFM_IEEE80211_11A, "11a" }, \ + { IFM_IEEE80211_11B, "11b" }, \ + { IFM_IEEE80211_11G, "11g" }, \ + { IFM_IEEE80211_FH, "fh" }, \ + { IFM_IEEE80211_11NA, "11na" }, \ + { IFM_IEEE80211_11NG, "11ng" }, \ + { IFM_IEEE80211_VHT5G, "11ac" }, \ + { IFM_IEEE80211_VHT2G, "11ac2" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_IEEE80211_MODE_ALIASES { \ + { IFM_AUTO, "auto" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_ATM_DESCRIPTIONS { \ + { IFM_ATM_UNKNOWN, "Unknown" }, \ + { IFM_ATM_UTP_25, "UTP/25.6MBit" }, \ + { IFM_ATM_TAXI_100, "Taxi/100MBit" }, \ + { IFM_ATM_TAXI_140, "Taxi/140MBit" }, \ + { IFM_ATM_MM_155, "Multi-mode/155MBit" }, \ + { IFM_ATM_SM_155, "Single-mode/155MBit" }, \ + { IFM_ATM_UTP_155, "UTP/155MBit" }, \ + { IFM_ATM_MM_622, "Multi-mode/622MBit" }, \ + { IFM_ATM_SM_622, "Single-mode/622MBit" }, \ + { IFM_ATM_VIRTUAL, "Virtual" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_ATM_ALIASES { \ + { IFM_ATM_UNKNOWN, "UNKNOWN" }, \ + { IFM_ATM_UTP_25, "UTP-25" }, \ + { IFM_ATM_TAXI_100, "TAXI-100" }, \ + { IFM_ATM_TAXI_140, "TAXI-140" }, \ + { IFM_ATM_MM_155, "MM-155" }, \ + { IFM_ATM_SM_155, "SM-155" }, \ + { IFM_ATM_UTP_155, "UTP-155" }, \ + { IFM_ATM_MM_622, "MM-622" }, \ + { IFM_ATM_SM_622, "SM-622" }, \ + { IFM_ATM_VIRTUAL, "VIRTUAL" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS { \ + { IFM_ATM_SDH, "SDH" }, \ + { IFM_ATM_NOSCRAMB, "Noscramb" }, \ + { IFM_ATM_UNASSIGNED, "Unassigned" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_SHARED_DESCRIPTIONS { \ + { IFM_AUTO, "autoselect" }, \ + { IFM_MANUAL, "manual" }, \ + { IFM_NONE, "none" }, \ + { 0, NULL }, \ +} + +#define IFM_SUBTYPE_SHARED_ALIASES { \ + { IFM_AUTO, "auto" }, \ + \ + /* \ + * Shorthands for common media+option combinations as announced \ + * by miibus(4) \ + */ \ + { IFM_AUTO | IFM_FLOW, "auto-flow" }, \ + \ + { 0, NULL }, \ +} + +#define IFM_SHARED_OPTION_DESCRIPTIONS { \ + { IFM_FDX, "full-duplex" }, \ + { IFM_HDX, "half-duplex" }, \ + { IFM_FLOW, "flowcontrol" }, \ + { IFM_FLAG0, "flag0" }, \ + { IFM_FLAG1, "flag1" }, \ + { IFM_FLAG2, "flag2" }, \ + { IFM_LOOP, "hw-loopback" }, \ + { 0, NULL }, \ +} + +#define IFM_SHARED_OPTION_ALIASES { \ + { IFM_FDX, "fdx" }, \ + { IFM_HDX, "hdx" }, \ + { IFM_FLOW, "flow" }, \ + { IFM_LOOP, "loop" }, \ + { IFM_LOOP, "loopback" }, \ + { 0, NULL }, \ +} + +/* + * Baudrate descriptions for the various media types. + */ +struct ifmedia_baudrate { + int ifmb_word; /* media word */ + uint64_t ifmb_baudrate; /* corresponding baudrate */ +}; + +#define IFM_BAUDRATE_DESCRIPTIONS { \ + { IFM_ETHER | IFM_10_T, IF_Mbps(10) }, \ + { IFM_ETHER | IFM_10_2, IF_Mbps(10) }, \ + { IFM_ETHER | IFM_10_5, IF_Mbps(10) }, \ + { IFM_ETHER | IFM_100_TX, IF_Mbps(100) }, \ + { IFM_ETHER | IFM_100_FX, IF_Mbps(100) }, \ + { IFM_ETHER | IFM_100_T4, IF_Mbps(100) }, \ + { IFM_ETHER | IFM_100_VG, IF_Mbps(100) }, \ + { IFM_ETHER | IFM_100_T2, IF_Mbps(100) }, \ + { IFM_ETHER | IFM_1000_SX, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_10_STP, IF_Mbps(10) }, \ + { IFM_ETHER | IFM_10_FL, IF_Mbps(10) }, \ + { IFM_ETHER | IFM_1000_LX, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_1000_CX, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_1000_T, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_HPNA_1, IF_Mbps(1) }, \ + { IFM_ETHER | IFM_10G_LR, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_10G_SR, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_10G_CX4, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_2500_SX, IF_Mbps(2500ULL) }, \ + { IFM_ETHER | IFM_10G_TWINAX, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_10G_TWINAX_LONG, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_10G_LRM, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_10G_T, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_40G_CR4, IF_Gbps(40ULL) }, \ + { IFM_ETHER | IFM_40G_SR4, IF_Gbps(40ULL) }, \ + { IFM_ETHER | IFM_40G_LR4, IF_Gbps(40ULL) }, \ + { IFM_ETHER | IFM_1000_KX, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_10G_KX4, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_10G_KR, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_10G_CR1, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_20G_KR2, IF_Gbps(20ULL) }, \ + { IFM_ETHER | IFM_2500_KX, IF_Mbps(2500) }, \ + { IFM_ETHER | IFM_2500_T, IF_Mbps(2500) }, \ + { IFM_ETHER | IFM_5000_T, IF_Mbps(5000) }, \ + { IFM_ETHER | IFM_50G_PCIE, IF_Gbps(50ULL) }, \ + { IFM_ETHER | IFM_25G_PCIE, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_1000_SGMII, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_10G_SFI, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_40G_XLPPI, IF_Gbps(40ULL) }, \ + { IFM_ETHER | IFM_1000_CX_SGMII, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_40G_KR4, IF_Gbps(40ULL) }, \ + { IFM_ETHER | IFM_10G_ER, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_100G_CR4, IF_Gbps(100ULL) }, \ + { IFM_ETHER | IFM_100G_SR4, IF_Gbps(100ULL) }, \ + { IFM_ETHER | IFM_100G_KR4, IF_Gbps(100ULL) }, \ + { IFM_ETHER | IFM_100G_LR4, IF_Gbps(100ULL) }, \ + { IFM_ETHER | IFM_56G_R4, IF_Gbps(56ULL) }, \ + { IFM_ETHER | IFM_100_T, IF_Mbps(100ULL) }, \ + { IFM_ETHER | IFM_25G_CR, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_25G_KR, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_25G_SR, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_50G_CR2, IF_Gbps(50ULL) }, \ + { IFM_ETHER | IFM_50G_KR2, IF_Gbps(50ULL) }, \ + { IFM_ETHER | IFM_25G_LR, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_10G_AOC, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_25G_ACC, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_25G_AOC, IF_Gbps(25ULL) }, \ + \ + { IFM_TOKEN | IFM_TOK_STP4, IF_Mbps(4) }, \ + { IFM_TOKEN | IFM_TOK_STP16, IF_Mbps(16) }, \ + { IFM_TOKEN | IFM_TOK_UTP4, IF_Mbps(4) }, \ + { IFM_TOKEN | IFM_TOK_UTP16, IF_Mbps(16) }, \ + \ + { IFM_FDDI | IFM_FDDI_SMF, IF_Mbps(100) }, \ + { IFM_FDDI | IFM_FDDI_MMF, IF_Mbps(100) }, \ + { IFM_FDDI | IFM_FDDI_UTP, IF_Mbps(100) }, \ + \ + { IFM_IEEE80211 | IFM_IEEE80211_FH1, IF_Mbps(1) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_FH2, IF_Mbps(2) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_DS2, IF_Mbps(2) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_DS5, IF_Kbps(5500) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_DS11, IF_Mbps(11) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_DS1, IF_Mbps(1) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_DS22, IF_Mbps(22) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM6, IF_Mbps(6) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM9, IF_Mbps(9) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM12, IF_Mbps(12) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM18, IF_Mbps(18) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM24, IF_Mbps(24) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM36, IF_Mbps(36) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM48, IF_Mbps(48) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM54, IF_Mbps(54) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM72, IF_Mbps(72) }, \ + \ + { 0, 0 }, \ +} + +/* + * Status descriptions for the various media types. + */ +struct ifmedia_status_description { + int ifms_type; + int ifms_valid; + int ifms_bit; + const char *ifms_string[2]; +}; + +#define IFM_STATUS_DESC(ifms, bit) \ + (ifms)->ifms_string[((ifms)->ifms_bit & (bit)) ? 1 : 0] + +#define IFM_STATUS_DESCRIPTIONS { \ + { IFM_ETHER, IFM_AVALID, IFM_ACTIVE, \ + { "no carrier", "active" } }, \ + { IFM_FDDI, IFM_AVALID, IFM_ACTIVE, \ + { "no ring", "inserted" } }, \ + { IFM_TOKEN, IFM_AVALID, IFM_ACTIVE, \ + { "no ring", "inserted" } }, \ + { IFM_IEEE80211, IFM_AVALID, IFM_ACTIVE, \ + { "no network", "active" } }, \ + { IFM_ATM, IFM_AVALID, IFM_ACTIVE, \ + { "no network", "active" } }, \ + { 0, 0, 0, \ + { NULL, NULL } } \ +} +#endif /* _NET_IF_MEDIA_H_ */ diff --git a/nx/external/bsd/include/net/route.h b/nx/external/bsd/include/net/route.h new file mode 100644 index 00000000..8f61a4b8 --- /dev/null +++ b/nx/external/bsd/include/net/route.h @@ -0,0 +1,323 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1980, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * @(#)route.h 8.4 (Berkeley) 1/9/95 + * $FreeBSD$ + */ + +#ifndef _NET_ROUTE_H_ +#define _NET_ROUTE_H_ + +#include // custom +#include // custom + +/* + * Kernel resident routing tables. + * + * The routing tables are initialized when interface addresses + * are set by making entries for all directly connected interfaces. + */ + +/* + * Struct route consiste of a destination address, + * a route entry pointer, link-layer prepend data pointer along + * with its length. + */ +struct route { + struct rtentry *ro_rt; + struct llentry *ro_lle; + /* + * ro_prepend and ro_plen are only used for bpf to pass in a + * preformed header. They are not cacheable. + */ + char *ro_prepend; + uint16_t ro_plen; + uint16_t ro_flags; + uint16_t ro_mtu; /* saved ro_rt mtu */ + uint16_t spare; + struct sockaddr ro_dst; +}; + +#define RT_L2_ME_BIT 2 /* dst L2 addr is our address */ +#define RT_MAY_LOOP_BIT 3 /* dst may require loop copy */ +#define RT_HAS_HEADER_BIT 4 /* mbuf already have its header prepended */ + +#define RT_L2_ME (1 << RT_L2_ME_BIT) /* 0x0004 */ +#define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT) /* 0x0008 */ +#define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT) /* 0x0010 */ + +#define RT_REJECT 0x0020 /* Destination is reject */ +#define RT_BLACKHOLE 0x0040 /* Destination is blackhole */ +#define RT_HAS_GW 0x0080 /* Destination has GW */ +#define RT_LLE_CACHE 0x0100 /* Cache link layer */ + +struct rt_metrics { + u_long rmx_locks; /* Kernel must leave these values alone */ + u_long rmx_mtu; /* MTU for this path */ + u_long rmx_hopcount; /* max hops expected */ + u_long rmx_expire; /* lifetime for route, e.g. redirect */ + u_long rmx_recvpipe; /* inbound delay-bandwidth product */ + u_long rmx_sendpipe; /* outbound delay-bandwidth product */ + u_long rmx_ssthresh; /* outbound gateway buffer limit */ + u_long rmx_rtt; /* estimated round trip time */ + u_long rmx_rttvar; /* estimated rtt variance */ + u_long rmx_pksent; /* packets sent using this route */ + u_long rmx_weight; /* route weight */ + u_long rmx_filler[3]; /* will be used for T/TCP later */ +}; + +/* + * rmx_rtt and rmx_rttvar are stored as microseconds; + * RTTTOPRHZ(rtt) converts to a value suitable for use + * by a protocol slowtimo counter. + */ +#define RTM_RTTUNIT 1000000 /* units for rtt, rttvar, as units per sec */ +#define RTTTOPRHZ(r) ((r) / (RTM_RTTUNIT / PR_SLOWHZ)) + +/* lle state is exported in rmx_state rt_metrics field */ +#define rmx_state rmx_weight + +/* + * Keep a generation count of routing table, incremented on route addition, + * so we can invalidate caches. This is accessed without a lock, as precision + * is not required. + */ +typedef volatile u_int rt_gen_t; /* tree generation (for adds) */ +#define RT_GEN(fibnum, af) rt_tables_get_gen(fibnum, af) + +#define RT_DEFAULT_FIB 0 /* Explicitly mark fib=0 restricted cases */ +#define RT_ALL_FIBS -1 /* Announce event for every fib */ + +/* + * We distinguish between routes to hosts and routes to networks, + * preferring the former if available. For each route we infer + * the interface to use from the gateway address supplied when + * the route was entered. Routes that forward packets through + * gateways are marked so that the output routines know to address the + * gateway rather than the ultimate destination. + */ + +// We don't need those includes, I guess +/*#ifndef RNF_NORMAL +#include +#ifdef RADIX_MPATH +#include +#endif +#endif +*/ + +#define RTF_UP 0x1 /* route usable */ +#define RTF_GATEWAY 0x2 /* destination is a gateway */ +#define RTF_HOST 0x4 /* host entry (net otherwise) */ +#define RTF_REJECT 0x8 /* host or net unreachable */ +#define RTF_DYNAMIC 0x10 /* created dynamically (by redirect) */ +#define RTF_MODIFIED 0x20 /* modified dynamically (by redirect) */ +#define RTF_DONE 0x40 /* message confirmed */ +/* 0x80 unused, was RTF_DELCLONE */ +/* 0x100 unused, was RTF_CLONING */ +#define RTF_XRESOLVE 0x200 /* external daemon resolves name */ +#define RTF_LLINFO 0x400 /* DEPRECATED - exists ONLY for backward + compatibility */ +#define RTF_LLDATA 0x400 /* used by apps to add/del L2 entries */ +#define RTF_STATIC 0x800 /* manually added */ +#define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */ +#define RTF_PROTO2 0x4000 /* protocol specific routing flag */ +#define RTF_PROTO1 0x8000 /* protocol specific routing flag */ +/* 0x10000 unused, was RTF_PRCLONING */ +/* 0x20000 unused, was RTF_WASCLONED */ +#define RTF_PROTO3 0x40000 /* protocol specific routing flag */ +#define RTF_FIXEDMTU 0x80000 /* MTU was explicitly specified */ +#define RTF_PINNED 0x100000 /* route is immutable */ +#define RTF_LOCAL 0x200000 /* route represents a local address */ +#define RTF_BROADCAST 0x400000 /* route represents a bcast address */ +#define RTF_MULTICAST 0x800000 /* route represents a mcast address */ + /* 0x8000000 and up unassigned */ +#define RTF_STICKY 0x10000000 /* always route dst->src */ + +#define RTF_RNH_LOCKED 0x40000000 /* radix node head is locked */ + +#define RTF_GWFLAG_COMPAT 0x80000000 /* a compatibility bit for interacting + with existing routing apps */ + +/* Mask of RTF flags that are allowed to be modified by RTM_CHANGE. */ +#define RTF_FMASK \ + (RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_BLACKHOLE | \ + RTF_REJECT | RTF_STATIC | RTF_STICKY) + +/* + * fib_ nexthop API flags. + */ + +/* Consumer-visible nexthop info flags */ +#define NHF_REJECT 0x0010 /* RTF_REJECT */ +#define NHF_BLACKHOLE 0x0020 /* RTF_BLACKHOLE */ +#define NHF_REDIRECT 0x0040 /* RTF_DYNAMIC|RTF_MODIFIED */ +#define NHF_DEFAULT 0x0080 /* Default route */ +#define NHF_BROADCAST 0x0100 /* RTF_BROADCAST */ +#define NHF_GATEWAY 0x0200 /* RTF_GATEWAY */ + +/* Nexthop request flags */ +#define NHR_IFAIF 0x01 /* Return ifa_ifp interface */ +#define NHR_REF 0x02 /* For future use */ + +/* Control plane route request flags */ +#define NHR_COPY 0x100 /* Copy rte data */ + +/* + * Routing statistics. + */ +struct rtstat { + short rts_badredirect; /* bogus redirect calls */ + short rts_dynamic; /* routes created by redirects */ + short rts_newgateway; /* routes modified by redirects */ + short rts_unreach; /* lookups which failed */ + short rts_wildcard; /* lookups satisfied by a wildcard */ +}; +/* + * Structures for routing messages. + */ +struct rt_msghdr { + u_short rtm_msglen; /* to skip over non-understood messages */ + u_char rtm_version; /* future binary compatibility */ + u_char rtm_type; /* message type */ + u_short rtm_index; /* index for associated ifp */ + int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ + int rtm_addrs; /* bitmask identifying sockaddrs in msg */ + pid_t rtm_pid; /* identify sender */ + int rtm_seq; /* for sender to identify action */ + int rtm_errno; /* why failed */ + int rtm_fmask; /* bitmask used in RTM_CHANGE message */ + u_long rtm_inits; /* which metrics we are initializing */ + struct rt_metrics rtm_rmx; /* metrics themselves */ +}; + +#define RTM_VERSION 5 /* Up the ante and ignore older versions */ + +/* + * Message types. + * + * The format for each message is annotated below using the following + * identifiers: + * + * (1) struct rt_msghdr + * (2) struct ifa_msghdr + * (3) struct if_msghdr + * (4) struct ifma_msghdr + * (5) struct if_announcemsghdr + * + */ +#define RTM_ADD 0x1 /* (1) Add Route */ +#define RTM_DELETE 0x2 /* (1) Delete Route */ +#define RTM_CHANGE 0x3 /* (1) Change Metrics or flags */ +#define RTM_GET 0x4 /* (1) Report Metrics */ +#define RTM_LOSING 0x5 /* (1) Kernel Suspects Partitioning */ +#define RTM_REDIRECT 0x6 /* (1) Told to use different route */ +#define RTM_MISS 0x7 /* (1) Lookup failed on this address */ +#define RTM_LOCK 0x8 /* (1) fix specified metrics */ + /* 0x9 */ + /* 0xa */ +#define RTM_RESOLVE 0xb /* (1) req to resolve dst to LL addr */ +#define RTM_NEWADDR 0xc /* (2) address being added to iface */ +#define RTM_DELADDR 0xd /* (2) address being removed from iface */ +#define RTM_IFINFO 0xe /* (3) iface going up/down etc. */ +#define RTM_NEWMADDR 0xf /* (4) mcast group membership being added to if */ +#define RTM_DELMADDR 0x10 /* (4) mcast group membership being deleted */ +#define RTM_IFANNOUNCE 0x11 /* (5) iface arrival/departure */ +#define RTM_IEEE80211 0x12 /* (5) IEEE80211 wireless event */ + +/* + * Bitmask values for rtm_inits and rmx_locks. + */ +#define RTV_MTU 0x1 /* init or lock _mtu */ +#define RTV_HOPCOUNT 0x2 /* init or lock _hopcount */ +#define RTV_EXPIRE 0x4 /* init or lock _expire */ +#define RTV_RPIPE 0x8 /* init or lock _recvpipe */ +#define RTV_SPIPE 0x10 /* init or lock _sendpipe */ +#define RTV_SSTHRESH 0x20 /* init or lock _ssthresh */ +#define RTV_RTT 0x40 /* init or lock _rtt */ +#define RTV_RTTVAR 0x80 /* init or lock _rttvar */ +#define RTV_WEIGHT 0x100 /* init or lock _weight */ + +/* + * Bitmask values for rtm_addrs. + */ +#define RTA_DST 0x1 /* destination sockaddr present */ +#define RTA_GATEWAY 0x2 /* gateway sockaddr present */ +#define RTA_NETMASK 0x4 /* netmask sockaddr present */ +#define RTA_GENMASK 0x8 /* cloning mask sockaddr present */ +#define RTA_IFP 0x10 /* interface name sockaddr present */ +#define RTA_IFA 0x20 /* interface addr sockaddr present */ +#define RTA_AUTHOR 0x40 /* sockaddr for author of redirect */ +#define RTA_BRD 0x80 /* for NEWADDR, broadcast or p-p dest addr */ + +/* + * Index offsets for sockaddr array for alternate internal encoding. + */ +#define RTAX_DST 0 /* destination sockaddr present */ +#define RTAX_GATEWAY 1 /* gateway sockaddr present */ +#define RTAX_NETMASK 2 /* netmask sockaddr present */ +#define RTAX_GENMASK 3 /* cloning mask sockaddr present */ +#define RTAX_IFP 4 /* interface name sockaddr present */ +#define RTAX_IFA 5 /* interface addr sockaddr present */ +#define RTAX_AUTHOR 6 /* sockaddr for author of redirect */ +#define RTAX_BRD 7 /* for NEWADDR, broadcast or p-p dest addr */ +#define RTAX_MAX 8 /* size of array to allocate */ + +typedef int rt_filter_f_t(const struct rtentry *, void *); + +struct rt_addrinfo { + int rti_addrs; /* Route RTF_ flags */ + int rti_flags; /* Route RTF_ flags */ + struct sockaddr *rti_info[RTAX_MAX]; /* Sockaddr data */ + struct ifaddr *rti_ifa; /* value of rt_ifa addr */ + struct ifnet *rti_ifp; /* route interface */ + rt_filter_f_t *rti_filter; /* filter function */ + void *rti_filterdata; /* filter paramenters */ + u_long rti_mflags; /* metrics RTV_ flags */ + u_long rti_spare; /* Will be used for fib */ + struct rt_metrics *rti_rmx; /* Pointer to route metrics */ +}; + +/* + * This macro returns the size of a struct sockaddr when passed + * through a routing socket. Basically we round up sa_len to + * a multiple of sizeof(long), with a minimum of sizeof(long). + * The case sa_len == 0 should only apply to empty structures. + */ +#define SA_SIZE(sa) \ + ( (((struct sockaddr *)(sa))->sa_len == 0) ? \ + sizeof(long) : \ + 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) ) + +#define sa_equal(a, b) ( \ + (((const struct sockaddr *)(a))->sa_len == ((const struct sockaddr *)(b))->sa_len) && \ + (bcmp((a), (b), ((const struct sockaddr *)(b))->sa_len) == 0)) + +#endif diff --git a/nx/external/bsd/include/netdb.h b/nx/external/bsd/include/netdb.h new file mode 100644 index 00000000..2b51f526 --- /dev/null +++ b/nx/external/bsd/include/netdb.h @@ -0,0 +1,244 @@ +// TuxSH: define __BSD_VISIBLE, change a lot of symbols, etc +#ifndef __BSD_VISIBLE +#define __BSD_VISIBLE 1 +#endif + +/*- + * SPDX-License-Identifier: (BSD-3-Clause AND ISC) + * + * Copyright (c) 1980, 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +/* + * @(#)netdb.h 8.1 (Berkeley) 6/2/93 + * From: Id: netdb.h,v 8.9 1996/11/19 08:39:29 vixie Exp $ + * $FreeBSD$ + */ + +#ifndef _NETDB_H_ +#define _NETDB_H_ + +#include +#include +#include + +extern __thread int h_errno; +// Removed some FreeBSD definitions + +/* + * Structures returned by network data base library. All addresses are + * supplied in host order, and returned in network order (suitable for + * use in system calls). + */ +struct hostent { + char *h_name; /* official name of host */ + char **h_aliases; /* alias list */ + int h_addrtype; /* host address type */ + int h_length; /* length of address */ + char **h_addr_list; /* list of addresses from name server */ +#define h_addr h_addr_list[0] /* address, for backward compatibility */ +}; + +struct netent { + char *n_name; /* official name of net */ + char **n_aliases; /* alias list */ + int n_addrtype; /* net address type */ + uint32_t n_net; /* network # */ +}; + +struct servent { + char *s_name; /* official service name */ + char **s_aliases; /* alias list */ + int s_port; /* port # */ + char *s_proto; /* protocol to use */ +}; + +struct protoent { + char *p_name; /* official protocol name */ + char **p_aliases; /* alias list */ + int p_proto; /* protocol # */ +}; + +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ + int ai_family; /* AF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + socklen_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; + +#define IPPORT_RESERVED 1024 + +/* + * Error return codes from gethostbyname() and gethostbyaddr() + * (left in h_errno). + */ + +#define NETDB_INTERNAL -1 /* see errno */ +#define NETDB_SUCCESS 0 /* no problem */ +#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ +#define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */ +#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ +#define NO_DATA 4 /* Valid name, no data record of requested type */ +#define NO_ADDRESS NO_DATA /* no address, look for MX record */ + +/* + * Error return codes from getaddrinfo() + */ +#if 1//0 +/* obsoleted */ +#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ +#endif +#define EAI_AGAIN 2 /* temporary failure in name resolution */ +#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ +#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_MEMORY 6 /* memory allocation failure */ +#if 1//0 +/* obsoleted */ +#define EAI_NODATA 7 /* no address associated with hostname */ +#endif +#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ +#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ +#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ +#define EAI_SYSTEM 11 /* system error returned in errno */ +#define EAI_BADHINTS 12 /* invalid value for hints */ +#define EAI_PROTOCOL 13 /* resolved protocol is unknown */ +#define EAI_OVERFLOW 14 /* argument buffer overflow */ +#define EAI_MAX 15 + +/* + * Flag values for getaddrinfo() + */ +#define AI_PASSIVE 0x00000001 /* get address to use bind() */ +#define AI_CANONNAME 0x00000002 /* fill ai_canonname */ +#define AI_NUMERICHOST 0x00000004 /* prevent host name resolution */ +#define AI_NUMERICSERV 0x00000008 /* prevent service name resolution */ +/* valid flags for addrinfo (not a standard def, apps should not use it) */ +#define AI_MASK \ + (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | \ + AI_ADDRCONFIG | AI_ALL | AI_V4MAPPED) + +#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ +#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ +#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ +#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ +/* special recommended flags for getipnodebyname */ +#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) + +/* + * Constants for getnameinfo() + */ +#define NI_MAXHOST 1025 +#define NI_MAXSERV 32 + +/* + * Flag values for getnameinfo() + */ +#define NI_NOFQDN 0x00000001 +#define NI_NUMERICHOST 0x00000002 +#define NI_NAMEREQD 0x00000004 +#define NI_NUMERICSERV 0x00000008 +#define NI_DGRAM 0x00000010 +#define NI_NUMERICSCOPE 0x00000020 + +/* + * Scope delimit character + */ +#define SCOPE_DELIMITER '%' + +// Modified the prototypes: added argument names, etc. +__BEGIN_DECLS +void endhostent(void); +void endnetent(void); +void endprotoent(void); +void endservent(void); +#if __BSD_VISIBLE || (__POSIX_VISIBLE && __POSIX_VISIBLE <= 200112) +struct hostent* gethostbyname(const char *name); +struct hostent* gethostbyaddr(const void *addr, socklen_t len, int type); +#endif +struct hostent *gethostent(void); +struct netent *getnetbyaddr(uint32_t, int); +struct netent *getnetbyname(const char *); +struct netent *getnetent(void); +struct protoent *getprotobyname(const char *); +struct protoent *getprotobynumber(int); +struct protoent *getprotoent(void); +struct servent *getservbyname(const char *, const char *); +struct servent *getservbyport(int, const char *); +struct servent *getservent(void); +void sethostent(int); +/* void sethostfile(const char *); */ +void setnetent(int); +void setprotoent(int); +int getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *host, socklen_t hostlen, + char *serv, socklen_t servlen, int flags); +int getaddrinfo(const char *node, const char *service, + const struct addrinfo *hints, + struct addrinfo **res); +void freeaddrinfo(struct addrinfo *ai); + +const char *gai_strerror(int err); +void setservent(int); + +#if __BSD_VISIBLE +// removed a lot of definitions here +void freehostent(struct hostent *he); +void herror(const char *s); +const char* hstrerror(int err); +#endif + +// Removed private __h_errno() +__END_DECLS + +#endif /* !_NETDB_H_ */ diff --git a/nx/external/bsd/include/netinet/in.h b/nx/external/bsd/include/netinet/in.h new file mode 100644 index 00000000..0f624398 --- /dev/null +++ b/nx/external/bsd/include/netinet/in.h @@ -0,0 +1,683 @@ +// TuxSH: removed definitions under _KERNEL ifdef blocks, modify the prototype of some functions, some other cleanup, etc. +#ifndef __BSD_VISIBLE +#define __BSD_VISIBLE 1 +#endif + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1982, 1986, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * @(#)in.h 8.3 (Berkeley) 1/3/94 + * $FreeBSD$ + */ + +#ifndef _NETINET_IN_H_ +#define _NETINET_IN_H_ + +#include +#include +#include +#include + +/* Protocols common to RFC 1700, POSIX, and X/Open. */ +#define IPPROTO_IP 0 /* dummy for IP */ +#define IPPROTO_ICMP 1 /* control message protocol */ +#define IPPROTO_TCP 6 /* tcp */ +#define IPPROTO_UDP 17 /* user datagram protocol */ + +#define INADDR_ANY ((in_addr_t)0x00000000) +#define INADDR_BROADCAST ((in_addr_t)0xffffffff) /* must be masked */ + +#ifndef _SA_FAMILY_T_DECLARED +typedef __sa_family_t sa_family_t; +#define _SA_FAMILY_T_DECLARED +#endif + +/* Internet address (a structure for historical reasons). */ +#ifndef _STRUCT_IN_ADDR_DECLARED +struct in_addr { + in_addr_t s_addr; +}; +#define _STRUCT_IN_ADDR_DECLARED +#endif + +#ifndef _SOCKLEN_T_DECLARED +typedef __socklen_t socklen_t; +#define _SOCKLEN_T_DECLARED +#endif + +#include + +/* Socket address, internet style. */ +struct sockaddr_in { + uint8_t sin_len; + sa_family_t sin_family; + in_port_t sin_port; + struct in_addr sin_addr; + char sin_zero[8]; +}; + +// Removed redundant host<>local definition functions + +#if __POSIX_VISIBLE >= 200112 +#define IPPROTO_IPV6 41 /* IP6 header */ +#define IPPROTO_RAW 255 /* raw IP packet */ +#define INET_ADDRSTRLEN 16 +#endif + +#if __BSD_VISIBLE +/* + * Constants and structures defined by the internet system, + * Per RFC 790, September 1981, and numerous additions. + */ + +/* + * Protocols (RFC 1700) + */ +#define IPPROTO_HOPOPTS 0 /* IP6 hop-by-hop options */ +#define IPPROTO_IGMP 2 /* group mgmt protocol */ +#define IPPROTO_GGP 3 /* gateway^2 (deprecated) */ +#define IPPROTO_IPV4 4 /* IPv4 encapsulation */ +#define IPPROTO_IPIP IPPROTO_IPV4 /* for compatibility */ +#define IPPROTO_ST 7 /* Stream protocol II */ +#define IPPROTO_EGP 8 /* exterior gateway protocol */ +#define IPPROTO_PIGP 9 /* private interior gateway */ +#define IPPROTO_RCCMON 10 /* BBN RCC Monitoring */ +#define IPPROTO_NVPII 11 /* network voice protocol*/ +#define IPPROTO_PUP 12 /* pup */ +#define IPPROTO_ARGUS 13 /* Argus */ +#define IPPROTO_EMCON 14 /* EMCON */ +#define IPPROTO_XNET 15 /* Cross Net Debugger */ +#define IPPROTO_CHAOS 16 /* Chaos*/ +#define IPPROTO_MUX 18 /* Multiplexing */ +#define IPPROTO_MEAS 19 /* DCN Measurement Subsystems */ +#define IPPROTO_HMP 20 /* Host Monitoring */ +#define IPPROTO_PRM 21 /* Packet Radio Measurement */ +#define IPPROTO_IDP 22 /* xns idp */ +#define IPPROTO_TRUNK1 23 /* Trunk-1 */ +#define IPPROTO_TRUNK2 24 /* Trunk-2 */ +#define IPPROTO_LEAF1 25 /* Leaf-1 */ +#define IPPROTO_LEAF2 26 /* Leaf-2 */ +#define IPPROTO_RDP 27 /* Reliable Data */ +#define IPPROTO_IRTP 28 /* Reliable Transaction */ +#define IPPROTO_TP 29 /* tp-4 w/ class negotiation */ +#define IPPROTO_BLT 30 /* Bulk Data Transfer */ +#define IPPROTO_NSP 31 /* Network Services */ +#define IPPROTO_INP 32 /* Merit Internodal */ +#define IPPROTO_SEP 33 /* Sequential Exchange */ +#define IPPROTO_3PC 34 /* Third Party Connect */ +#define IPPROTO_IDPR 35 /* InterDomain Policy Routing */ +#define IPPROTO_XTP 36 /* XTP */ +#define IPPROTO_DDP 37 /* Datagram Delivery */ +#define IPPROTO_CMTP 38 /* Control Message Transport */ +#define IPPROTO_TPXX 39 /* TP++ Transport */ +#define IPPROTO_IL 40 /* IL transport protocol */ +#define IPPROTO_SDRP 42 /* Source Demand Routing */ +#define IPPROTO_ROUTING 43 /* IP6 routing header */ +#define IPPROTO_FRAGMENT 44 /* IP6 fragmentation header */ +#define IPPROTO_IDRP 45 /* InterDomain Routing*/ +#define IPPROTO_RSVP 46 /* resource reservation */ +#define IPPROTO_GRE 47 /* General Routing Encap. */ +#define IPPROTO_MHRP 48 /* Mobile Host Routing */ +#define IPPROTO_BHA 49 /* BHA */ +#define IPPROTO_ESP 50 /* IP6 Encap Sec. Payload */ +#define IPPROTO_AH 51 /* IP6 Auth Header */ +#define IPPROTO_INLSP 52 /* Integ. Net Layer Security */ +#define IPPROTO_SWIPE 53 /* IP with encryption */ +#define IPPROTO_NHRP 54 /* Next Hop Resolution */ +#define IPPROTO_MOBILE 55 /* IP Mobility */ +#define IPPROTO_TLSP 56 /* Transport Layer Security */ +#define IPPROTO_SKIP 57 /* SKIP */ +#define IPPROTO_ICMPV6 58 /* ICMP6 */ +#define IPPROTO_NONE 59 /* IP6 no next header */ +#define IPPROTO_DSTOPTS 60 /* IP6 destination option */ +#define IPPROTO_AHIP 61 /* any host internal protocol */ +#define IPPROTO_CFTP 62 /* CFTP */ +#define IPPROTO_HELLO 63 /* "hello" routing protocol */ +#define IPPROTO_SATEXPAK 64 /* SATNET/Backroom EXPAK */ +#define IPPROTO_KRYPTOLAN 65 /* Kryptolan */ +#define IPPROTO_RVD 66 /* Remote Virtual Disk */ +#define IPPROTO_IPPC 67 /* Pluribus Packet Core */ +#define IPPROTO_ADFS 68 /* Any distributed FS */ +#define IPPROTO_SATMON 69 /* Satnet Monitoring */ +#define IPPROTO_VISA 70 /* VISA Protocol */ +#define IPPROTO_IPCV 71 /* Packet Core Utility */ +#define IPPROTO_CPNX 72 /* Comp. Prot. Net. Executive */ +#define IPPROTO_CPHB 73 /* Comp. Prot. HeartBeat */ +#define IPPROTO_WSN 74 /* Wang Span Network */ +#define IPPROTO_PVP 75 /* Packet Video Protocol */ +#define IPPROTO_BRSATMON 76 /* BackRoom SATNET Monitoring */ +#define IPPROTO_ND 77 /* Sun net disk proto (temp.) */ +#define IPPROTO_WBMON 78 /* WIDEBAND Monitoring */ +#define IPPROTO_WBEXPAK 79 /* WIDEBAND EXPAK */ +#define IPPROTO_EON 80 /* ISO cnlp */ +#define IPPROTO_VMTP 81 /* VMTP */ +#define IPPROTO_SVMTP 82 /* Secure VMTP */ +#define IPPROTO_VINES 83 /* Banyon VINES */ +#define IPPROTO_TTP 84 /* TTP */ +#define IPPROTO_IGP 85 /* NSFNET-IGP */ +#define IPPROTO_DGP 86 /* dissimilar gateway prot. */ +#define IPPROTO_TCF 87 /* TCF */ +#define IPPROTO_IGRP 88 /* Cisco/GXS IGRP */ +#define IPPROTO_OSPFIGP 89 /* OSPFIGP */ +#define IPPROTO_SRPC 90 /* Strite RPC protocol */ +#define IPPROTO_LARP 91 /* Locus Address Resoloution */ +#define IPPROTO_MTP 92 /* Multicast Transport */ +#define IPPROTO_AX25 93 /* AX.25 Frames */ +#define IPPROTO_IPEIP 94 /* IP encapsulated in IP */ +#define IPPROTO_MICP 95 /* Mobile Int.ing control */ +#define IPPROTO_SCCSP 96 /* Semaphore Comm. security */ +#define IPPROTO_ETHERIP 97 /* Ethernet IP encapsulation */ +#define IPPROTO_ENCAP 98 /* encapsulation header */ +#define IPPROTO_APES 99 /* any private encr. scheme */ +#define IPPROTO_GMTP 100 /* GMTP*/ +#define IPPROTO_IPCOMP 108 /* payload compression (IPComp) */ +#define IPPROTO_SCTP 132 /* SCTP */ +#define IPPROTO_MH 135 /* IPv6 Mobility Header */ +#define IPPROTO_UDPLITE 136 /* UDP-Lite */ +#define IPPROTO_HIP 139 /* IP6 Host Identity Protocol */ +#define IPPROTO_SHIM6 140 /* IP6 Shim6 Protocol */ +/* 101-254: Partly Unassigned */ +#define IPPROTO_PIM 103 /* Protocol Independent Mcast */ +#define IPPROTO_CARP 112 /* CARP */ +#define IPPROTO_PGM 113 /* PGM */ +#define IPPROTO_MPLS 137 /* MPLS-in-IP */ +#define IPPROTO_PFSYNC 240 /* PFSYNC */ +#define IPPROTO_RESERVED_253 253 /* Reserved */ +#define IPPROTO_RESERVED_254 254 /* Reserved */ +/* 255: Reserved */ +/* BSD Private, local use, namespace incursion, no longer used */ +#define IPPROTO_OLD_DIVERT 254 /* OLD divert pseudo-proto */ +#define IPPROTO_MAX 256 + +/* last return value of *_input(), meaning "all job for this pkt is done". */ +#define IPPROTO_DONE 257 + +/* Only used internally, so can be outside the range of valid IP protocols. */ +#define IPPROTO_DIVERT 258 /* divert pseudo-protocol */ +#define IPPROTO_SEND 259 /* SeND pseudo-protocol */ + +/* + * Defined to avoid confusion. The master value is defined by + * PROTO_SPACER in sys/protosw.h. + */ +#define IPPROTO_SPACER 32767 /* spacer for loadable protos */ + +/* + * Local port number conventions: + * + * When a user does a bind(2) or connect(2) with a port number of zero, + * a non-conflicting local port address is chosen. + * The default range is IPPORT_HIFIRSTAUTO through + * IPPORT_HILASTAUTO, although that is settable by sysctl. + * + * A user may set the IPPROTO_IP option IP_PORTRANGE to change this + * default assignment range. + * + * The value IP_PORTRANGE_DEFAULT causes the default behavior. + * + * The value IP_PORTRANGE_HIGH changes the range of candidate port numbers + * into the "high" range. These are reserved for client outbound connections + * which do not want to be filtered by any firewalls. + * + * The value IP_PORTRANGE_LOW changes the range to the "low" are + * that is (by convention) restricted to privileged processes. This + * convention is based on "vouchsafe" principles only. It is only secure + * if you trust the remote host to restrict these ports. + * + * The default range of ports and the high range can be changed by + * sysctl(3). (net.inet.ip.portrange.{hi,low,}{first,last}) + * + * Changing those values has bad security implications if you are + * using a stateless firewall that is allowing packets outside of that + * range in order to allow transparent outgoing connections. + * + * Such a firewall configuration will generally depend on the use of these + * default values. If you change them, you may find your Security + * Administrator looking for you with a heavy object. + * + * For a slightly more orthodox text view on this: + * + * ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers + * + * port numbers are divided into three ranges: + * + * 0 - 1023 Well Known Ports + * 1024 - 49151 Registered Ports + * 49152 - 65535 Dynamic and/or Private Ports + * + */ + +/* + * Ports < IPPORT_RESERVED are reserved for + * privileged processes (e.g. root). (IP_PORTRANGE_LOW) + */ +#define IPPORT_RESERVED 1024 + +/* + * Default local port range, used by IP_PORTRANGE_DEFAULT + */ +#define IPPORT_EPHEMERALFIRST 10000 +#define IPPORT_EPHEMERALLAST 65535 + +/* + * Dynamic port range, used by IP_PORTRANGE_HIGH. + */ +#define IPPORT_HIFIRSTAUTO 49152 +#define IPPORT_HILASTAUTO 65535 + +/* + * Scanning for a free reserved port return a value below IPPORT_RESERVED, + * but higher than IPPORT_RESERVEDSTART. Traditionally the start value was + * 512, but that conflicts with some well-known-services that firewalls may + * have a fit if we use. + */ +#define IPPORT_RESERVEDSTART 600 + +#define IPPORT_MAX 65535 + +/* + * Definitions of bits in internet address integers. + * On subnets, the decomposition of addresses to host and net parts + * is done according to subnet mask, not the masks here. + */ +#define IN_CLASSA(i) (((in_addr_t)(i) & 0x80000000) == 0) +#define IN_CLASSA_NET 0xff000000 +#define IN_CLASSA_NSHIFT 24 +#define IN_CLASSA_HOST 0x00ffffff +#define IN_CLASSA_MAX 128 + +#define IN_CLASSB(i) (((in_addr_t)(i) & 0xc0000000) == 0x80000000) +#define IN_CLASSB_NET 0xffff0000 +#define IN_CLASSB_NSHIFT 16 +#define IN_CLASSB_HOST 0x0000ffff +#define IN_CLASSB_MAX 65536 + +#define IN_CLASSC(i) (((in_addr_t)(i) & 0xe0000000) == 0xc0000000) +#define IN_CLASSC_NET 0xffffff00 +#define IN_CLASSC_NSHIFT 8 +#define IN_CLASSC_HOST 0x000000ff + +#define IN_CLASSD(i) (((in_addr_t)(i) & 0xf0000000) == 0xe0000000) +#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */ +#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */ +#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */ +#define IN_MULTICAST(i) IN_CLASSD(i) + +#define IN_EXPERIMENTAL(i) (((in_addr_t)(i) & 0xf0000000) == 0xf0000000) +#define IN_BADCLASS(i) (((in_addr_t)(i) & 0xf0000000) == 0xf0000000) + +#define IN_LINKLOCAL(i) (((in_addr_t)(i) & 0xffff0000) == 0xa9fe0000) +#define IN_LOOPBACK(i) (((in_addr_t)(i) & 0xff000000) == 0x7f000000) +#define IN_ZERONET(i) (((in_addr_t)(i) & 0xff000000) == 0) + +#define IN_PRIVATE(i) ((((in_addr_t)(i) & 0xff000000) == 0x0a000000) || \ + (((in_addr_t)(i) & 0xfff00000) == 0xac100000) || \ + (((in_addr_t)(i) & 0xffff0000) == 0xc0a80000)) + +#define IN_LOCAL_GROUP(i) (((in_addr_t)(i) & 0xffffff00) == 0xe0000000) + +#define IN_ANY_LOCAL(i) (IN_LINKLOCAL(i) || IN_LOCAL_GROUP(i)) + +#define INADDR_LOOPBACK ((in_addr_t)0x7f000001) +#define INADDR_NONE ((in_addr_t)0xffffffff) /* -1 return */ + +#define INADDR_UNSPEC_GROUP ((in_addr_t)0xe0000000) /* 224.0.0.0 */ +#define INADDR_ALLHOSTS_GROUP ((in_addr_t)0xe0000001) /* 224.0.0.1 */ +#define INADDR_ALLRTRS_GROUP ((in_addr_t)0xe0000002) /* 224.0.0.2 */ +#define INADDR_ALLRPTS_GROUP ((in_addr_t)0xe0000016) /* 224.0.0.22, IGMPv3 */ +#define INADDR_CARP_GROUP ((in_addr_t)0xe0000012) /* 224.0.0.18 */ +#define INADDR_PFSYNC_GROUP ((in_addr_t)0xe00000f0) /* 224.0.0.240 */ +#define INADDR_ALLMDNS_GROUP ((in_addr_t)0xe00000fb) /* 224.0.0.251 */ +#define INADDR_MAX_LOCAL_GROUP ((in_addr_t)0xe00000ff) /* 224.0.0.255 */ + +#define IN_LOOPBACKNET 127 /* official! */ + +#define IN_RFC3021_MASK ((in_addr_t)0xfffffffe) + +/* + * Options for use with [gs]etsockopt at the IP level. + * First word of comment is data type; bool is stored in int. + */ +#define IP_OPTIONS 1 /* buf/ip_opts; set/get IP options */ +#define IP_HDRINCL 2 /* int; header is included with data */ +#define IP_TOS 3 /* int; IP type of service and preced. */ +#define IP_TTL 4 /* int; IP time to live */ +#define IP_RECVOPTS 5 /* bool; receive all IP opts w/dgram */ +#define IP_RECVRETOPTS 6 /* bool; receive IP opts for response */ +#define IP_RECVDSTADDR 7 /* bool; receive IP dst addr w/dgram */ +#define IP_SENDSRCADDR IP_RECVDSTADDR /* cmsg_type to set src addr */ +#define IP_RETOPTS 8 /* ip_opts; set/get IP options */ +#define IP_MULTICAST_IF 9 /* struct in_addr *or* struct ip_mreqn; + * set/get IP multicast i/f */ +#define IP_MULTICAST_TTL 10 /* u_char; set/get IP multicast ttl */ +#define IP_MULTICAST_LOOP 11 /* u_char; set/get IP multicast loopback */ +#define IP_ADD_MEMBERSHIP 12 /* ip_mreq; add an IP group membership */ +#define IP_DROP_MEMBERSHIP 13 /* ip_mreq; drop an IP group membership */ +#define IP_MULTICAST_VIF 14 /* set/get IP mcast virt. iface */ +#define IP_RSVP_ON 15 /* enable RSVP in kernel */ +#define IP_RSVP_OFF 16 /* disable RSVP in kernel */ +#define IP_RSVP_VIF_ON 17 /* set RSVP per-vif socket */ +#define IP_RSVP_VIF_OFF 18 /* unset RSVP per-vif socket */ +#define IP_PORTRANGE 19 /* int; range to choose for unspec port */ +#define IP_RECVIF 20 /* bool; receive reception if w/dgram */ +/* for IPSEC */ +#define IP_IPSEC_POLICY 21 /* int; set/get security policy */ + /* unused; was IP_FAITH */ +#define IP_ONESBCAST 23 /* bool: send all-ones broadcast */ +#define IP_BINDANY 24 /* bool: allow bind to any address */ +#define IP_BINDMULTI 25 /* bool: allow multiple listeners on a tuple */ +#define IP_RSS_LISTEN_BUCKET 26 /* int; set RSS listen bucket */ +#define IP_ORIGDSTADDR 27 /* bool: receive IP dst addr/port w/dgram */ +#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR + +/* + * Options for controlling the firewall and dummynet. + * Historical options (from 40 to 64) will eventually be + * replaced by only two options, IP_FW3 and IP_DUMMYNET3. + */ +#define IP_FW_TABLE_ADD 40 /* add entry */ +#define IP_FW_TABLE_DEL 41 /* delete entry */ +#define IP_FW_TABLE_FLUSH 42 /* flush table */ +#define IP_FW_TABLE_GETSIZE 43 /* get table size */ +#define IP_FW_TABLE_LIST 44 /* list table contents */ + +#define IP_FW3 48 /* generic ipfw v.3 sockopts */ +#define IP_DUMMYNET3 49 /* generic dummynet v.3 sockopts */ + +#define IP_FW_ADD 50 /* add a firewall rule to chain */ +#define IP_FW_DEL 51 /* delete a firewall rule from chain */ +#define IP_FW_FLUSH 52 /* flush firewall rule chain */ +#define IP_FW_ZERO 53 /* clear single/all firewall counter(s) */ +#define IP_FW_GET 54 /* get entire firewall rule chain */ +#define IP_FW_RESETLOG 55 /* reset logging counters */ + +#define IP_FW_NAT_CFG 56 /* add/config a nat rule */ +#define IP_FW_NAT_DEL 57 /* delete a nat rule */ +#define IP_FW_NAT_GET_CONFIG 58 /* get configuration of a nat rule */ +#define IP_FW_NAT_GET_LOG 59 /* get log of a nat rule */ + +#define IP_DUMMYNET_CONFIGURE 60 /* add/configure a dummynet pipe */ +#define IP_DUMMYNET_DEL 61 /* delete a dummynet pipe from chain */ +#define IP_DUMMYNET_FLUSH 62 /* flush dummynet */ +#define IP_DUMMYNET_GET 64 /* get entire dummynet pipes */ + +#define IP_RECVTTL 65 /* bool; receive IP TTL w/dgram */ +#define IP_MINTTL 66 /* minimum TTL for packet or drop */ +#define IP_DONTFRAG 67 /* don't fragment packet */ +#define IP_RECVTOS 68 /* bool; receive IP TOS w/dgram */ + +/* IPv4 Source Filter Multicast API [RFC3678] */ +#define IP_ADD_SOURCE_MEMBERSHIP 70 /* join a source-specific group */ +#define IP_DROP_SOURCE_MEMBERSHIP 71 /* drop a single source */ +#define IP_BLOCK_SOURCE 72 /* block a source */ +#define IP_UNBLOCK_SOURCE 73 /* unblock a source */ + +/* The following option is private; do not use it from user applications. */ +#define IP_MSFILTER 74 /* set/get filter list */ + +/* Protocol Independent Multicast API [RFC3678] */ +#define MCAST_JOIN_GROUP 80 /* join an any-source group */ +#define MCAST_LEAVE_GROUP 81 /* leave all sources for group */ +#define MCAST_JOIN_SOURCE_GROUP 82 /* join a source-specific group */ +#define MCAST_LEAVE_SOURCE_GROUP 83 /* leave a single source */ +#define MCAST_BLOCK_SOURCE 84 /* block a source */ +#define MCAST_UNBLOCK_SOURCE 85 /* unblock a source */ + +/* Flow and RSS definitions */ +#define IP_FLOWID 90 /* get flow id for the given socket/inp */ +#define IP_FLOWTYPE 91 /* get flow type (M_HASHTYPE) */ +#define IP_RSSBUCKETID 92 /* get RSS flowid -> bucket mapping */ +#define IP_RECVFLOWID 93 /* bool; receive IP flowid/flowtype w/ datagram */ +#define IP_RECVRSSBUCKETID 94 /* bool; receive IP RSS bucket id w/ datagram */ + +/* + * Defaults and limits for options + */ +#define IP_DEFAULT_MULTICAST_TTL 1 /* normally limit m'casts to 1 hop */ +#define IP_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */ + +/* + * The imo_membership vector for each socket is now dynamically allocated at + * run-time, bounded by USHRT_MAX, and is reallocated when needed, sized + * according to a power-of-two increment. + */ +#define IP_MIN_MEMBERSHIPS 31 +#define IP_MAX_MEMBERSHIPS 4095 +#define IP_MAX_SOURCE_FILTER 1024 /* XXX to be unused */ + +/* + * Default resource limits for IPv4 multicast source filtering. + * These may be modified by sysctl. + */ +#define IP_MAX_GROUP_SRC_FILTER 512 /* sources per group */ +#define IP_MAX_SOCK_SRC_FILTER 128 /* sources per socket/group */ +#define IP_MAX_SOCK_MUTE_FILTER 128 /* XXX no longer used */ + +/* + * Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP. + */ +struct ip_mreq { + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_interface; /* local IP address of interface */ +}; + +/* + * Modified argument structure for IP_MULTICAST_IF, obtained from Linux. + * This is used to specify an interface index for multicast sends, as + * the IPv4 legacy APIs do not support this (unless IP_SENDIF is available). + */ +struct ip_mreqn { + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_address; /* local IP address of interface */ + int imr_ifindex; /* Interface index; cast to uint32_t */ +}; + +/* + * Argument structure for IPv4 Multicast Source Filter APIs. [RFC3678] + */ +struct ip_mreq_source { + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_sourceaddr; /* IP address of source */ + struct in_addr imr_interface; /* local IP address of interface */ +}; + +/* + * Argument structures for Protocol-Independent Multicast Source + * Filter APIs. [RFC3678] + */ +struct group_req { + uint32_t gr_interface; /* interface index */ + struct sockaddr_storage gr_group; /* group address */ +}; + +struct group_source_req { + uint32_t gsr_interface; /* interface index */ + struct sockaddr_storage gsr_group; /* group address */ + struct sockaddr_storage gsr_source; /* source address */ +}; + +// Removed private stuff +// Removed RFC3678 functions + +/* + * Filter modes; also used to represent per-socket filter mode internally. + */ +#define MCAST_UNDEFINED 0 /* fmode: not yet defined */ +#define MCAST_INCLUDE 1 /* fmode: include these source(s) */ +#define MCAST_EXCLUDE 2 /* fmode: exclude these source(s) */ + +/* + * Argument for IP_PORTRANGE: + * - which range to search when port is unspecified at bind() or connect() + */ +#define IP_PORTRANGE_DEFAULT 0 /* default range */ +#define IP_PORTRANGE_HIGH 1 /* "high" - request firewall bypass */ +#define IP_PORTRANGE_LOW 2 /* "low" - vouchsafe security */ + +/* + * Identifiers for IP sysctl nodes + */ +#define IPCTL_FORWARDING 1 /* act as router */ +#define IPCTL_SENDREDIRECTS 2 /* may send redirects when forwarding */ +#define IPCTL_DEFTTL 3 /* default TTL */ +#ifdef notyet +#define IPCTL_DEFMTU 4 /* default MTU */ +#endif +/* IPCTL_RTEXPIRE 5 deprecated */ +/* IPCTL_RTMINEXPIRE 6 deprecated */ +/* IPCTL_RTMAXCACHE 7 deprecated */ +#define IPCTL_SOURCEROUTE 8 /* may perform source routes */ +#define IPCTL_DIRECTEDBROADCAST 9 /* may re-broadcast received packets */ +#define IPCTL_INTRQMAXLEN 10 /* max length of netisr queue */ +#define IPCTL_INTRQDROPS 11 /* number of netisr q drops */ +#define IPCTL_STATS 12 /* ipstat structure */ +#define IPCTL_ACCEPTSOURCEROUTE 13 /* may accept source routed packets */ +#define IPCTL_FASTFORWARDING 14 /* use fast IP forwarding code */ + /* 15, unused, was: IPCTL_KEEPFAITH */ +#define IPCTL_GIF_TTL 16 /* default TTL for gif encap packet */ +#define IPCTL_INTRDQMAXLEN 17 /* max length of direct netisr queue */ +#define IPCTL_INTRDQDROPS 18 /* number of direct netisr q drops */ + +#endif /* __BSD_VISIBLE */ + +/* INET6 stuff */ +#if __POSIX_VISIBLE >= 200112 +// TuxSH: modified + +#define INET6_ADDRSTRLEN 46 + +// For compliance: + +#define IPV6_UNICAST_HOPS 4 /* int; IP6 hops */ +#define IPV6_MULTICAST_IF 9 /* u_int; set/get IP6 multicast i/f */ +#define IPV6_MULTICAST_HOPS 10 /* int; set/get IP6 multicast hops */ +#define IPV6_MULTICAST_LOOP 11 /* u_int; set/get IP6 multicast loopback */ +#define IPV6_JOIN_GROUP 12 /* ipv6_mreq; join a group membership */ +#define IPV6_LEAVE_GROUP 13 /* ipv6_mreq; leave a group membership */ +#define IPV6_PORTRANGE 14 /* int; range to choose for unspec port */ +#define IPV6_V6ONLY 27 /* bool; make AF_INET6 sockets v6 only */ + +/* + * Unspecified + */ +#define IN6_IS_ADDR_UNSPECIFIED(a) \ + ((a)->__u6_addr.__u6_addr32[0] == 0 && \ + (a)->__u6_addr.__u6_addr32[1] == 0 && \ + (a)->__u6_addr.__u6_addr32[2] == 0 && \ + (a)->__u6_addr.__u6_addr32[3] == 0) + +/* + * Loopback + */ +#define IN6_IS_ADDR_LOOPBACK(a) \ + ((a)->__u6_addr.__u6_addr32[0] == 0 && \ + (a)->__u6_addr.__u6_addr32[1] == 0 && \ + (a)->__u6_addr.__u6_addr32[2] == 0 && \ + (a)->__u6_addr.__u6_addr32[3] == ntohl(1)) + +/* + * IPv4 compatible + */ +#define IN6_IS_ADDR_V4COMPAT(a) \ + ((a)->__u6_addr.__u6_addr32[0] == 0 && \ + (a)->__u6_addr.__u6_addr32[1] == 0 && \ + (a)->__u6_addr.__u6_addr32[2] == 0 && \ + (a)->__u6_addr.__u6_addr32[3] != 0 && \ + (a)->__u6_addr.__u6_addr32[3] != ntohl(1)) + +/* + * Mapped + */ +#define IN6_IS_ADDR_V4MAPPED(a) \ + ((a)->__u6_addr.__u6_addr32[0] == 0 && \ + (a)->__u6_addr.__u6_addr32[1] == 0 && \ + (a)->__u6_addr.__u6_addr32[2] == ntohl(0x0000ffff)) + +#define __IPV6_ADDR_SCOPE_NODELOCAL 0x01 +#define __IPV6_ADDR_SCOPE_INTFACELOCAL 0x01 +#define __IPV6_ADDR_SCOPE_LINKLOCAL 0x02 +#define __IPV6_ADDR_SCOPE_SITELOCAL 0x05 +#define __IPV6_ADDR_SCOPE_ORGLOCAL 0x08 /* just used in this file */ +#define __IPV6_ADDR_SCOPE_GLOBAL 0x0e + +/* + * Unicast Scope + * Note that we must check topmost 10 bits only, not 16 bits (see RFC2373). + */ +#define IN6_IS_ADDR_LINKLOCAL(a) \ + (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80)) +#define IN6_IS_ADDR_SITELOCAL(a) \ + (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) + +/* + * Multicast + */ +#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff) + +#define __IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f) + +#define IN6_IS_ADDR_MC_NODELOCAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL)) +#define IN6_IS_ADDR_MC_LINKLOCAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL)) +#define IN6_IS_ADDR_MC_SITELOCAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL)) +#define IN6_IS_ADDR_MC_ORGLOCAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL)) +#define IN6_IS_ADDR_MC_GLOBAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL)) + +struct in6_addr { + union { + uint16_t __u6_addr16[8]; + uint32_t __u6_addr32[4]; + unsigned char s6_addr[16]; /* IPv6 address */ + }; +}; + +struct sockaddr_in6 { + sa_family_t sin6_family; /* AF_INET6 */ + in_port_t sin6_port; /* port number */ + uint32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ + uint32_t sin6_scope_id; /* Scope ID */ +}; + +extern const struct in6_addr in6addr_any; +extern const struct in6_addr in6addr_loopback; + +#endif + +#endif /* !_NETINET_IN_H_*/ diff --git a/nx/external/bsd/include/netinet/tcp.h b/nx/external/bsd/include/netinet/tcp.h new file mode 100644 index 00000000..c4c58ede --- /dev/null +++ b/nx/external/bsd/include/netinet/tcp.h @@ -0,0 +1,268 @@ +// TuxSH: removed definitions under _KERNEL ifdef blocks, modify the prototype of some functions, some other cleanup, etc. +#ifndef __BSD_VISIBLE +#define __BSD_VISIBLE 1 +#endif + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * @(#)tcp.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD$ + */ + +#ifndef _NETINET_TCP_H_ +#define _NETINET_TCP_H_ + +#include +#include + +#if __BSD_VISIBLE + +typedef u_int32_t tcp_seq; + +#define tcp6_seq tcp_seq /* for KAME src sync over BSD*'s */ +#define tcp6hdr tcphdr /* for KAME src sync over BSD*'s */ + +/* + * TCP header. + * Per RFC 793, September, 1981. + */ +struct tcphdr { + u_short th_sport; /* source port */ + u_short th_dport; /* destination port */ + tcp_seq th_seq; /* sequence number */ + tcp_seq th_ack; /* acknowledgement number */ +#if BYTE_ORDER == LITTLE_ENDIAN + u_char th_x2:4, /* (unused) */ + th_off:4; /* data offset */ +#endif +#if BYTE_ORDER == BIG_ENDIAN + u_char th_off:4, /* data offset */ + th_x2:4; /* (unused) */ +#endif + u_char th_flags; +#define TH_FIN 0x01 +#define TH_SYN 0x02 +#define TH_RST 0x04 +#define TH_PUSH 0x08 +#define TH_ACK 0x10 +#define TH_URG 0x20 +#define TH_ECE 0x40 +#define TH_CWR 0x80 +#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|TH_ECE|TH_CWR) +#define PRINT_TH_FLAGS "\20\1FIN\2SYN\3RST\4PUSH\5ACK\6URG\7ECE\10CWR" + + u_short th_win; /* window */ + u_short th_sum; /* checksum */ + u_short th_urp; /* urgent pointer */ +}; + +#define TCPOPT_EOL 0 +#define TCPOLEN_EOL 1 +#define TCPOPT_PAD 0 /* padding after EOL */ +#define TCPOLEN_PAD 1 +#define TCPOPT_NOP 1 +#define TCPOLEN_NOP 1 +#define TCPOPT_MAXSEG 2 +#define TCPOLEN_MAXSEG 4 +#define TCPOPT_WINDOW 3 +#define TCPOLEN_WINDOW 3 +#define TCPOPT_SACK_PERMITTED 4 +#define TCPOLEN_SACK_PERMITTED 2 +#define TCPOPT_SACK 5 +#define TCPOLEN_SACKHDR 2 +#define TCPOLEN_SACK 8 /* 2*sizeof(tcp_seq) */ +#define TCPOPT_TIMESTAMP 8 +#define TCPOLEN_TIMESTAMP 10 +#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ +#define TCPOPT_SIGNATURE 19 /* Keyed MD5: RFC 2385 */ +#define TCPOLEN_SIGNATURE 18 +#define TCPOPT_FAST_OPEN 34 +#define TCPOLEN_FAST_OPEN_EMPTY 2 +#define TCPOLEN_FAST_OPEN_MIN 6 +#define TCPOLEN_FAST_OPEN_MAX 18 + +/* Miscellaneous constants */ +#define MAX_SACK_BLKS 6 /* Max # SACK blocks stored at receiver side */ +#define TCP_MAX_SACK 4 /* MAX # SACKs sent in any segment */ + + +/* + * The default maximum segment size (MSS) to be used for new TCP connections + * when path MTU discovery is not enabled. + * + * RFC879 derives the default MSS from the largest datagram size hosts are + * minimally required to handle directly or through IP reassembly minus the + * size of the IP and TCP header. With IPv6 the minimum MTU is specified + * in RFC2460. + * + * For IPv4 the MSS is 576 - sizeof(struct tcpiphdr) + * For IPv6 the MSS is IPV6_MMTU - sizeof(struct ip6_hdr) - sizeof(struct tcphdr) + * + * We use explicit numerical definition here to avoid header pollution. + */ +#define TCP_MSS 536 +#define TCP6_MSS 1220 + +/* + * Limit the lowest MSS we accept for path MTU discovery and the TCP SYN MSS + * option. Allowing low values of MSS can consume significant resources and + * be used to mount a resource exhaustion attack. + * Connections requesting lower MSS values will be rounded up to this value + * and the IP_DF flag will be cleared to allow fragmentation along the path. + * + * See tcp_subr.c tcp_minmss SYSCTL declaration for more comments. Setting + * it to "0" disables the minmss check. + * + * The default value is fine for TCP across the Internet's smallest official + * link MTU (256 bytes for AX.25 packet radio). However, a connection is very + * unlikely to come across such low MTU interfaces these days (anno domini 2003). + */ +#define TCP_MINMSS 216 + +#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ +#define TTCP_CLIENT_SND_WND 4096 /* dflt send window for T/TCP client */ + +#define TCP_MAX_WINSHIFT 14 /* maximum window shift */ + +#define TCP_MAXBURST 4 /* maximum segments in a burst */ + +#define TCP_MAXHLEN (0xf<<2) /* max length of header in bytes */ +#define TCP_MAXOLEN (TCP_MAXHLEN - sizeof(struct tcphdr)) + /* max space left for options */ +#endif /* __BSD_VISIBLE */ + +/* + * User-settable options (used with setsockopt). These are discrete + * values and are not masked together. Some values appear to be + * bitmasks for historical reasons. + */ +#define TCP_NODELAY 1 /* don't delay send to coalesce packets */ +#if __BSD_VISIBLE +#define TCP_MAXSEG 2 /* set maximum segment size */ +#define TCP_NOPUSH 4 /* don't push last block of write */ +#define TCP_NOOPT 8 /* don't use TCP options */ +#define TCP_MD5SIG 16 /* use MD5 digests (RFC2385) */ +#define TCP_INFO 32 /* retrieve tcp_info structure */ +#define TCP_CONGESTION 64 /* get/set congestion control algorithm */ +#define TCP_CCALGOOPT 65 /* get/set cc algorithm specific options */ +#define TCP_KEEPINIT 128 /* N, time to establish connection */ +#define TCP_KEEPIDLE 256 /* L,N,X start keeplives after this period */ +#define TCP_KEEPINTVL 512 /* L,N interval between keepalives */ +#define TCP_KEEPCNT 1024 /* L,N number of keepalives before close */ +#define TCP_FASTOPEN 1025 /* enable TFO / was created via TFO */ +#define TCP_PCAP_OUT 2048 /* number of output packets to keep */ +#define TCP_PCAP_IN 4096 /* number of input packets to keep */ +#define TCP_FUNCTION_BLK 8192 /* Set the tcp function pointers to the specified stack */ +/* Start of reserved space for third-party user-settable options. */ +#define TCP_VENDOR SO_VENDOR + +#define TCP_CA_NAME_MAX 16 /* max congestion control name length */ + +#define TCPI_OPT_TIMESTAMPS 0x01 +#define TCPI_OPT_SACK 0x02 +#define TCPI_OPT_WSCALE 0x04 +#define TCPI_OPT_ECN 0x08 +#define TCPI_OPT_TOE 0x10 + +/* + * The TCP_INFO socket option comes from the Linux 2.6 TCP API, and permits + * the caller to query certain information about the state of a TCP + * connection. We provide an overlapping set of fields with the Linux + * implementation, but since this is a fixed size structure, room has been + * left for growth. In order to maximize potential future compatibility with + * the Linux API, the same variable names and order have been adopted, and + * padding left to make room for omitted fields in case they are added later. + * + * XXX: This is currently an unstable ABI/API, in that it is expected to + * change. + */ +struct tcp_info { + u_int8_t tcpi_state; /* TCP FSM state. */ + u_int8_t __tcpi_ca_state; + u_int8_t __tcpi_retransmits; + u_int8_t __tcpi_probes; + u_int8_t __tcpi_backoff; + u_int8_t tcpi_options; /* Options enabled on conn. */ + u_int8_t tcpi_snd_wscale:4, /* RFC1323 send shift value. */ + tcpi_rcv_wscale:4; /* RFC1323 recv shift value. */ + + u_int32_t tcpi_rto; /* Retransmission timeout (usec). */ + u_int32_t __tcpi_ato; + u_int32_t tcpi_snd_mss; /* Max segment size for send. */ + u_int32_t tcpi_rcv_mss; /* Max segment size for receive. */ + + u_int32_t __tcpi_unacked; + u_int32_t __tcpi_sacked; + u_int32_t __tcpi_lost; + u_int32_t __tcpi_retrans; + u_int32_t __tcpi_fackets; + + /* Times; measurements in usecs. */ + u_int32_t __tcpi_last_data_sent; + u_int32_t __tcpi_last_ack_sent; /* Also unimpl. on Linux? */ + u_int32_t tcpi_last_data_recv; /* Time since last recv data. */ + u_int32_t __tcpi_last_ack_recv; + + /* Metrics; variable units. */ + u_int32_t __tcpi_pmtu; + u_int32_t __tcpi_rcv_ssthresh; + u_int32_t tcpi_rtt; /* Smoothed RTT in usecs. */ + u_int32_t tcpi_rttvar; /* RTT variance in usecs. */ + u_int32_t tcpi_snd_ssthresh; /* Slow start threshold. */ + u_int32_t tcpi_snd_cwnd; /* Send congestion window. */ + u_int32_t __tcpi_advmss; + u_int32_t __tcpi_reordering; + + u_int32_t __tcpi_rcv_rtt; + u_int32_t tcpi_rcv_space; /* Advertised recv window. */ + + /* FreeBSD extensions to tcp_info. */ + u_int32_t tcpi_snd_wnd; /* Advertised send window. */ + u_int32_t tcpi_snd_bwnd; /* No longer used. */ + u_int32_t tcpi_snd_nxt; /* Next egress seqno */ + u_int32_t tcpi_rcv_nxt; /* Next ingress seqno */ + u_int32_t tcpi_toe_tid; /* HWTID for TOE endpoints */ + u_int32_t tcpi_snd_rexmitpack; /* Retransmitted packets */ + u_int32_t tcpi_rcv_ooopack; /* Out-of-order packets */ + u_int32_t tcpi_snd_zerowin; /* Zero-sized windows sent */ + + /* Padding to grow without breaking ABI. */ + u_int32_t __tcpi_pad[26]; /* Padding. */ +}; +#endif +#define TCP_FUNCTION_NAME_LEN_MAX 32 + +struct tcp_function_set { + char function_set_name[TCP_FUNCTION_NAME_LEN_MAX]; + uint32_t pcbcnt; +}; + +#endif /* !_NETINET_TCP_H_ */ diff --git a/nx/external/bsd/include/netinet/udp.h b/nx/external/bsd/include/netinet/udp.h new file mode 100644 index 00000000..6f8eff76 --- /dev/null +++ b/nx/external/bsd/include/netinet/udp.h @@ -0,0 +1,81 @@ +// TuxSH: removed definitions under _KERNEL ifdef blocks, modify the prototype of some functions, some other cleanup, etc. +#ifndef __BSD_VISIBLE +#define __BSD_VISIBLE 1 +#endif + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. + * All rights reserved. + * + * 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. 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. + * + * @(#)udp.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD$ + */ + +#ifndef _NETINET_UDP_H_ +#define _NETINET_UDP_H_ + +// Added: +#include +#include +#include + +/* + * UDP protocol header. + * Per RFC 768, September, 1981. + */ +struct udphdr { + u_short uh_sport; /* source port */ + u_short uh_dport; /* destination port */ + u_short uh_ulen; /* udp length */ + u_short uh_sum; /* udp checksum */ +}; + +/* + * User-settable options (used with setsockopt). + */ +#define UDP_ENCAP 1 + +/* Start of reserved space for third-party user-settable options. */ +#define UDP_VENDOR SO_VENDOR + +/* + * UDP Encapsulation of IPsec Packets options. + */ +/* Encapsulation types. */ +#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */ +#define UDP_ENCAP_ESPINUDP 2 /* RFC3948 */ + +/* Default ESP in UDP encapsulation port. */ +#define UDP_ENCAP_ESPINUDP_PORT 500 + +/* Maximum UDP fragment size for ESP over UDP. */ +#define UDP_ENCAP_ESPINUDP_MAXFRAGLEN 552 + +#endif diff --git a/nx/external/bsd/include/poll.h b/nx/external/bsd/include/poll.h new file mode 100644 index 00000000..9e82e741 --- /dev/null +++ b/nx/external/bsd/include/poll.h @@ -0,0 +1,122 @@ +// TuxSH: removed definitions under _KERNEL ifdef blocks, modify the prototype of some functions, some other cleanup, etc. +#ifndef __BSD_VISIBLE +#define __BSD_VISIBLE 1 +#endif + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1997 Peter Wemm + * All rights reserved. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _SYS_POLL_H_ +#define _SYS_POLL_H_ + +#include + +/* + * This file is intended to be compatible with the traditional poll.h. + */ + +typedef unsigned int nfds_t; + +/* + * This structure is passed as an array to poll(2). + */ +struct pollfd { + int fd; /* which file descriptor to poll */ + short events; /* events we are interested in */ + short revents; /* events found on return */ +}; + +/* + * Requestable events. If poll(2) finds any of these set, they are + * copied to revents on return. + * XXX Note that FreeBSD doesn't make much distinction between POLLPRI + * and POLLRDBAND since none of the file types have distinct priority + * bands - and only some have an urgent "mode". + * XXX Note POLLIN isn't really supported in true SVSV terms. Under SYSV + * POLLIN includes all of normal, band and urgent data. Most poll handlers + * on FreeBSD only treat it as "normal" data. + */ +#define POLLIN 0x0001 /* any readable data available */ +#define POLLPRI 0x0002 /* OOB/Urgent readable data */ +#define POLLOUT 0x0004 /* file descriptor is writeable */ +#define POLLRDNORM 0x0040 /* non-OOB/URG data available */ +#define POLLWRNORM POLLOUT /* no write type differentiation */ +#define POLLRDBAND 0x0080 /* OOB/Urgent readable data */ +#define POLLWRBAND 0x0100 /* OOB/Urgent data can be written */ + +#if __BSD_VISIBLE +/* General FreeBSD extension (currently only supported for sockets): */ +#define POLLINIGNEOF 0x2000 /* like POLLIN, except ignore EOF */ +#endif + +/* + * These events are set if they occur regardless of whether they were + * requested. + */ +#define POLLERR 0x0008 /* some poll error occurred */ +#define POLLHUP 0x0010 /* file descriptor was "hung up" */ +#define POLLNVAL 0x0020 /* requested events "invalid" */ + +#if __BSD_VISIBLE + +#define POLLSTANDARD (POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLRDBAND|\ + POLLWRBAND|POLLERR|POLLHUP|POLLNVAL) + +/* + * Request that poll() wait forever. + * XXX in SYSV, this is defined in stropts.h, which is not included + * by poll.h. + */ +#define INFTIM (-1) + +#endif + + +#if __BSD_VISIBLE +#include + +#include +#include + +#ifndef _SIGSET_T_DECLARED +#define _SIGSET_T_DECLARED +typedef __sigset_t sigset_t; +#endif + +#endif + +__BEGIN_DECLS +int poll(struct pollfd *pfd, nfds_t nfds, int timeout); +// changed poll argument names ; removed ppoll because it is not exposed +__END_DECLS + +#endif /* !_SYS_POLL_H_ */ diff --git a/nx/external/bsd/include/sys/_iovec.h b/nx/external/bsd/include/sys/_iovec.h new file mode 100644 index 00000000..80af42c7 --- /dev/null +++ b/nx/external/bsd/include/sys/_iovec.h @@ -0,0 +1,48 @@ +// TuxSH: removed definitions under _KERNEL ifdef blocks, modify the prototype of some functions, some other cleanup, etc. + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1982, 1986, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * @(#)uio.h 8.5 (Berkeley) 2/22/94 + * $FreeBSD$ + */ + +#ifndef _SYS__IOVEC_H_ +#define _SYS__IOVEC_H_ + +#include // changed +#include + +struct iovec { + void *iov_base; /* Base address. */ + size_t iov_len; /* Length. */ +}; + +#endif /* !_SYS__IOVEC_H_ */ diff --git a/nx/external/bsd/include/sys/_sockaddr_storage.h b/nx/external/bsd/include/sys/_sockaddr_storage.h new file mode 100644 index 00000000..90e52e31 --- /dev/null +++ b/nx/external/bsd/include/sys/_sockaddr_storage.h @@ -0,0 +1,59 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * @(#)socket.h 8.4 (Berkeley) 2/21/94 + * $FreeBSD$ + */ + +#ifndef _SYS__SOCKADDR_STORAGE_H_ +#define _SYS__SOCKADDR_STORAGE_H_ + +#include // changed +#include + +/* + * RFC 2553: protocol-independent placeholder for socket addresses + */ +#define _SS_MAXSIZE 128U +#define _SS_ALIGNSIZE (sizeof(__int64_t)) +#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) - \ + sizeof(sa_family_t)) +#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) - \ + sizeof(sa_family_t) - _SS_PAD1SIZE - _SS_ALIGNSIZE) + +struct sockaddr_storage { + unsigned char ss_len; /* address length */ + sa_family_t ss_family; /* address family */ + char __ss_pad1[_SS_PAD1SIZE]; + int64_t __ss_align; /* force desired struct alignment */ // changed + char __ss_pad2[_SS_PAD2SIZE]; +}; + +#endif /* !_SYS__SOCKADDR_STORAGE_H_ */ diff --git a/nx/external/bsd/include/sys/filio.h b/nx/external/bsd/include/sys/filio.h new file mode 100644 index 00000000..7899791f --- /dev/null +++ b/nx/external/bsd/include/sys/filio.h @@ -0,0 +1,66 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, 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. 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. + * + * @(#)filio.h 8.1 (Berkeley) 3/28/94 + * $FreeBSD$ + */ + +#ifndef _SYS_FILIO_H_ +#define _SYS_FILIO_H_ + +#include + +/* Generic file-descriptor ioctl's. */ +#define FIOCLEX _IO('f', 1) /* set close on exec on fd */ +#define FIONCLEX _IO('f', 2) /* remove close on exec */ +#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */ +#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */ +#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */ +#define FIOSETOWN _IOW('f', 124, int) /* set owner */ +#define FIOGETOWN _IOR('f', 123, int) /* get owner */ +#define FIODTYPE _IOR('f', 122, int) /* get d_flags type part */ +#define FIOGETLBA _IOR('f', 121, int) /* get start blk # */ +struct fiodgname_arg { + int len; + void *buf; +}; +#define FIODGNAME _IOW('f', 120, struct fiodgname_arg) /* get dev. name */ +#define FIONWRITE _IOR('f', 119, int) /* get # bytes (yet) to write */ +#define FIONSPACE _IOR('f', 118, int) /* get space in send queue */ +/* Handle lseek SEEK_DATA and SEEK_HOLE for holey file knowledge. */ +#define FIOSEEKDATA _IOWR('f', 97, off_t) /* SEEK_DATA */ +#define FIOSEEKHOLE _IOWR('f', 98, off_t) /* SEEK_HOLE */ + +#endif /* !_SYS_FILIO_H_ */ diff --git a/nx/external/bsd/include/sys/ioccom.h b/nx/external/bsd/include/sys/ioccom.h new file mode 100644 index 00000000..eaaf8089 --- /dev/null +++ b/nx/external/bsd/include/sys/ioccom.h @@ -0,0 +1,74 @@ +// TuxSH: removed definitions under _KERNEL ifdef blocks, modify the prototype of some functions, some other cleanup, etc. + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * @(#)ioccom.h 8.2 (Berkeley) 3/28/94 + * $FreeBSD$ + */ + +#ifndef _SYS_IOCCOM_H_ +#define _SYS_IOCCOM_H_ + +/* + * Ioctl's have the command encoded in the lower word, and the size of + * any in or out parameters in the upper word. The high 3 bits of the + * upper word are used to encode the in/out status of the parameter. + */ +#define IOCPARM_SHIFT 13 /* number of bits for ioctl size */ +#define IOCPARM_MASK ((1 << IOCPARM_SHIFT) - 1) /* parameter length mask */ +#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) +#define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16)) +#define IOCGROUP(x) (((x) >> 8) & 0xff) + +#define IOCPARM_MAX (1 << IOCPARM_SHIFT) /* max size of ioctl */ +#define IOC_VOID 0x20000000 /* no parameters */ +#define IOC_OUT 0x40000000 /* copy out parameters */ +#define IOC_IN 0x80000000 /* copy in parameters */ +#define IOC_INOUT (IOC_IN|IOC_OUT) +#define IOC_DIRMASK (IOC_VOID|IOC_OUT|IOC_IN) + +#define _IOC(inout,group,num,len) ((unsigned long) \ + ((inout) | (((len) & IOCPARM_MASK) << 16) | ((group) << 8) | (num))) +#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0) +#define _IOWINT(g,n) _IOC(IOC_VOID, (g), (n), sizeof(int)) +#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) +#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) +/* this should be _IORW, but stdio got there first */ +#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t)) + +#include + +__BEGIN_DECLS +// Modified declaration +int ioctl(int fd, int request, ...); +__END_DECLS + +#endif /* !_SYS_IOCCOM_H_ */ diff --git a/nx/external/bsd/include/sys/ioctl.h b/nx/external/bsd/include/sys/ioctl.h new file mode 100644 index 00000000..2753d835 --- /dev/null +++ b/nx/external/bsd/include/sys/ioctl.h @@ -0,0 +1,52 @@ +// TuxSH: removed definitions under _KERNEL ifdef block, modify the prototype of some functions, +// some other changes + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, 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. 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. + * + * @(#)ioctl.h 8.6 (Berkeley) 3/28/94 + * $FreeBSD$ + */ + +#ifndef _SYS_IOCTL_H_ +#define _SYS_IOCTL_H_ + +#include + +#include +#include +//#include + +#endif /* !_SYS_IOCTL_H_ */ diff --git a/nx/external/bsd/include/sys/socket.h b/nx/external/bsd/include/sys/socket.h new file mode 100644 index 00000000..c8195dc2 --- /dev/null +++ b/nx/external/bsd/include/sys/socket.h @@ -0,0 +1,570 @@ +// TuxSH: removed definitions under _KERNEL ifdef blocks, modify the prototype of some functions, some other cleanup, etc. +#ifndef __BSD_VISIBLE +#define __BSD_VISIBLE 1 +#endif + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * @(#)socket.h 8.4 (Berkeley) 2/21/94 + * $FreeBSD$ + */ + +#ifndef _SYS_SOCKET_H_ +#define _SYS_SOCKET_H_ + +#include +#include +#include + +/* + * Definitions related to sockets: types, address families, options. + */ + +/* + * Data types. + */ + +// Stripped some of them +#include // for ssize_t, etc. +#include + +#ifndef _SA_FAMILY_T_DECLARED +typedef __sa_family_t sa_family_t; +#define _SA_FAMILY_T_DECLARED +#endif + +#ifndef _SOCKLEN_T_DECLARED +typedef __socklen_t socklen_t; +#define _SOCKLEN_T_DECLARED +#endif + +/* + * Types + */ +#define SOCK_STREAM 1 /* stream socket */ +#define SOCK_DGRAM 2 /* datagram socket */ +#define SOCK_RAW 3 /* raw-protocol interface */ +#if __BSD_VISIBLE +#define SOCK_RDM 4 /* reliably-delivered message */ +#endif +#define SOCK_SEQPACKET 5 /* sequenced packet stream */ + +#if __BSD_VISIBLE +/* + * Creation flags, OR'ed into socket() and socketpair() type argument. + */ +#define SOCK_CLOEXEC 0x10000000 +#define SOCK_NONBLOCK 0x20000000 + +#endif /* __BSD_VISIBLE */ + +/* + * Option flags per-socket. + */ +#define SO_DEBUG 0x0001 /* turn on debugging info recording */ +#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ +#define SO_REUSEADDR 0x0004 /* allow local address reuse */ +#define SO_KEEPALIVE 0x0008 /* keep connections alive */ +#define SO_DONTROUTE 0x0010 /* just use interface addresses */ +#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */ +#if __BSD_VISIBLE +#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */ +#endif +#define SO_LINGER 0x0080 /* linger on close if data present */ +#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */ +#if __BSD_VISIBLE +#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */ +#define SO_TIMESTAMP 0x0400 /* timestamp received dgram traffic */ +#define SO_NOSIGPIPE 0x0800 /* no SIGPIPE from EPIPE */ +#define SO_ACCEPTFILTER 0x1000 /* there is an accept filter */ +#define SO_BINTIME 0x2000 /* timestamp received dgram traffic */ +#endif +#define SO_NO_OFFLOAD 0x4000 /* socket cannot be offloaded */ +#define SO_NO_DDP 0x8000 /* disable direct data placement */ + +/* + * Additional options, not kept in so_options. + */ +#define SO_SNDBUF 0x1001 /* send buffer size */ +#define SO_RCVBUF 0x1002 /* receive buffer size */ +#define SO_SNDLOWAT 0x1003 /* send low-water mark */ +#define SO_RCVLOWAT 0x1004 /* receive low-water mark */ +#define SO_SNDTIMEO 0x1005 /* send timeout */ +#define SO_RCVTIMEO 0x1006 /* receive timeout */ +#define SO_ERROR 0x1007 /* get error status and clear */ +#define SO_TYPE 0x1008 /* get socket type */ +#if __BSD_VISIBLE +#define SO_LABEL 0x1009 /* socket's MAC label */ +#define SO_PEERLABEL 0x1010 /* socket's peer's MAC label */ +#define SO_LISTENQLIMIT 0x1011 /* socket's backlog limit */ +#define SO_LISTENQLEN 0x1012 /* socket's complete queue length */ +#define SO_LISTENINCQLEN 0x1013 /* socket's incomplete queue length */ +#define SO_SETFIB 0x1014 /* use this FIB to route */ +#define SO_USER_COOKIE 0x1015 /* user cookie (dummynet etc.) */ +#define SO_PROTOCOL 0x1016 /* get socket protocol (Linux name) */ +#define SO_PROTOTYPE SO_PROTOCOL /* alias for SO_PROTOCOL (SunOS name) */ +#define SO_TS_CLOCK 0x1017 /* clock type used for SO_TIMESTAMP */ +#define SO_MAX_PACING_RATE 0x1018 /* socket's max TX pacing rate (Linux name) */ +#endif + +#if __BSD_VISIBLE +#define SO_TS_REALTIME_MICRO 0 /* microsecond resolution, realtime */ +#define SO_TS_BINTIME 1 /* sub-nanosecond resolution, realtime */ +#define SO_TS_REALTIME 2 /* nanosecond resolution, realtime */ +#define SO_TS_MONOTONIC 3 /* nanosecond resolution, monotonic */ +#define SO_TS_DEFAULT SO_TS_REALTIME_MICRO +#define SO_TS_CLOCK_MAX SO_TS_MONOTONIC +#endif + +/* + * Space reserved for new socket options added by third-party vendors. + * This range applies to all socket option levels. New socket options + * in FreeBSD should always use an option value less than SO_VENDOR. + */ +#if __BSD_VISIBLE +#define SO_VENDOR 0x80000000 +#endif + +/* + * Structure used for manipulating linger option. + */ +struct linger { + int l_onoff; /* option on/off */ + int l_linger; /* linger time */ +}; + +#if __BSD_VISIBLE +struct accept_filter_arg { + char af_name[16]; + char af_arg[256-16]; +}; +#endif + +/* + * Level number for (get/set)sockopt() to apply to socket itself. + */ +#define SOL_SOCKET 0xffff /* options for socket level */ + +/* + * Address families. + */ +#define AF_UNSPEC 0 /* unspecified */ +#if __BSD_VISIBLE +#define AF_LOCAL AF_UNIX /* local to host (pipes, portals) */ +#endif +#define AF_UNIX 1 /* standardized name for AF_LOCAL */ +#define AF_INET 2 /* internetwork: UDP, TCP, etc. */ +#if __BSD_VISIBLE +#define AF_IMPLINK 3 /* arpanet imp addresses */ +#define AF_PUP 4 /* pup protocols: e.g. BSP */ +#define AF_CHAOS 5 /* mit CHAOS protocols */ +#define AF_NETBIOS 6 /* SMB protocols */ +#define AF_ISO 7 /* ISO protocols */ +#define AF_OSI AF_ISO +#define AF_ECMA 8 /* European computer manufacturers */ +#define AF_DATAKIT 9 /* datakit protocols */ +#define AF_CCITT 10 /* CCITT protocols, X.25 etc */ +#define AF_SNA 11 /* IBM SNA */ +#define AF_DECnet 12 /* DECnet */ +#define AF_DLI 13 /* DEC Direct data link interface */ +#define AF_LAT 14 /* LAT */ +#define AF_HYLINK 15 /* NSC Hyperchannel */ +#define AF_APPLETALK 16 /* Apple Talk */ +#define AF_ROUTE 17 /* Internal Routing Protocol */ +#define AF_LINK 18 /* Link layer interface */ +#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */ +#define AF_COIP 20 /* connection-oriented IP, aka ST II */ +#define AF_CNT 21 /* Computer Network Technology */ +#define pseudo_AF_RTIP 22 /* Help Identify RTIP packets */ +#define AF_IPX 23 /* Novell Internet Protocol */ +#define AF_SIP 24 /* Simple Internet Protocol */ +#define pseudo_AF_PIP 25 /* Help Identify PIP packets */ +#define AF_ISDN 26 /* Integrated Services Digital Network*/ +#define AF_E164 AF_ISDN /* CCITT E.164 recommendation */ +#define pseudo_AF_KEY 27 /* Internal key-management function */ +#endif +#define AF_INET6 28 /* IPv6 */ +#if __BSD_VISIBLE +#define AF_NATM 29 /* native ATM access */ +#define AF_ATM 30 /* ATM */ +#define pseudo_AF_HDRCMPLT 31 /* Used by BPF to not rewrite headers + * in interface output routine + */ +#define AF_NETGRAPH 32 /* Netgraph sockets */ +#define AF_SLOW 33 /* 802.3ad slow protocol */ +#define AF_SCLUSTER 34 /* Sitara cluster protocol */ +#define AF_ARP 35 +#define AF_BLUETOOTH 36 /* Bluetooth sockets */ +#define AF_IEEE80211 37 /* IEEE 802.11 protocol */ +#define AF_INET_SDP 40 /* OFED Socket Direct Protocol ipv4 */ +#define AF_INET6_SDP 42 /* OFED Socket Direct Protocol ipv6 */ +#define AF_MAX 42 +/* + * When allocating a new AF_ constant, please only allocate + * even numbered constants for FreeBSD until 134 as odd numbered AF_ + * constants 39-133 are now reserved for vendors. + */ +#define AF_VENDOR00 39 +#define AF_VENDOR01 41 +#define AF_VENDOR02 43 +#define AF_VENDOR03 45 +#define AF_VENDOR04 47 +#define AF_VENDOR05 49 +#define AF_VENDOR06 51 +#define AF_VENDOR07 53 +#define AF_VENDOR08 55 +#define AF_VENDOR09 57 +#define AF_VENDOR10 59 +#define AF_VENDOR11 61 +#define AF_VENDOR12 63 +#define AF_VENDOR13 65 +#define AF_VENDOR14 67 +#define AF_VENDOR15 69 +#define AF_VENDOR16 71 +#define AF_VENDOR17 73 +#define AF_VENDOR18 75 +#define AF_VENDOR19 77 +#define AF_VENDOR20 79 +#define AF_VENDOR21 81 +#define AF_VENDOR22 83 +#define AF_VENDOR23 85 +#define AF_VENDOR24 87 +#define AF_VENDOR25 89 +#define AF_VENDOR26 91 +#define AF_VENDOR27 93 +#define AF_VENDOR28 95 +#define AF_VENDOR29 97 +#define AF_VENDOR30 99 +#define AF_VENDOR31 101 +#define AF_VENDOR32 103 +#define AF_VENDOR33 105 +#define AF_VENDOR34 107 +#define AF_VENDOR35 109 +#define AF_VENDOR36 111 +#define AF_VENDOR37 113 +#define AF_VENDOR38 115 +#define AF_VENDOR39 117 +#define AF_VENDOR40 119 +#define AF_VENDOR41 121 +#define AF_VENDOR42 123 +#define AF_VENDOR43 125 +#define AF_VENDOR44 127 +#define AF_VENDOR45 129 +#define AF_VENDOR46 131 +#define AF_VENDOR47 133 +#endif + +/* + * Structure used by kernel to store most + * addresses. + */ +struct sockaddr { + unsigned char sa_len; /* total length */ + sa_family_t sa_family; /* address family */ + char sa_data[14]; /* actually longer; address value */ +}; +#if __BSD_VISIBLE +#define SOCK_MAXADDRLEN 255 /* longest possible addresses */ + +/* + * Structure used by kernel to pass protocol + * information in raw sockets. + */ +struct sockproto { + unsigned short sp_family; /* address family */ + unsigned short sp_protocol; /* protocol */ +}; +#endif + +#include + +#if __BSD_VISIBLE +/* + * Protocol families, same as address families for now. + */ +#define PF_UNSPEC AF_UNSPEC +#define PF_LOCAL AF_LOCAL +#define PF_UNIX PF_LOCAL /* backward compatibility */ +#define PF_INET AF_INET +#define PF_IMPLINK AF_IMPLINK +#define PF_PUP AF_PUP +#define PF_CHAOS AF_CHAOS +#define PF_NETBIOS AF_NETBIOS +#define PF_ISO AF_ISO +#define PF_OSI AF_ISO +#define PF_ECMA AF_ECMA +#define PF_DATAKIT AF_DATAKIT +#define PF_CCITT AF_CCITT +#define PF_SNA AF_SNA +#define PF_DECnet AF_DECnet +#define PF_DLI AF_DLI +#define PF_LAT AF_LAT +#define PF_HYLINK AF_HYLINK +#define PF_APPLETALK AF_APPLETALK +#define PF_ROUTE AF_ROUTE +#define PF_LINK AF_LINK +#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */ +#define PF_COIP AF_COIP +#define PF_CNT AF_CNT +#define PF_SIP AF_SIP +#define PF_IPX AF_IPX +#define PF_RTIP pseudo_AF_RTIP /* same format as AF_INET */ +#define PF_PIP pseudo_AF_PIP +#define PF_ISDN AF_ISDN +#define PF_KEY pseudo_AF_KEY +#define PF_INET6 AF_INET6 +#define PF_NATM AF_NATM +#define PF_ATM AF_ATM +#define PF_NETGRAPH AF_NETGRAPH +#define PF_SLOW AF_SLOW +#define PF_SCLUSTER AF_SCLUSTER +#define PF_ARP AF_ARP +#define PF_BLUETOOTH AF_BLUETOOTH +#define PF_IEEE80211 AF_IEEE80211 +#define PF_INET_SDP AF_INET_SDP +#define PF_INET6_SDP AF_INET6_SDP + +#define PF_MAX AF_MAX + +/* + * Definitions for network related sysctl, CTL_NET. + * + * Second level is protocol family. + * Third level is protocol number. + * + * Further levels are defined by the individual families. + */ + +/* + * PF_ROUTE - Routing table + * + * Three additional levels are defined: + * Fourth: address family, 0 is wildcard + * Fifth: type of info, defined below + * Sixth: flag(s) to mask with for NET_RT_FLAGS + */ +#define NET_RT_DUMP 1 /* dump; may limit to a.f. */ +#define NET_RT_FLAGS 2 /* by flags, e.g. RESOLVING */ +#define NET_RT_IFLIST 3 /* survey interface list */ +#define NET_RT_IFMALIST 4 /* return multicast address list */ +#define NET_RT_IFLISTL 5 /* Survey interface list, using 'l'en + * versions of msghdr structs. */ +#endif /* __BSD_VISIBLE */ + +/* + * Maximum queue length specifiable by listen. + */ +#define SOMAXCONN 128 + +/* + * Message header for recvmsg and sendmsg calls. + * Used value-result for recvmsg, value only for sendmsg. + */ +struct msghdr { + void *msg_name; /* optional address */ + socklen_t msg_namelen; /* size of address */ + struct iovec *msg_iov; /* scatter/gather array */ + int msg_iovlen; /* # elements in msg_iov */ + void *msg_control; /* ancillary data, see below */ + socklen_t msg_controllen; /* ancillary data buffer len */ + int msg_flags; /* flags on received message */ +}; + +#define MSG_OOB 0x00000001 /* process out-of-band data */ +#define MSG_PEEK 0x00000002 /* peek at incoming message */ +#define MSG_DONTROUTE 0x00000004 /* send without using routing tables */ +#define MSG_EOR 0x00000008 /* data completes record */ +#define MSG_TRUNC 0x00000010 /* data discarded before delivery */ +#define MSG_CTRUNC 0x00000020 /* control data lost before delivery */ +#define MSG_WAITALL 0x00000040 /* wait for full request or error */ +#if __BSD_VISIBLE +#define MSG_DONTWAIT 0x00000080 /* this message should be nonblocking */ +#define MSG_EOF 0x00000100 /* data completes connection */ +/* 0x00000200 unused */ +/* 0x00000400 unused */ +/* 0x00000800 unused */ +/* 0x00001000 unused */ +#define MSG_NOTIFICATION 0x00002000 /* SCTP notification */ +#define MSG_NBIO 0x00004000 /* FIONBIO mode, used by fifofs */ +#define MSG_COMPAT 0x00008000 /* used in sendit() */ +#endif +#if __POSIX_VISIBLE >= 200809 +#define MSG_NOSIGNAL 0x00020000 /* do not generate SIGPIPE on EOF */ +#endif +#if __BSD_VISIBLE +#define MSG_CMSG_CLOEXEC 0x00040000 /* make received fds close-on-exec */ +#define MSG_WAITFORONE 0x00080000 /* for recvmmsg() */ +#endif + +/* + * Header for ancillary data objects in msg_control buffer. + * Used for additional information with/about a datagram + * not expressible by flags. The format is a sequence + * of message elements headed by cmsghdr structures. + */ +struct cmsghdr { + socklen_t cmsg_len; /* data byte count, including hdr */ + int cmsg_level; /* originating protocol */ + int cmsg_type; /* protocol-specific type */ +/* followed by u_char cmsg_data[]; */ +}; + +// socket credential stuff, we don't need this +// cmsg macros, uses some obscure macro + +/* "Socket"-level control message types: */ +#define SCM_RIGHTS 0x01 /* access rights (array of int) */ +#if __BSD_VISIBLE +#define SCM_TIMESTAMP 0x02 /* timestamp (struct timeval) */ +#define SCM_CREDS 0x03 /* process creds (struct cmsgcred) */ +#define SCM_BINTIME 0x04 /* timestamp (struct bintime) */ +#define SCM_REALTIME 0x05 /* timestamp (struct timespec) */ +#define SCM_MONOTONIC 0x06 /* timestamp (struct timespec) */ +#define SCM_TIME_INFO 0x07 /* timestamp info */ + +struct sock_timestamp_info { + uint32_t st_info_flags; + uint32_t st_info_pad0; + uint64_t st_info_rsv[7]; +}; + +#define ST_INFO_HW 0x0001 /* SCM_TIMESTAMP was hw */ +#define ST_INFO_HW_HPREC 0x0002 /* SCM_TIMESTAMP was hw-assisted + on entrance */ +#endif + +#if __BSD_VISIBLE +/* + * 4.3 compat sockaddr, move to compat file later + */ +struct osockaddr { + unsigned short sa_family; /* address family */ + char sa_data[14]; /* up to 14 bytes of direct address */ +}; + +/* + * 4.3-compat message header (move to compat file later). + */ +struct omsghdr { + char *msg_name; /* optional address */ + int msg_namelen; /* size of address */ + struct iovec *msg_iov; /* scatter/gather array */ + int msg_iovlen; /* # elements in msg_iov */ + char *msg_accrights; /* access rights sent/received */ + int msg_accrightslen; +}; +#endif + +/* + * howto arguments for shutdown(2), specified by Posix.1g. + */ +#define SHUT_RD 0 /* shut down the reading side */ +#define SHUT_WR 1 /* shut down the writing side */ +#define SHUT_RDWR 2 /* shut down both sides */ + +#if __BSD_VISIBLE +/* for SCTP */ +/* we cheat and use the SHUT_XX defines for these */ +#define PRU_FLUSH_RD SHUT_RD +#define PRU_FLUSH_WR SHUT_WR +#define PRU_FLUSH_RDWR SHUT_RDWR +#endif + + +#if __BSD_VISIBLE +/* + * sendfile(2) header/trailer struct + */ +struct sf_hdtr { + struct iovec *headers; /* pointer to an array of header struct iovec's */ + int hdr_cnt; /* number of header iovec's */ + struct iovec *trailers; /* pointer to an array of trailer struct iovec's */ + int trl_cnt; /* number of trailer iovec's */ +}; + +/* + * Sendfile-specific flag(s) + */ +#define SF_NODISKIO 0x00000001 +#define SF_MNOWAIT 0x00000002 /* obsolete */ +#define SF_SYNC 0x00000004 +#define SF_USER_READAHEAD 0x00000008 +#define SF_NOCACHE 0x00000010 +#define SF_FLAGS(rh, flags) (((rh) << 16) | (flags)) +/* + * Sendmmsg/recvmmsg specific structure(s) + */ +struct mmsghdr { + struct msghdr msg_hdr; /* message header */ + ssize_t msg_len; /* message length */ +}; +#endif /* __BSD_VISIBLE */ + +#include + +// Note: rewrote the definitions to make them more POSIX-compliant and such, adding back arg names +// Remove some function declarations + +__BEGIN_DECLS + +// Note: POSIX claims that some prototypes should take restrict ptrs +// But this causes more problem that it solves, so much like linux +// We won't declare those args restrict. + +int socket(int domain, int type, int protocol); +ssize_t recv(int sockfd, void *buf, size_t len, int flags); +ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); +ssize_t send(int sockfd, const void* buf, size_t len, int flags); +ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); +int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); +int listen(int sockfd, int backlog); +int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); +int shutdown(int sockfd, int how); + +int sockatmark(int sockfd); +int socketpair(int domain, int type, int protocol, int sv[2]); + +ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); +ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags); + +#if __BSD_VISIBLE +struct timespec; +int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags); +int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout); +#endif +__END_DECLS + +#endif /* !_SYS_SOCKET_H_ */ diff --git a/nx/external/bsd/include/sys/sockio.h b/nx/external/bsd/include/sys/sockio.h new file mode 100644 index 00000000..3e35f307 --- /dev/null +++ b/nx/external/bsd/include/sys/sockio.h @@ -0,0 +1,143 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * 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. 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. + * + * @(#)sockio.h 8.1 (Berkeley) 3/28/94 + * $FreeBSD$ + */ + +#ifndef _SYS_SOCKIO_H_ +#define _SYS_SOCKIO_H_ + +#include + +/* Socket ioctl's. */ +#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */ +#define SIOCSPGRP _IOW('s', 8, int) /* set process group */ +#define SIOCGPGRP _IOR('s', 9, int) /* get process group */ + +/* SIOCADDRT _IOW('r', 10, struct ortentry) 4.3BSD */ +/* SIOCDELRT _IOW('r', 11, struct ortentry) 4.3BSD */ +#define SIOCGETVIFCNT _IOWR('r', 15, struct sioc_vif_req)/* get vif pkt cnt */ +#define SIOCGETSGCNT _IOWR('r', 16, struct sioc_sg_req) /* get s,g pkt cnt */ + +#define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */ +/* OSIOCGIFADDR _IOWR('i', 13, struct ifreq) 4.3BSD */ +#define SIOCGIFADDR _IOWR('i', 33, struct ifreq) /* get ifnet address */ +#define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */ +/* OSIOCGIFDSTADDR _IOWR('i', 15, struct ifreq) 4.3BSD */ +#define SIOCGIFDSTADDR _IOWR('i', 34, struct ifreq) /* get p-p address */ +#define SIOCSIFFLAGS _IOW('i', 16, struct ifreq) /* set ifnet flags */ +#define SIOCGIFFLAGS _IOWR('i', 17, struct ifreq) /* get ifnet flags */ +/* OSIOCGIFBRDADDR _IOWR('i', 18, struct ifreq) 4.3BSD */ +#define SIOCGIFBRDADDR _IOWR('i', 35, struct ifreq) /* get broadcast addr */ +#define SIOCSIFBRDADDR _IOW('i', 19, struct ifreq) /* set broadcast addr */ +/* OSIOCGIFCONF _IOWR('i', 20, struct ifconf) 4.3BSD */ +#define SIOCGIFCONF _IOWR('i', 36, struct ifconf) /* get ifnet list */ +/* OSIOCGIFNETMASK _IOWR('i', 21, struct ifreq) 4.3BSD */ +#define SIOCGIFNETMASK _IOWR('i', 37, struct ifreq) /* get net addr mask */ +#define SIOCSIFNETMASK _IOW('i', 22, struct ifreq) /* set net addr mask */ +#define SIOCGIFMETRIC _IOWR('i', 23, struct ifreq) /* get IF metric */ +#define SIOCSIFMETRIC _IOW('i', 24, struct ifreq) /* set IF metric */ +#define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */ +#define OSIOCAIFADDR _IOW('i', 26, struct oifaliasreq) /* FreeBSD 9.x */ +/* SIOCALIFADDR _IOW('i', 27, struct if_laddrreq) KAME */ +/* SIOCGLIFADDR _IOWR('i', 28, struct if_laddrreq) KAME */ +/* SIOCDLIFADDR _IOW('i', 29, struct if_laddrreq) KAME */ +#define SIOCSIFCAP _IOW('i', 30, struct ifreq) /* set IF features */ +#define SIOCGIFCAP _IOWR('i', 31, struct ifreq) /* get IF features */ +#define SIOCGIFINDEX _IOWR('i', 32, struct ifreq) /* get IF index */ +#define SIOCGIFMAC _IOWR('i', 38, struct ifreq) /* get IF MAC label */ +#define SIOCSIFMAC _IOW('i', 39, struct ifreq) /* set IF MAC label */ +#define SIOCSIFNAME _IOW('i', 40, struct ifreq) /* set IF name */ +#define SIOCSIFDESCR _IOW('i', 41, struct ifreq) /* set ifnet descr */ +#define SIOCGIFDESCR _IOWR('i', 42, struct ifreq) /* get ifnet descr */ +#define SIOCAIFADDR _IOW('i', 43, struct ifaliasreq)/* add/chg IF alias */ + +#define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */ +#define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */ +#define SIOCGIFMTU _IOWR('i', 51, struct ifreq) /* get IF mtu */ +#define SIOCSIFMTU _IOW('i', 52, struct ifreq) /* set IF mtu */ +#define SIOCGIFPHYS _IOWR('i', 53, struct ifreq) /* get IF wire */ +#define SIOCSIFPHYS _IOW('i', 54, struct ifreq) /* set IF wire */ +#define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */ +#define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */ + +#define SIOCSIFGENERIC _IOW('i', 57, struct ifreq) /* generic IF set op */ +#define SIOCGIFGENERIC _IOWR('i', 58, struct ifreq) /* generic IF get op */ + +#define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */ +#define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) /* set linklevel addr */ +#define SIOCGI2C _IOWR('i', 61, struct ifreq) /* get I2C data */ +#define SIOCGHWADDR _IOWR('i', 62, struct ifreq) /* get hardware lladdr */ + +#define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif address */ +#define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) /* get gif psrc addr */ +#define SIOCGIFPDSTADDR _IOWR('i', 72, struct ifreq) /* get gif pdst addr */ +#define SIOCDIFPHYADDR _IOW('i', 73, struct ifreq) /* delete gif addrs */ +/* SIOCSLIFPHYADDR _IOW('i', 74, struct if_laddrreq) KAME */ +/* SIOCGLIFPHYADDR _IOWR('i', 75, struct if_laddrreq) KAME */ + +#define SIOCGPRIVATE_0 _IOWR('i', 80, struct ifreq) /* device private 0 */ +#define SIOCGPRIVATE_1 _IOWR('i', 81, struct ifreq) /* device private 1 */ + +#define SIOCSIFVNET _IOWR('i', 90, struct ifreq) /* move IF jail/vnet */ +#define SIOCSIFRVNET _IOWR('i', 91, struct ifreq) /* reclaim vnet IF */ + +#define SIOCGIFFIB _IOWR('i', 92, struct ifreq) /* get IF fib */ +#define SIOCSIFFIB _IOW('i', 93, struct ifreq) /* set IF fib */ + +#define SIOCGTUNFIB _IOWR('i', 94, struct ifreq) /* get tunnel fib */ +#define SIOCSTUNFIB _IOW('i', 95, struct ifreq) /* set tunnel fib */ + +#define SIOCSDRVSPEC _IOW('i', 123, struct ifdrv) /* set driver-specific + parameters */ +#define SIOCGDRVSPEC _IOWR('i', 123, struct ifdrv) /* get driver-specific + parameters */ + +#define SIOCIFCREATE _IOWR('i', 122, struct ifreq) /* create clone if */ +#define SIOCIFCREATE2 _IOWR('i', 124, struct ifreq) /* create clone if */ +#define SIOCIFDESTROY _IOW('i', 121, struct ifreq) /* destroy clone if */ +#define SIOCIFGCLONERS _IOWR('i', 120, struct if_clonereq) /* get cloners */ + +#define SIOCAIFGROUP _IOW('i', 135, struct ifgroupreq) /* add an ifgroup */ +#define SIOCGIFGROUP _IOWR('i', 136, struct ifgroupreq) /* get ifgroups */ +#define SIOCDIFGROUP _IOW('i', 137, struct ifgroupreq) /* delete ifgroup */ +#define SIOCGIFGMEMB _IOWR('i', 138, struct ifgroupreq) /* get members */ +#define SIOCGIFXMEDIA _IOWR('i', 139, struct ifmediareq) /* get net xmedia */ + +#define SIOCGIFRSSKEY _IOWR('i', 150, struct ifrsskey)/* get RSS key */ +#define SIOCGIFRSSHASH _IOWR('i', 151, struct ifrsshash)/* get the current RSS + type/func settings */ + +#endif /* !_SYS_SOCKIO_H_ */ diff --git a/nx/external/bsd/include/sys/sysctl.h b/nx/external/bsd/include/sys/sysctl.h new file mode 100644 index 00000000..929c1632 --- /dev/null +++ b/nx/external/bsd/include/sys/sysctl.h @@ -0,0 +1,320 @@ +// TuxSH: removed definitions under _KERNEL ifdef blocks, modify the prototype of some functions, some other cleanup, etc. +// Note: I didn't provide +#ifndef __BSD_VISIBLE +#define __BSD_VISIBLE 1 +#endif + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * 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. 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$ + */ + +#ifndef _SYS_SYSCTL_H_ +#define _SYS_SYSCTL_H_ + +//#include + +//struct thread; + +/* + * 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 24 /* 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(8) 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_S64 4 /* name describes a signed 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 CTLTYPE_U64 9 /* name describes an unsigned 64-bit number */ +#define CTLTYPE_U8 0xa /* name describes an unsigned 8-bit number */ +#define CTLTYPE_U16 0xb /* name describes an unsigned 16-bit number */ +#define CTLTYPE_S8 0xc /* name describes a signed 8-bit number */ +#define CTLTYPE_S16 0xd /* name describes a signed 16-bit number */ +#define CTLTYPE_S32 0xe /* name describes a signed 32-bit number */ +#define CTLTYPE_U32 0xf /* name describes an unsigned 32-bit number */ + +#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_DORMANT 0x20000000 /* This sysctl is not active yet */ +#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 */ +#define CTLFLAG_SKIP 0x01000000 /* Skip this sysctl when listing */ +#define CTLMASK_SECURE 0x00F00000 /* Secure level */ +#define CTLFLAG_TUN 0x00080000 /* Default value is loaded from getenv() */ +#define CTLFLAG_RDTUN (CTLFLAG_RD|CTLFLAG_TUN) +#define CTLFLAG_RWTUN (CTLFLAG_RW|CTLFLAG_TUN) +#define CTLFLAG_MPSAFE 0x00040000 /* Handler is MP safe */ +#define CTLFLAG_VNET 0x00020000 /* Prisons with vnet can fiddle */ +#define CTLFLAG_DYING 0x00010000 /* Oid is being removed */ +#define CTLFLAG_CAPRD 0x00008000 /* Can be read in capability mode */ +#define CTLFLAG_CAPWR 0x00004000 /* Can be written in capability mode */ +#define CTLFLAG_STATS 0x00002000 /* Statistics, not a tuneable */ +#define CTLFLAG_NOFETCH 0x00001000 /* Don't fetch tunable from getenv() */ +#define CTLFLAG_CAPRW (CTLFLAG_CAPRD|CTLFLAG_CAPWR) + +/* + * Secure level. Note that CTLFLAG_SECURE == CTLFLAG_SECURE1. + * + * Secure when the securelevel is raised to at least N. + */ +#define CTLSHIFT_SECURE 20 +#define CTLFLAG_SECURE1 (CTLFLAG_SECURE | (0 << CTLSHIFT_SECURE)) +#define CTLFLAG_SECURE2 (CTLFLAG_SECURE | (1 << CTLSHIFT_SECURE)) +#define CTLFLAG_SECURE3 (CTLFLAG_SECURE | (2 << CTLSHIFT_SECURE)) + +/* + * 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) + +/* + * The starting number for dynamically-assigned entries. WARNING! + * ALL static sysctl entries should have numbers LESS than this! + */ +#define CTL_AUTO_START 0x100 + +/* + * 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 /* filesystem, 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 */ + +/* + * 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: kernel 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 /* struct cdev *: 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_IOV_MAX 35 /* int: value of UIO_MAXIOV */ +#define KERN_HOSTUUID 36 /* string: host UUID identifier */ +#define KERN_ARND 37 /* int: from arc4rand() */ +#define KERN_MAXPHYS 38 /* int: MAXPHYS value */ +/* + * 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 */ +#define KERN_PROC_PROC 8 /* only return procs */ +#define KERN_PROC_SV_NAME 9 /* get syscall vector name */ +#define KERN_PROC_RGID 10 /* by real group id */ +#define KERN_PROC_GID 11 /* by effective group id */ +#define KERN_PROC_PATHNAME 12 /* path to executable */ +#define KERN_PROC_OVMMAP 13 /* Old VM map entries for process */ +#define KERN_PROC_OFILEDESC 14 /* Old file descriptors for process */ +#define KERN_PROC_KSTACK 15 /* Kernel stacks for process */ +#define KERN_PROC_INC_THREAD 0x10 /* + * modifier for pid, pgrp, tty, + * uid, ruid, gid, rgid and proc + * This effectively uses 16-31 + */ +#define KERN_PROC_VMMAP 32 /* VM map entries for process */ +#define KERN_PROC_FILEDESC 33 /* File descriptors for process */ +#define KERN_PROC_GROUPS 34 /* process groups */ +#define KERN_PROC_ENV 35 /* get environment */ +#define KERN_PROC_AUXV 36 /* get ELF auxiliary vector */ +#define KERN_PROC_RLIMIT 37 /* process resource limits */ +#define KERN_PROC_PS_STRINGS 38 /* get ps_strings location */ +#define KERN_PROC_UMASK 39 /* process umask */ +#define KERN_PROC_OSREL 40 /* osreldate for process binary */ +#define KERN_PROC_SIGTRAMP 41 /* signal trampoline location */ +#define KERN_PROC_CWD 42 /* process current working directory */ +#define KERN_PROC_NFDS 43 /* number of open file descriptors */ + +/* + * 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? */ + +/* + * 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_REALMEM 12 /* int: 'real' memory */ + +/* + * 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 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 + +#include + +// Modified: added arg names, etc + +__BEGIN_DECLS +int sysctl(const int *name, unsigned int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen); +int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, const void *newp, size_t newlen); +int sysctlnametomib(const char *name, int *mibp, size_t *sizep); +__END_DECLS + +#endif /* !_SYS_SYSCTL_H_ */ diff --git a/nx/include/switch.h b/nx/include/switch.h index 34ccb71a..4de36478 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -14,6 +14,9 @@ extern "C" { #include "switch/nro.h" +#include "switch/arm/tls.h" +#include "switch/arm/cache.h" + #include "switch/kernel/svc.h" #include "switch/kernel/tmem.h" #include "switch/kernel/shmem.h" @@ -25,18 +28,16 @@ extern "C" { #include "switch/kernel/detect.h" #include "switch/kernel/random.h" #include "switch/kernel/jit.h" - -#include "switch/arm/tls.h" -#include "switch/arm/cache.h" -#include "switch/ipc.h" +#include "switch/kernel/ipc.h" #include "switch/services/sm.h" #include "switch/services/fs.h" #include "switch/services/acc.h" #include "switch/services/apm.h" #include "switch/services/applet.h" +#include "switch/services/audin.h" #include "switch/services/audout.h" -#include "switch/services/bsd.h" +//#include "switch/services/bsd.h" Use switch/runtime/devices/socket.h instead #include "switch/services/fatal.h" #include "switch/services/time.h" #include "switch/services/usb.h" @@ -71,6 +72,7 @@ extern "C" { #include "switch/runtime/devices/usb_comms.h" #include "switch/runtime/devices/fs_dev.h" #include "switch/runtime/devices/romfs_dev.h" +#include "switch/runtime/devices/socket.h" #ifdef __cplusplus } diff --git a/nx/include/switch/arm/atomics.h b/nx/include/switch/arm/atomics.h new file mode 100644 index 00000000..c6714234 --- /dev/null +++ b/nx/include/switch/arm/atomics.h @@ -0,0 +1,17 @@ +#include "../types.h" + +static inline u32 atomicIncrement32(u32* p) { + return __atomic_fetch_add(p, 1, __ATOMIC_SEQ_CST); +} + +static inline u32 atomicDecrement32(u32* p) { + return __atomic_sub_fetch(p, 1, __ATOMIC_SEQ_CST); +} + +static inline u64 atomicIncrement64(u64* p) { + return __atomic_fetch_add(p, 1, __ATOMIC_SEQ_CST); +} + +static inline u64 atomicDecrement64(u64* p) { + return __atomic_sub_fetch(p, 1, __ATOMIC_SEQ_CST); +} diff --git a/nx/include/switch/audio/audio.h b/nx/include/switch/audio/audio.h new file mode 100644 index 00000000..cbea7cb9 --- /dev/null +++ b/nx/include/switch/audio/audio.h @@ -0,0 +1,19 @@ +/** + * @file audio.h + * @brief Global audio service. + * @author hexkyz + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" + +typedef enum { + PcmFormat_Invalid = 0, + PcmFormat_Int8 = 1, + PcmFormat_Int16 = 2, + PcmFormat_Int24 = 3, + PcmFormat_Int32 = 4, + PcmFormat_Float = 5, + PcmFormat_Adpcm = 6, +} PcmFormat; diff --git a/nx/include/switch/ipc.h b/nx/include/switch/kernel/ipc.h similarity index 61% rename from nx/include/switch/ipc.h rename to nx/include/switch/kernel/ipc.h index 9d52dcea..a243d300 100644 --- a/nx/include/switch/ipc.h +++ b/nx/include/switch/kernel/ipc.h @@ -5,39 +5,59 @@ * @copyright libnx Authors */ #pragma once -#include "result.h" -#include "arm/tls.h" -#include "kernel/svc.h" +#include "../result.h" +#include "../arm/tls.h" +#include "../kernel/svc.h" /// IPC input header magic #define SFCI_MAGIC 0x49434653 /// IPC output header magic #define SFCO_MAGIC 0x4f434653 -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +/// IPC invalid object ID +#define IPC_INVALID_OBJECT_ID UINT32_MAX ///@name IPC request building ///@{ /// IPC command (request) structure. +#define IPC_MAX_BUFFERS 8 +#define IPC_MAX_OBJECTS 8 + +typedef enum { + BufferType_Normal=0, ///< Regular buffer. + BufferType_Type1=1, ///< Allows ProcessMemory and shared TransferMemory. + BufferType_Invalid=2, + BufferType_Type3=3 ///< Same as Type1 except remote process is not allowed to use device-mapping. +} BufferType; + +typedef enum { + BufferDirection_Send=0, + BufferDirection_Recv=1, + BufferDirection_Exch=2, +} BufferDirection; + typedef struct { size_t NumSend; // A size_t NumRecv; // B - size_t NumTransfer; // W - const void* Buffers[4]; - size_t BufferSizes[4]; - u8 Flags[4]; + size_t NumExch; // W + const void* Buffers[IPC_MAX_BUFFERS]; + size_t BufferSizes[IPC_MAX_BUFFERS]; + BufferType BufferTypes[IPC_MAX_BUFFERS]; size_t NumStaticIn; // X size_t NumStaticOut; // C - const void* Statics[4]; - size_t StaticSizes[4]; - u8 Indices[4]; + const void* Statics[IPC_MAX_BUFFERS]; + size_t StaticSizes[IPC_MAX_BUFFERS]; + u8 StaticIndices[IPC_MAX_BUFFERS]; bool SendPid; size_t NumHandlesCopy; size_t NumHandlesMove; - Handle Handles[8]; + Handle Handles[IPC_MAX_OBJECTS]; + + size_t NumObjectIds; + u32 ObjectIds[IPC_MAX_OBJECTS]; } IpcCommand; /** @@ -45,16 +65,7 @@ typedef struct { * @param cmd IPC command structure. */ static inline void ipcInitialize(IpcCommand* cmd) { - cmd->NumSend = 0; - cmd->NumRecv = 0; - cmd->NumTransfer = 0; - - cmd->NumStaticIn = 0; - cmd->NumStaticOut = 0; - - cmd->SendPid = false; - cmd->NumHandlesCopy = 0; - cmd->NumHandlesMove = 0; + *cmd = (IpcCommand){0}; } /// IPC buffer descriptor. @@ -81,13 +92,13 @@ typedef struct { * @param cmd IPC command structure. * @param buffer Address of the buffer. * @param size Size of the buffer. - * @param flags Flags to attach to the buffer. + * @param type Buffer type. */ -static inline void ipcAddSendBuffer(IpcCommand* cmd, const void* buffer, size_t size, u8 flags) { +static inline void ipcAddSendBuffer(IpcCommand* cmd, const void* buffer, size_t size, BufferType type) { size_t off = cmd->NumSend; cmd->Buffers[off] = buffer; cmd->BufferSizes[off] = size; - cmd->Flags[off] = flags; + cmd->BufferTypes[off] = type; cmd->NumSend++; } @@ -96,29 +107,29 @@ static inline void ipcAddSendBuffer(IpcCommand* cmd, const void* buffer, size_t * @param cmd IPC command structure. * @param buffer Address of the buffer. * @param size Size of the buffer. - * @param flags Flags to attach to the buffer. + * @param type Buffer type. */ -static inline void ipcAddRecvBuffer(IpcCommand* cmd, void* buffer, size_t size, u8 flags) { +static inline void ipcAddRecvBuffer(IpcCommand* cmd, void* buffer, size_t size, BufferType type) { size_t off = cmd->NumSend + cmd->NumRecv; cmd->Buffers[off] = buffer; cmd->BufferSizes[off] = size; - cmd->Flags[off] = flags; + cmd->BufferTypes[off] = type; cmd->NumRecv++; } /** - * @brief Adds a transfer-buffer to an IPC command structure. + * @brief Adds an exchange-buffer to an IPC command structure. * @param cmd IPC command structure. * @param buffer Address of the buffer. * @param size Size of the buffer. - * @param flags Flags to attach to the buffer. + * @param type Buffer type. */ -static inline void ipcAddTransferBuffer(IpcCommand* cmd, void* buffer, size_t size, u8 flags) { - size_t off = cmd->NumSend + cmd->NumRecv + cmd->NumTransfer; +static inline void ipcAddExchBuffer(IpcCommand* cmd, void* buffer, size_t size, BufferType type) { + size_t off = cmd->NumSend + cmd->NumRecv + cmd->NumExch; cmd->Buffers[off] = buffer; cmd->BufferSizes[off] = size; - cmd->Flags[off] = flags; - cmd->NumTransfer++; + cmd->BufferTypes[off] = type; + cmd->NumExch++; } /** @@ -126,13 +137,13 @@ static inline void ipcAddTransferBuffer(IpcCommand* cmd, void* buffer, size_t si * @param cmd IPC command structure. * @param buffer Address of the buffer. * @param size Size of the buffer. - * @param flags Flags to attach to the buffer. + * @param index Index of buffer. */ static inline void ipcAddSendStatic(IpcCommand* cmd, const void* buffer, size_t size, u8 index) { size_t off = cmd->NumStaticIn; cmd->Statics[off] = buffer; cmd->StaticSizes[off] = size; - cmd->Indices[off] = index; + cmd->StaticIndices[off] = index; cmd->NumStaticIn++; } @@ -141,13 +152,13 @@ static inline void ipcAddSendStatic(IpcCommand* cmd, const void* buffer, size_t * @param cmd IPC command structure. * @param buffer Address of the buffer. * @param size Size of the buffer. - * @param flags Flags to attach to the buffer. + * @param index Index of buffer. */ static inline void ipcAddRecvStatic(IpcCommand* cmd, void* buffer, size_t size, u8 index) { size_t off = cmd->NumStaticIn + cmd->NumStaticOut; cmd->Statics[off] = buffer; cmd->StaticSizes[off] = size; - cmd->Indices[off] = index; + cmd->StaticIndices[off] = index; cmd->NumStaticOut++; } @@ -188,7 +199,7 @@ static inline void ipcSendHandleMove(IpcCommand* cmd, Handle h) { static inline void* ipcPrepareHeader(IpcCommand* cmd, size_t sizeof_raw) { u32* buf = (u32*)armGetTls(); size_t i; - *buf++ = 4 | (cmd->NumStaticIn << 16) | (cmd->NumSend << 20) | (cmd->NumRecv << 24) | (cmd->NumTransfer << 28); + *buf++ = 4 | (cmd->NumStaticIn << 16) | (cmd->NumSend << 20) | (cmd->NumRecv << 24) | (cmd->NumExch << 28); u32* fill_in_size_later = buf; @@ -218,17 +229,17 @@ static inline void* ipcPrepareHeader(IpcCommand* cmd, size_t sizeof_raw) { uintptr_t ptr = (uintptr_t) cmd->Statics[i]; desc->Addr = ptr; - desc->Packed = cmd->Indices[i] | (cmd->StaticSizes[i] << 16) | + desc->Packed = cmd->StaticIndices[i] | (cmd->StaticSizes[i] << 16) | (((ptr >> 32) & 15) << 12) | (((ptr >> 36) & 15) << 6); } - for (i=0; i<(cmd->NumSend + cmd->NumRecv + cmd->NumTransfer); i++, buf+=3) { + for (i=0; i<(cmd->NumSend + cmd->NumRecv + cmd->NumExch); i++, buf+=3) { IpcBufferDescriptor* desc = (IpcBufferDescriptor*) buf; desc->Size = cmd->BufferSizes[i]; uintptr_t ptr = (uintptr_t) cmd->Buffers[i]; desc->Addr = ptr; - desc->Packed = cmd->Flags[i] | + desc->Packed = cmd->BufferTypes[i] | (((ptr >> 32) & 15) << 28) | ((ptr >> 36) << 2); } @@ -281,18 +292,30 @@ static inline Result ipcDispatch(Handle session) { /// IPC parsed command (response) structure. typedef struct { - bool HasPid; ///< true if the 'Pid' field is filled out. - u64 Pid; ///< PID included in the response (only if HasPid is true) + bool HasPid; ///< true if the 'Pid' field is filled out. + u64 Pid; ///< PID included in the response (only if HasPid is true) - size_t NumHandles; ///< Number of handles in the response. - Handle Handles[8]; ///< Handles. + size_t NumHandles; ///< Number of handles copied. + Handle Handles[IPC_MAX_OBJECTS]; ///< Handles. + bool WasHandleCopied[IPC_MAX_OBJECTS]; ///< true if the handle was moved, false if it was copied. - size_t NumBuffers; ///< Number of buffers in the response. - void* Buffers[4]; ///< Pointers to the buffers. - size_t BufferSizes[4]; ///< Sizes of the buffers. + u32 ThisObjectId; ///< Object ID to call the command on (for domain messages). + size_t NumObjectIds; ///< Number of object IDs (for domain messages). + u32 ObjectIds[IPC_MAX_OBJECTS]; ///< Object IDs (for domain messages). - void* Raw; ///< Pointer to the raw embedded data structure in the response. - size_t RawSize; ///< Size of the raw embedded data. + size_t NumBuffers; ///< Number of buffers in the response. + void* Buffers[IPC_MAX_BUFFERS]; ///< Pointers to the buffers. + size_t BufferSizes[IPC_MAX_BUFFERS]; ///< Sizes of the buffers. + BufferType BufferTypes[IPC_MAX_BUFFERS]; ///< Types of the buffers. + BufferDirection BufferDirections[IPC_MAX_BUFFERS]; ///< Direction of each buffer. + + size_t NumStatics; ///< Number of statics in the response. + void* Statics[IPC_MAX_BUFFERS]; ///< Pointers to the statics. + size_t StaticSizes[IPC_MAX_BUFFERS]; ///< Sizes of the statics. + u8 StaticIndices[IPC_MAX_BUFFERS]; ///< Indices of the statics. + + void* Raw; ///< Pointer to the raw embedded data structure in the response. + size_t RawSize; ///< Size of the raw embedded data. } IpcParsedCommand; /** @@ -319,26 +342,50 @@ static inline Result ipcParse(IpcParsedCommand* r) { r->Pid |= ((u64)(*buf++)) << 32; } - size_t num_handles = ((ctrl2 >> 1) & 15) + ((ctrl2 >> 5) & 15); - buf += num_handles; + size_t num_handles_copy = ((ctrl2 >> 1) & 15); + size_t num_handles_move = ((ctrl2 >> 5) & 15); - if (num_handles > 8) - num_handles = 8; + size_t num_handles = num_handles_copy + num_handles_move; + + if (num_handles > IPC_MAX_OBJECTS) + num_handles = IPC_MAX_OBJECTS; for (i=0; iHandles[i] = *(buf-num_handles+i); + r->WasHandleCopied[i] = (i < num_handles_copy); + } r->NumHandles = num_handles; } size_t num_statics = (ctrl0 >> 16) & 15; - buf += num_statics*2; + u32* buf_after_statics = buf + num_statics*2; - size_t num_bufs = ((ctrl0 >> 20) & 15) + ((ctrl0 >> 24) & 15) + (((ctrl0 >> 28) & 15)); + if (num_statics > IPC_MAX_BUFFERS) + num_statics = IPC_MAX_BUFFERS; + + for (i=0; iPacked; + + r->Statics[i] = (void*) (desc->Addr | ((packed & 15) << 32) | (((packed >> 6) & 15) << 36)); + r->StaticSizes[i] = packed >> 16; + r->StaticIndices[i] = packed & 63; + } + + r->NumStatics = num_statics; + buf = buf_after_statics; + + size_t num_bufs_send = (ctrl0 >> 20) & 15; + size_t num_bufs_recv = (ctrl0 >> 24) & 15; + size_t num_bufs_exch = (ctrl0 >> 28) & 15; + + size_t num_bufs = num_bufs_send + num_bufs_recv + num_bufs_exch; r->Raw = (void*)(((uintptr_t)(buf + num_bufs*3) + 15) &~ 15); - if (num_bufs > 4) - num_bufs = 4; + if (num_bufs > IPC_MAX_BUFFERS) + num_bufs = IPC_MAX_BUFFERS; for (i=0; iBuffers[i] = (void*) (desc->Addr | ((packed >> 28) << 32) | (((packed >> 2) & 15) << 36)); r->BufferSizes[i] = desc->Size; - // todo: Do we care about buffer type? + r->BufferTypes[i] = packed & 3; + + if (i < num_bufs_send) + r->BufferDirections[i] = BufferDirection_Send; + else if (i < (num_bufs_send + num_bufs_recv)) + r->BufferDirections[i] = BufferDirection_Recv; + else + r->BufferDirections[i] = BufferDirection_Exch; } r->NumBuffers = num_bufs; @@ -424,7 +478,7 @@ static inline Result ipcConvertSessionToDomain(Handle session, u32* object_id_ou u64 magic; u64 result; u32 object_id; - } *raw = (struct ipcConvertSessionToDomainResponse*) r.Raw; + } *raw = (struct ipcConvertSessionToDomainResponse*)r.Raw; rc = raw->result; @@ -436,13 +490,22 @@ static inline Result ipcConvertSessionToDomain(Handle session, u32* object_id_ou return rc; } +/** + * @brief Adds an object ID to be sent through an IPC domain command structure. + * @param cmd IPC domain command structure. + * @param object_id Object ID to send. + */ +static inline void ipcSendObjectId(IpcCommand* cmd, u32 object_id) { + cmd->ObjectIds[cmd->NumObjectIds++] = object_id; +} + /// IPC domain message header. typedef struct { u8 Type; - u8 Pad0; + u8 NumObjectIds; u16 Length; - u32 ObjectId; - u32 Pad1[2]; + u32 ThisObjectId; + u32 Pad[2]; } DomainMessageHeader; /** @@ -452,17 +515,20 @@ typedef struct { * @oaram object_id Domain object ID. * @return Pointer to the raw embedded data structure in the request, ready to be filled out. */ -static inline void* ipcPrepareHeaderForDomain(IpcCommand* cmd, size_t sizeof_raw, size_t object_id) { +static inline void* ipcPrepareHeaderForDomain(IpcCommand* cmd, size_t sizeof_raw, u32 object_id) { void* raw = ipcPrepareHeader(cmd, sizeof_raw + sizeof(DomainMessageHeader)); DomainMessageHeader* hdr = (DomainMessageHeader*) raw; + u32 *object_ids = (u32*)(((uintptr_t) raw) + sizeof(DomainMessageHeader) + sizeof_raw); hdr->Type = 1; + hdr->NumObjectIds = (u8)cmd->NumObjectIds; hdr->Length = sizeof_raw; - hdr->ObjectId = object_id; + hdr->ThisObjectId = object_id; + hdr->Pad[0] = hdr->Pad[1] = 0; - hdr->Pad0 = hdr->Pad1[0] = hdr->Pad1[1] = 0; - - return (void*)(((uintptr_t) raw) + sizeof(DomainMessageHeader)); + for(size_t i = 0; i < cmd->NumObjectIds; i++) + object_ids[i] = cmd->ObjectIds[i]; + return (void*)(((uintptr_t) raw) + sizeof(DomainMessageHeader)); } /** @@ -472,12 +538,43 @@ static inline void* ipcPrepareHeaderForDomain(IpcCommand* cmd, size_t sizeof_raw */ static inline Result ipcParseForDomain(IpcParsedCommand* r) { Result rc = ipcParse(r); + DomainMessageHeader* hdr; + u32 *object_ids; + if(R_FAILED(rc)) + return rc; - if (R_SUCCEEDED(rc)) { - r->Raw = (void*)(((uintptr_t) r->Raw) + sizeof(DomainMessageHeader)); - } + hdr = (DomainMessageHeader*) r->Raw; + object_ids = (u32*)(((uintptr_t) hdr) + sizeof(DomainMessageHeader) + hdr->Length); + r->Raw = (void*)(((uintptr_t) r->Raw) + sizeof(DomainMessageHeader)); + + r->ThisObjectId = hdr->ThisObjectId; + r->NumObjectIds = hdr->NumObjectIds > 8 ? 8 : hdr->NumObjectIds; + for(size_t i = 0; i < r->NumObjectIds; i++) + r->ObjectIds[i] = object_ids[i]; return rc; } +/** + * @brief Closes a domain object by ID. + * @param session IPC session handle. + * @param object_id ID of the object to close. + * @return Result code. + */ +static inline Result ipcCloseObjectById(Handle session, u32 object_id) { + IpcCommand c; + DomainMessageHeader* hdr; + + ipcInitialize(&c); + hdr = (DomainMessageHeader*)ipcPrepareHeader(&c, sizeof(DomainMessageHeader)); + + hdr->Type = 2; + hdr->NumObjectIds = 0; + hdr->Length = 0; + hdr->ThisObjectId = object_id; + hdr->Pad[0] = hdr->Pad[1] = 0; + + return ipcDispatch(session); // this command has no associated response +} + ///@} diff --git a/nx/include/switch/kernel/mutex.h b/nx/include/switch/kernel/mutex.h index bdad14af..fe6ca3a3 100644 --- a/nx/include/switch/kernel/mutex.h +++ b/nx/include/switch/kernel/mutex.h @@ -6,7 +6,7 @@ */ #pragma once #include -#include "../types.h" // not needed in this file, still including it +#include "../types.h" /// Mutex datatype, defined in newlib. typedef _LOCK_T Mutex; @@ -29,6 +29,13 @@ static inline void mutexInit(Mutex* m) */ void mutexLock(Mutex* m); +/** + * @brief Attempts to lock a mutex without waiting. + * @param m Mutex object. + * @return 1 if the mutex has been acquired successfully, and 0 on contention. + */ +bool mutexTryLock(Mutex* m); + /** * @brief Unlocks a mutex. * @param m Mutex object. @@ -53,6 +60,13 @@ static inline void rmutexInit(RMutex* m) */ void rmutexLock(RMutex* m); +/** + * @brief Attempts to lock a recursive mutex without waiting. + * @param m Recursive mutex object. + * @return 1 if the mutex has been acquired successfully, and 0 on contention. + */ +bool rmutexTryLock(RMutex* m); + /** * @brief Unlocks a recursive mutex. * @param m Recursive mutex object. diff --git a/nx/include/switch/kernel/tmem.h b/nx/include/switch/kernel/tmem.h index 24e68586..4093812a 100644 --- a/nx/include/switch/kernel/tmem.h +++ b/nx/include/switch/kernel/tmem.h @@ -7,6 +7,7 @@ */ #pragma once #include "../types.h" +#include "../kernel/svc.h" /// Transfer memory information structure. typedef struct { diff --git a/nx/include/switch/result.h b/nx/include/switch/result.h index 3299aa6e..1f8f43fd 100644 --- a/nx/include/switch/result.h +++ b/nx/include/switch/result.h @@ -21,10 +21,16 @@ /// Module values enum { + Module_Kernel=1, Module_Libnx=345, Module_LibnxNvidia=348, }; +/// Kernel error codes +enum { + KernelError_Timeout=117, +}; + /// libnx error codes enum { LibnxError_BadReloc=1, @@ -65,6 +71,7 @@ enum { LibnxError_WeirdKernel, LibnxError_IncompatSysVer, LibnxError_InitFail_Time, + LibnxError_TooManyDevOpTabs, }; /// libnx nvidia error codes diff --git a/nx/include/switch/runtime/devices/romfs_dev.h b/nx/include/switch/runtime/devices/romfs_dev.h index f23ab5ab..e6ce78be 100644 --- a/nx/include/switch/runtime/devices/romfs_dev.h +++ b/nx/include/switch/runtime/devices/romfs_dev.h @@ -11,8 +11,6 @@ #include "../../types.h" #include "../../services/fs.h" -/// WARNING: This is not ready to be used. - /// RomFS header. typedef struct { diff --git a/nx/include/switch/runtime/devices/socket.h b/nx/include/switch/runtime/devices/socket.h new file mode 100644 index 00000000..155eea6f --- /dev/null +++ b/nx/include/switch/runtime/devices/socket.h @@ -0,0 +1,39 @@ +#pragma once +#include "../../types.h" + +/// Configuration structure for socketInitalize +typedef struct { + u32 bsdsockets_version; ///< Observed 1 on 2.0 LibAppletWeb, 2 on 3.0. + + u32 tcp_tx_buf_size; ///< Size of the TCP transfer (send) buffer (initial or fixed). + u32 tcp_rx_buf_size; ///< Size of the TCP recieve buffer (initial or fixed). + u32 tcp_tx_buf_max_size; ///< Maximum size of the TCP transfer (send) buffer. If it is 0, the size of the buffer is fixed to its initial value. + u32 tcp_rx_buf_max_size; ///< Maximum size of the TCP receive buffer. If it is 0, the size of the buffer is fixed to its initial value. + + u32 udp_tx_buf_size; ///< Size of the UDP transfer (send) buffer (typically 0x2400 bytes). + u32 udp_rx_buf_size; ///< Size of the UDP receive buffer (typically 0xA500 bytes). + + u32 sb_efficiency; ///< Number of buffers for each socket (standard values range from 1 to 8). + + size_t serialized_out_addrinfos_max_size; ///< For getaddrinfo. + size_t serialized_out_hostent_max_size; ///< For gethostbyname/gethostbyaddr. + bool bypass_nsd; ///< For name gethostbyname/getaddrinfo: bypass the Name Server Daemon. + int dns_timeout; ///< For DNS requests: timeout or 0. +} SocketInitConfig; + +/// Fetch the default configuration for the socket driver. +const SocketInitConfig *socketGetDefaultInitConfig(void); +/// Initalize the socket driver. +Result socketInitialize(const SocketInitConfig *config); +/// Fetch the last bsd:u/s Switch result code (thread-local). +Result socketGetLastBsdResult(void); +/// Fetch the last sfdnsres Switch result code (thread-local). +Result socketGetLastSfdnsresResult(void); +/// Deinitialize the socket driver. +void socketExit(void); + +/// Initalize the socket driver using the default configuration. +static inline Result socketInitializeDefault(void) { + return socketInitialize(socketGetDefaultInitConfig()); +} + diff --git a/nx/include/switch/services/audin.h b/nx/include/switch/services/audin.h new file mode 100644 index 00000000..58153041 --- /dev/null +++ b/nx/include/switch/services/audin.h @@ -0,0 +1,60 @@ +/** + * @file audin.h + * @brief Audio input service. + * @author hexkyz + * @copyright libnx Authors + */ +#pragma once + +#include "../audio/audio.h" + +typedef enum { + AudioInState_Started = 0, + AudioInState_Stopped = 1, +} AudioInState; + +/// Audio input buffer format +typedef struct AudioInBuffer AudioInBuffer; + +struct AudioInBuffer +{ + AudioInBuffer* next; ///< Next buffer. (Unused) + void* buffer; ///< Sample buffer (aligned to 0x1000 bytes). + u64 buffer_size; ///< Sample buffer size (aligned to 0x1000 bytes). + u64 data_size; ///< Size of data inside the buffer. + u64 data_offset; ///< Offset of data inside the buffer. (Unused?) +}; + +Result audinInitialize(void); +void audinExit(void); + +Result audinListAudioIns(char *DeviceNames, u32 *DeviceNamesCount); +Result audinOpenAudioIn(const char *DeviceNameIn, char *DeviceNameOut, u32 SampleRateIn, u32 ChannelCountIn, u32 *SampleRateOut, u32 *ChannelCountOut, PcmFormat *Format, AudioInState *State); +Result audinGetAudioInState(AudioInState *State); +Result audinStartAudioIn(void); +Result audinStopAudioIn(void); +Result audinAppendAudioInBuffer(AudioInBuffer *Buffer); +Result audinGetReleasedAudioInBuffer(AudioInBuffer **Buffer, u32 *ReleasedBuffersCount); +Result audinContainsAudioInBuffer(AudioInBuffer *Buffer, bool *ContainsBuffer); + +/** + * @brief Submits an audio sample data buffer for capturing and waits for it to finish capturing. + * @brief Uses \ref audinAppendAudioInBuffer and \ref audinWaitCaptureFinish internally. + * @param source AudioInBuffer containing the buffer to hold the captured sample data. + * @param released AudioInBuffer to receive the captured buffer after being released. + */ +Result audinCaptureBuffer(AudioInBuffer *source, AudioInBuffer **released); + +/** + * @brief Waits for audio capture to finish. + * @param released AudioInBuffer to receive the first captured buffer after being released. + * @param released_count Pointer to receive the number of captured buffers. + * @param timeout Timeout value, use U64_MAX to wait until all finished. + */ +Result audinWaitCaptureFinish(AudioInBuffer **released, u32* released_count, u64 timeout); + +/// These return the state associated with the currently active audio input device. +u32 audinGetSampleRate(void); ///< Supported sample rate (48000Hz). +u32 audinGetChannelCount(void); ///< Supported channel count (2 channels). +PcmFormat audinGetPcmFormat(void); ///< Supported PCM format (Int16). +AudioInState audinGetDeviceState(void); ///< Initial device state (stopped). diff --git a/nx/include/switch/services/audout.h b/nx/include/switch/services/audout.h index d9e7a62f..fcb11b15 100644 --- a/nx/include/switch/services/audout.h +++ b/nx/include/switch/services/audout.h @@ -6,17 +6,7 @@ */ #pragma once -#include "../types.h" - -typedef enum { - PcmFormat_Invalid = 0, - PcmFormat_INT8 = 1, - PcmFormat_INT16 = 2, - PcmFormat_INT24 = 3, - PcmFormat_INT32 = 4, - PcmFormat_FLOAT = 5, - PcmFormat_ADPCM = 6, -} PcmFormat; +#include "../audio/audio.h" typedef enum { AudioOutState_Started = 0, @@ -28,11 +18,11 @@ typedef struct AudioOutBuffer AudioOutBuffer; struct AudioOutBuffer { - AudioOutBuffer* next; ///< Next buffer. + AudioOutBuffer* next; ///< Next buffer. (Unused) void* buffer; ///< Sample buffer (aligned to 0x1000 bytes). - u64 buffer_size; ///< Sample buffer size. + u64 buffer_size; ///< Sample buffer size (aligned to 0x1000 bytes). u64 data_size; ///< Size of data inside the buffer. - u64 data_offset; ///< Offset of data inside the buffer. + u64 data_offset; ///< Offset of data inside the buffer. (Unused?) }; Result audoutInitialize(void); @@ -44,18 +34,27 @@ Result audoutGetAudioOutState(AudioOutState *State); Result audoutStartAudioOut(void); Result audoutStopAudioOut(void); Result audoutAppendAudioOutBuffer(AudioOutBuffer *Buffer); -Result audoutGetReleasedAudioOutBuffer(AudioOutBuffer *Buffer, u32 *ReleasedBuffersCount); +Result audoutGetReleasedAudioOutBuffer(AudioOutBuffer **Buffer, u32 *ReleasedBuffersCount); Result audoutContainsAudioOutBuffer(AudioOutBuffer *Buffer, bool *ContainsBuffer); /** - * @brief Submits an audio sample data buffer for playing. + * @brief Submits an audio sample data buffer for playing and waits for it to finish playing. + * @brief Uses \ref audoutAppendAudioOutBuffer and \ref audoutWaitPlayFinish internally. * @param source AudioOutBuffer containing the source sample data to be played. - * @param released AudioOutBuffer to receive the last played buffer. + * @param released AudioOutBuffer to receive the played buffer after being released. */ -Result audoutPlayBuffer(AudioOutBuffer *source, AudioOutBuffer *released); +Result audoutPlayBuffer(AudioOutBuffer *source, AudioOutBuffer **released); + +/** + * @brief Waits for audio playback to finish. + * @param released AudioOutBuffer to receive the first played buffer after being released. + * @param released_count Pointer to receive the number of played buffers. + * @param timeout Timeout value, use U64_MAX to wait until all finished. + */ +Result audoutWaitPlayFinish(AudioOutBuffer **released, u32* released_count, u64 timeout); /// These return the state associated with the currently active audio output device. u32 audoutGetSampleRate(void); ///< Supported sample rate (48000Hz). u32 audoutGetChannelCount(void); ///< Supported channel count (2 channels). -PcmFormat audoutGetPcmFormat(void); ///< Supported PCM format (INT16). +PcmFormat audoutGetPcmFormat(void); ///< Supported PCM format (Int16). AudioOutState audoutGetDeviceState(void); ///< Initial device state (stopped). diff --git a/nx/include/switch/services/bsd.h b/nx/include/switch/services/bsd.h index 8191aa6f..e21121d9 100644 --- a/nx/include/switch/services/bsd.h +++ b/nx/include/switch/services/bsd.h @@ -1,11 +1,15 @@ /** * @file bsd.h - * @brief BSD sockets (bsd:u/s) service IPC wrapper. + * @brief BSD sockets (bsd:u/s) service IPC wrapper. Please use socket.c instead. * @author plutoo * @author TuxSH * @copyright libnx Authors */ #pragma once +#include // for socklen_t +#include // for fd_set +#include // for struct pollfd, ndfs_t + #include "../types.h" #include "../kernel/tmem.h" @@ -22,42 +26,52 @@ typedef struct { u32 udp_rx_buf_size; ///< Size of the UDP receive buffer (typically 0xA500 bytes). u32 sb_efficiency; ///< Number of buffers for each socket (standard values range from 1 to 8). -} BsdConfig; +} BsdInitConfig; -struct bsd_sockaddr_in { - u8 sin_len; - u8 sin_family; - u16 sin_port; - u32 sin_addr; - u8 sin_zero[8]; -}; +extern __thread Result g_bsdResult; ///< Last Switch "result", per-thread +extern __thread int g_bsdErrno; ///< Last errno, per-thread -const BsdConfig *bsdGetDefaultConfig(void); -Result bsdInitialize(const BsdConfig *config); +/// Fetch the default configuration for bsdInitialize. +const BsdInitConfig *bsdGetDefaultInitConfig(void); +/// Initialize the BSD service. +Result bsdInitialize(const BsdInitConfig *config); +/// Deinitialize the BSD service. void bsdExit(void); -int bsdGetErrno(void); -int bsdConnect(int sockfd, const void* addr, u32 addrlen); + int bsdSocket(int domain, int type, int protocol); -int bsdBind(int sockfd, const void* addr, u32 addrlen); +/// Like @ref bsdSocket but the newly created socket is immediately shut down. +int bsdSocketExempt(int domain, int type, int protocol); +int bsdOpen(const char *pathname, int flags); +int bsdSelect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); +int bsdPoll(struct pollfd *fds, nfds_t nfds, int timeout); +int bsdSysctl(const int *name, unsigned int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen); +ssize_t bsdRecv(int sockfd, void *buf, size_t len, int flags); +ssize_t bsdRecvFrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); +ssize_t bsdSend(int sockfd, const void* buf, size_t len, int flags); +ssize_t bsdSendTo(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); +int bsdAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +int bsdBind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +int bsdConnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +int bsdGetPeerName(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +int bsdGetSockName(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +int bsdGetSockOpt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); int bsdListen(int sockfd, int backlog); -int bsdSend(int sockfd, const void* buffer, size_t length, int flags); -int bsdSendTo(int sockfd, const void* buffer, size_t length, int flags, const struct bsd_sockaddr_in *dest_addr, size_t dest_len); -int bsdRecv(int sockfd, void* buffer, size_t length, int flags); -int bsdSetSockOpt(int sockfd, int level, int option_name, const void *option_value, size_t option_size); -int bsdWrite(int sockfd, const void* buffer, size_t length); +/// Made non-variadic for convenience. +int bsdIoctl(int fd, int request, void *data); +/// Made non-variadic for convenience. +int bsdFcntl(int fd, int cmd, int flags); +int bsdSetSockOpt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); +int bsdShutdown(int sockfd, int how); +int bsdShutdownAllSockets(int how); +ssize_t bsdWrite(int fd, const void *buf, size_t count); +ssize_t bsdRead(int fd, void *buf, size_t count); +int bsdClose(int fd); +/// Duplicate a socket (bsd:s). +int bsdDuplicateSocket(int sockfd); -static inline Result bsdInitializeDefault(void) -{ - return bsdInitialize(bsdGetDefaultConfig()); +// TODO: Reverse-engineer GetResourceStatistics. Implement sendmmsg/recvmmsg (custom (un)serialization) + +/// Initialize the BSD service using the default configuration. +static inline Result bsdInitializeDefault(void) { + return bsdInitialize(bsdGetDefaultInitConfig()); } - -#define BSD_AF_INET 2 -#define BSD_AF_INET6 10 -#define BSD_IPPROTO_IP 0 -#define BSD_IPPROTO_TCP 6 -#define BSD_IPPROTO_UDP 17 - -#define BSD_SOCK_STREAM 1 -#define BSD_SOCK_DGRAM 2 - -#define BSD_MSG_RECV_ALL 0x40 diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index 2c0edde7..cb53f2be 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -539,6 +539,15 @@ typedef struct HidSharedMemory } HidSharedMemory; static_assert(sizeof(HidSharedMemory) == 0x40000, "Hid Shared Memory structure has incorrect size"); +typedef struct HidVibrationValue +{ + float amp_low; ///< Low Band amplitude. 1.0f: Max amplitude. + float freq_low; ///< Low Band frequency in Hz. + float amp_high; ///< High Band amplitude. 1.0f: Max amplitude. + float freq_high; ///< High Band frequency in Hz. +} HidVibrationValue; +static_assert(sizeof(HidVibrationValue) == 0x10, "Hid VibrationValue structure has incorrect size"); + Result hidInitialize(void); void hidExit(void); void hidReset(void); @@ -571,3 +580,22 @@ u32 hidTouchCount(void); void hidTouchRead(touchPosition *pos, u32 point_id); void hidJoystickRead(JoystickPosition *pos, HidControllerID id, HidControllerJoystick stick); + +/// Use this if you want to use a single joy-con as a dedicated CONTROLLER_PLAYER_*. +/// When used, both joy-cons in a pair should be used with this (CONTROLLER_PLAYER_1 and CONTROLLER_PLAYER_2 for example). +/// id must be CONTROLLER_PLAYER_*. +Result hidSetNpadJoyAssignmentModeSingleByDefault(HidControllerID id); +/// Used automatically during app startup/exit for all controllers. +/// When used, both joy-cons in a pair should be used with this (CONTROLLER_PLAYER_1 and CONTROLLER_PLAYER_2 for example). +/// id must be CONTROLLER_PLAYER_*. +Result hidSetNpadJoyAssignmentModeDual(HidControllerID id); + +Result hidInitializeVibrationDevices(u32 *VibrationDeviceHandles, size_t total_handles, HidControllerID id, HidControllerLayoutType type); + +Result hidSendVibrationValue(u32 *VibrationDeviceHandle, HidVibrationValue *VibrationValue); + +/// Sets whether vibration is allowed, this also affects the config displayed by System Settings. +Result hidPermitVibration(bool flag); + +/// Gets whether vibration is allowed. +Result hidIsVibrationPermitted(bool *flag); diff --git a/nx/include/switch/services/irs.h b/nx/include/switch/services/irs.h index 8c216922..f83ebe00 100644 --- a/nx/include/switch/services/irs.h +++ b/nx/include/switch/services/irs.h @@ -10,6 +10,45 @@ #include "../services/sm.h" #include "../services/hid.h" +typedef struct { + u64 unk_x0; + u8 unk_x8; + u8 unk_x9; + u8 unk_xa; + u8 pad[5]; + u16 unk_x10; + u32 unk_x12; + u16 unk_x16; + u32 unk_constant;//offset 0x18 + u8 unk_x1c; + u8 unk_x1d; + u8 pad2[2]; +} PACKED irsPackedMomentProcessorConfig; + +typedef struct { + u64 exposure; ///< IR Sensor exposure time in nanoseconds. + u32 ir_leds; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + u32 digital_gain; ///< IR sensor signal's digital gain. + u8 color_invert; ///< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + u8 pad[7]; + u32 sensor_res; ///< IR Sensor resolution. 0: 240x320, 1: 120x160, 2: 60x80. +} irsImageTransferProcessorConfig; + +typedef struct { + u64 exposure; ///< IR Sensor exposure time in nanoseconds. + u8 ir_leds; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + u8 digital_gain; ///< IR sensor signal's digital gain. + u8 color_invert; ///< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + u8 pad[5]; + u32 unk_constant;//offset 0x10 + u8 sensor_res; ///< IR Sensor resolution. 0: 240x320, 1: 120x160, 2: 60x80. + u8 pad2[3]; +} irsPackedImageTransferProcessorConfig; + +typedef struct { + u8 unk_x0[0x10]; +} PACKED irsImageTransferProcessorState; + Result irsInitialize(void); void irsExit(void); @@ -20,3 +59,28 @@ void* irsGetSharedmemAddr(void); Result irsActivateIrsensor(bool activate); Result irsGetIrCameraHandle(u32 *IrCameraHandle, HidControllerID id); + +/** + * @brief Start ImageTransferProcessor. + * @param[in] IrCameraHandle Camera handle. + * @param[in] config Input config. + * @param[in] size Work-buffer size, must be 0x1000-byte aligned. + * @note Do not use if already started. + */ +Result irsRunImageTransferProcessor(u32 IrCameraHandle, irsImageTransferProcessorConfig *config, size_t size); + +Result irsGetImageTransferProcessorState(u32 IrCameraHandle, void* buffer, size_t size, irsImageTransferProcessorState *state); + +/// Stop ImageTransferProcessor. Do not use if already stopped. +/// \ref irsExit calls this with all IrCameraHandles which were not already used with \ref irsStopImageProcessor. +Result irsStopImageProcessor(u32 IrCameraHandle); + +/// "Suspend" ImageTransferProcessor. +/// TODO: What does this really do? +Result irsSuspendImageProcessor(u32 IrCameraHandle); + +/** + * Gets the default configuration for Image Transfer mode. + * Defaults are exposure 300us, IR LEDs all ON, 8x digital gain, normal image and resolution 240 x 320. + */ +void irsGetDefaultImageTransferProcessorConfig(irsImageTransferProcessorConfig *config); diff --git a/nx/include/switch/services/pm.h b/nx/include/switch/services/pm.h index a0af0c42..6a1c8e3c 100644 --- a/nx/include/switch/services/pm.h +++ b/nx/include/switch/services/pm.h @@ -8,6 +8,8 @@ #include "../types.h" Result pmdmntInitialize(void); +void pmdmntExit(void); + Result pmdmntStartProcess(u64 pid); Result pmdmntGetTitlePid(u64* pid_out, u64 title_id); Result pmdmntEnableDebugForTitleId(Handle* handle_out, u64 title_id); diff --git a/nx/include/switch/services/sfdnsres.h b/nx/include/switch/services/sfdnsres.h new file mode 100644 index 00000000..26ca14de --- /dev/null +++ b/nx/include/switch/services/sfdnsres.h @@ -0,0 +1,48 @@ +/** + * @file sfdnsres.h + * @brief Domain name resolution service IPC wrapper. Please use socket.c instead. + * @author TuxSH + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +#include // For socklen_t, etc. + +/// Configuration structure for sfdnsres. +typedef struct { + size_t serialized_out_addrinfos_max_size; ///< For getaddrinfo. + size_t serialized_out_hostent_max_size; ///< For gethostbyname/gethostbyaddr. + bool bypass_nsd; ///< For name gethostbyname/getaddrinfo: bypass the Name Server Daemon. + int timeout; ///< For DNS requests: timeout or 0. +} SfdnsresConfig; + +/// Result values returned by the DNS request commands. +typedef struct { + int ret; ///< Return value (error code). + int errno_; ///< Errno. + ssize_t out_serialized_size; ///< Size of the serialized output buffer or -1 (?). +} SfdnsresRequestResults; + +// SetDnsAddressesPrivate & GetDnsAddressPrivate are stubbed + +Result sfdnsresGetHostByName(SfdnsresRequestResults *ret, const SfdnsresConfig *config, void *out_he_serialized, const char *name); +Result sfdnsresGetHostByAddr(SfdnsresRequestResults *ret, const SfdnsresConfig *config, void *out_he_serialized, const void *addr, socklen_t len, int type); + +Result sfdnsresGetHostStringError(int err, char *str, size_t str_size); +Result sfdnsresGetGaiStringError(int err, char *str, size_t str_size); + +Result sfdnsresGetAddrInfo(SfdnsresRequestResults *ret, const SfdnsresConfig *config, const char *node, const char *service, + const void *hints_serialized, size_t hints_serialized_size, void *res_serialized); +Result sfdnsresGetNameInfo(SfdnsresRequestResults *ret, const SfdnsresConfig *config, + const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, + char *serv, size_t servlen, int flags); + +/// Requests an handle for use with @ref sfdnsresCancelSocketCall. +Result sfdnsresRequestCancelHandle(u32 *out_handle); +/// Cancels a DNS request (how? which requests?). Bug: always sets errno? +Result sfdnsresCancelSocketCall(SfdnsresRequestResults *ret, u32 handle); +/// Cancels all DNS requests made by the current process (how? which requests?). Bug: always sets errno? +Result sfdnsresCancelAllSocketCalls(SfdnsresRequestResults *ret); +/// Clears up to 4 DNS server IPs registered by bsdcfg (DHCP client, etc.). +Result sfdnsresClearDnsIpServerAddressArray(void); diff --git a/nx/include/switch/services/sm.h b/nx/include/switch/services/sm.h index 1208e541..cc592700 100644 --- a/nx/include/switch/services/sm.h +++ b/nx/include/switch/services/sm.h @@ -8,18 +8,21 @@ #pragma once #include "../types.h" #include "../kernel/svc.h" -#include "../ipc.h" +#include "../kernel/ipc.h" /// Service type. typedef enum { - ServiceType_Uninitialized, ///< Uninitialized service. - ServiceType_Normal, ///< Normal service. - ServiceType_Override ///< Service overriden in the homebrew environment. + ServiceType_Uninitialized, ///< Uninitialized service. + ServiceType_Normal, ///< Normal service. + ServiceType_Domain, ///< Domain. + ServiceType_DomainSubservice, ///< Domain subservice; + ServiceType_Override ///< Service overriden in the homebrew environment. } ServiceType; /// Service object structure. typedef struct { Handle handle; + u32 object_id; ServiceType type; } Service; @@ -41,10 +44,47 @@ static inline bool serviceIsActive(Service* s) { return s->type != ServiceType_Uninitialized; } +/** + * @brief Returns whether a service is a domain. + * @param[in] s Service object. + * @return true if a domain. + */ +static inline bool serviceIsDomain(Service* s) { + return s->type == ServiceType_Domain; +} + +/** + * @brief Returns whether a service is a domain subservice. + * @param[in] s Service object. + * @return true if a domain subservice. + */ +static inline bool serviceIsDomainSubservice(Service* s) { + return s->type == ServiceType_DomainSubservice; +} + +/** + * @brief For a domain/domain subservice, return the associated object ID. + * @param[in] s Service object, necessarily a domain or domain subservice. + * @return The object ID. + */ +static inline u32 serviceGetObjectId(Service* s) { + return s->object_id; +} + +/** + * @brief Closes a domain object by ID. + * @param[in] s Service object, necessarily a domain or domain subservice. + * @param object_id ID of the object to close. + * @return Result code. + */ +static inline Result serviceCloseObjectById(Service* s, u32 object_id) { + return ipcCloseObjectById(s->handle, object_id); +} + /** * @brief Dispatches an IPC request to a service. * @param[in] s Service object. - * @return Result code + * @return Result code. */ static inline Result serviceIpcDispatch(Service* s) { return ipcDispatch(s->handle); @@ -52,12 +92,37 @@ static inline Result serviceIpcDispatch(Service* s) { /** * @brief Creates a service object from an IPC session handle. - * @param[in] s Service object. + * @param[out] s Service object. * @param[in] h IPC session handle. */ static inline void serviceCreate(Service* s, Handle h) { s->handle = h; s->type = ServiceType_Normal; + s->object_id = IPC_INVALID_OBJECT_ID; +} + +/** + * @brief Creates a domain subservice object from a parent service. + * @param[out] s Service object. + * @param[in] parent Parent service, necessarily a domain or domain subservice. + * @param[in] object_id Object ID for this subservice. + */ +static inline void serviceCreateDomainSubservice(Service* s, Service* parent, u32 object_id) { + s->handle = parent->handle; + s->type = ServiceType_DomainSubservice; + s->object_id = object_id; +} + +/** + * @brief Converts a regular service to a domain. + * @param[in] s Service object. + * @return Result code. + */ +static inline Result serviceConvertToDomain(Service* s) { + Result rc = ipcConvertSessionToDomain(s->handle, &s->object_id); + if(R_SUCCEEDED(rc)) + s->type = ServiceType_Domain; + return rc; } /** @@ -68,9 +133,14 @@ static inline void serviceClose(Service* s) { switch (s->type) { case ServiceType_Normal: + case ServiceType_Domain: svcCloseHandle(s->handle); break; + case ServiceType_DomainSubservice: + serviceCloseObjectById(s, s->object_id); + break; + case ServiceType_Override: // Don't close because we don't own the overridden handle. break; diff --git a/nx/source/display/binder.c b/nx/source/display/binder.c index 20a645db..9c141e24 100644 --- a/nx/source/display/binder.c +++ b/nx/source/display/binder.c @@ -1,7 +1,7 @@ #include #include "types.h" #include "result.h" -#include "ipc.h" +#include "kernel/ipc.h" #include "kernel/detect.h" #include "display/binder.h" diff --git a/nx/source/kernel/mutex.c b/nx/source/kernel/mutex.c index 95c22719..2152a8d8 100644 --- a/nx/source/kernel/mutex.c +++ b/nx/source/kernel/mutex.c @@ -41,6 +41,23 @@ void mutexLock(Mutex* m) { } } +bool mutexTryLock(Mutex* m) { + u32 self = _GetTag(); + u32 cur = __sync_val_compare_and_swap((u32*)m, 0, self); + + if (cur == 0) { + // We won the race! + return true; + } + + if ((cur &~ HAS_LISTENERS) == self) { + // Kernel assigned it to us! + return true; + } + + return 0; +} + void mutexUnlock(Mutex* m) { u32 old = __sync_lock_test_and_set((u32*)m, 0); @@ -58,6 +75,18 @@ void rmutexLock(RMutex* m) { m->counter++; } +bool rmutexTryLock(RMutex* m) { + if (m->thread_tag != _GetTag()) { + if (!mutexTryLock(&m->lock)) { + return false; + } + m->thread_tag = _GetTag(); + } + + m->counter++; + return true; +} + void rmutexUnlock(RMutex* m) { if (--m->counter == 0) { m->thread_tag = 0; diff --git a/nx/source/kernel/tmem.c b/nx/source/kernel/tmem.c index 338a1e07..8c154527 100644 --- a/nx/source/kernel/tmem.c +++ b/nx/source/kernel/tmem.c @@ -1,4 +1,5 @@ // Copyright 2017 plutoo +#include #include #include "types.h" #include "result.h" @@ -19,6 +20,9 @@ Result tmemCreate(TransferMemory* t, size_t size, Permission perm) if (t->src_addr == NULL) { rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory); } + else { + memset(t->src_addr, 0, size); + } if (R_SUCCEEDED(rc)) { rc = svcCreateTransferMemory(&t->handle, t->src_addr, size, perm); diff --git a/nx/source/runtime/argv.c b/nx/source/runtime/argv.c index 72975c54..13c89c68 100644 --- a/nx/source/runtime/argv.c +++ b/nx/source/runtime/argv.c @@ -103,13 +103,14 @@ void argvSetup(void) else { end_flag = 0; - if (quote_flag && args[argi] == '"') { - end_flag = 1; + if (quote_flag) { + if (args[argi] == '"') end_flag = 1; } else if (isspace(args[argi])) { end_flag = 1; } - else if(args[argi]!=0) { + + if(end_flag==0 && args[argi]!=0) { arglen++; } diff --git a/nx/source/runtime/devices/socket.c b/nx/source/runtime/devices/socket.c new file mode 100644 index 00000000..a7c807fb --- /dev/null +++ b/nx/source/runtime/devices/socket.c @@ -0,0 +1,1554 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "runtime/devices/socket.h" +#include "services/bsd.h" +#include "services/sfdnsres.h" +#include "result.h" + +__thread int h_errno; + +static SfdnsresConfig g_sfdnsresConfig; +static __thread Result g_sfdnsresResult; + +const struct in6_addr in6addr_any = {0}; +const struct in6_addr in6addr_loopback = {.__u6_addr32 = {0, 0, 0, __builtin_bswap32(1)}}; + +static int _socketOpen(struct _reent *r, void *fdptr, const char *path, int flags, int mode); +static int _socketClose(struct _reent *r, void *fdptr); +static ssize_t _socketWrite(struct _reent *r, void *fdptr, const char *buf, size_t count); +static ssize_t _socketRead(struct _reent *r, void *fdptr, char *buf, size_t count); + +static const devoptab_t g_socketDevoptab = { + .name = "soc", + .structSize = sizeof(int), + .open_r = _socketOpen, + .close_r = _socketClose, + .write_r = _socketWrite, + .read_r = _socketRead, + .seek_r = NULL, + .fstat_r = NULL, + .stat_r = NULL, + .link_r = NULL, + .unlink_r = NULL, + .chdir_r = NULL, + .rename_r = NULL, + .mkdir_r = NULL, + .dirStateSize = 0, + .diropen_r = NULL, + .dirreset_r = NULL, + .dirnext_r = NULL, + .dirclose_r = NULL, + .statvfs_r = NULL, + .ftruncate_r = NULL, + .fsync_r = NULL, + .deviceData = 0, + .chmod_r = NULL, + .fchmod_r = NULL, + .rmdir_r = NULL, +}; + +static const SocketInitConfig g_defaultSocketInitConfig = { + .bsdsockets_version = 1, + + .tcp_tx_buf_size = 0x8000, + .tcp_rx_buf_size = 0x10000, + .tcp_tx_buf_max_size = 0x40000, + .tcp_rx_buf_max_size = 0x40000, + + .udp_tx_buf_size = 0x2400, + .udp_rx_buf_size = 0xA500, + + .sb_efficiency = 4, + + .serialized_out_addrinfos_max_size = 0x1000, + .serialized_out_hostent_max_size = 0x200, + .bypass_nsd = false, + .dns_timeout = 0, +}; + +const SocketInitConfig *socketGetDefaultInitConfig(void) { + return &g_defaultSocketInitConfig; +} + +Result socketInitialize(const SocketInitConfig *config) { + Result ret = 0; + BsdInitConfig bcfg = { + .version = config->bsdsockets_version, + + .tcp_tx_buf_size = config->tcp_tx_buf_size, + .tcp_rx_buf_size = config->tcp_rx_buf_size, + .tcp_tx_buf_max_size = config->tcp_tx_buf_max_size, + .tcp_rx_buf_max_size = config->tcp_rx_buf_max_size, + + .udp_tx_buf_size = config->udp_tx_buf_size, + .udp_rx_buf_size = config->udp_rx_buf_size, + + .sb_efficiency = config->sb_efficiency, + }; + + SfdnsresConfig sfdnsresConfig = { + .serialized_out_addrinfos_max_size = config->serialized_out_addrinfos_max_size, + .serialized_out_hostent_max_size = config->serialized_out_hostent_max_size, + .bypass_nsd = config->bypass_nsd, + .timeout = config->dns_timeout, + }; + + int dev = FindDevice("soc:"); + if(dev != -1) + return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + + ret = bsdInitialize(&bcfg); + if(R_SUCCEEDED(ret)) + dev = AddDevice(&g_socketDevoptab); + else { + socketExit(); + return ret; + } + + if(dev == -1) { + socketExit(); + return MAKERESULT(Module_Libnx, LibnxError_TooManyDevOpTabs); + } + else { + g_bsdResult = 0; + g_bsdErrno = 0; + + g_sfdnsresConfig = sfdnsresConfig; + g_sfdnsresResult = 0; + } + + return ret; +} + +void socketExit(void) { + RemoveDevice("soc:"); + bsdExit(); +} + +Result socketGetLastBsdResult(void) { + return g_bsdResult; +} + +Result socketGetLastSfdnsresResult(void) { + return g_sfdnsresResult; +} + +/***********************************************************************************************************************/ + +static int _socketGetFd(int fd) { + __handle *handle = __get_handle(fd); + if(handle == NULL) { + errno = EBADF; + return -1; + } + if(strcmp(devoptab_list[handle->device]->name, "soc") != 0) { + errno = ENOTSOCK; + return -1; + } + return *(int *)handle->fileStruct; +} + +static int _socketParseBsdResult(struct _reent *r, int ret) { + int errno_; + if(ret != -1) + return ret; // Nothing to do + else { + if(g_bsdErrno == -1) { + // We're using -1 to signal Switch error codes. + // Note: all of the bsd:u/s handlers return 0. + switch(g_bsdResult) { + case 0xD201: + errno_ = ENFILE; + case 0xD401: + errno_ = EFAULT; + break; + case 0x10601: + errno_ = EBUSY; + break; + default: + errno_ = EPIPE; + break; + } + } + else + errno_ = g_bsdErrno; // Nintendo actually used the Linux errno definitions for their FreeBSD build :) + } + + if(r == NULL) + errno = errno_; + else + r->_errno = errno_; + + return -1; +} + +static int _socketOpen(struct _reent *r, void *fdptr, const char *path, int flags, int mode) { + (void)mode; + int ret = _socketParseBsdResult(r, bsdOpen(path, flags)); + if(ret == -1) + return ret; + + *(int *)fdptr = ret; + return 0; +} + +static int _socketClose(struct _reent *r, void *fdptr) { + int fd = *(int *)fdptr; + return _socketParseBsdResult(r, bsdClose(fd)); +} + +static ssize_t _socketWrite(struct _reent *r, void *fdptr, const char *buf, size_t count) { + int fd = *(int *)fdptr; + ssize_t ret = bsdWrite(fd, buf, count); + + _socketParseBsdResult(r, (int)ret); + return ret; +} + +static ssize_t _socketRead(struct _reent *r, void *fdptr, char *buf, size_t count) { + int fd = *(int *)fdptr; + ssize_t ret = bsdRead(fd, buf, count); + + _socketParseBsdResult(r, (int)ret); + return ret; +} + +/* + It is way too complicated and inefficient to use devoptab with bsdSelect. + We're therefore implementing select with poll. + + Code copied from libctru. +*/ +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { + struct pollfd *pollinfo; + nfds_t numfds = 0; + size_t i, j; + int rc, found; + + if(nfds >= FD_SETSIZE || nfds < 0) { + errno = EINVAL; + return -1; + } + + for(i = 0; i < nfds; ++i) { + if((readfds && FD_ISSET(i, readfds)) + || (writefds && FD_ISSET(i, writefds)) + || (exceptfds && FD_ISSET(i, exceptfds))) + ++numfds; + } + + pollinfo = (struct pollfd*)malloc(numfds * sizeof(struct pollfd)); + if(pollinfo == NULL) { + errno = ENOMEM; + return -1; + } + + for(i = 0, j = 0; i < nfds; ++i) { + if((readfds && FD_ISSET(i, readfds)) + || (writefds && FD_ISSET(i, writefds)) + || (exceptfds && FD_ISSET(i, exceptfds))) { + pollinfo[j].fd = i; + pollinfo[j].events = 0; + pollinfo[j].revents = 0; + + if(readfds && FD_ISSET(i, readfds)) + pollinfo[j].events |= POLLIN; + if(writefds && FD_ISSET(i, writefds)) + pollinfo[j].events |= POLLOUT; + + ++j; + } + } + + if(timeout) + rc = poll(pollinfo, numfds, timeout->tv_sec*1000 + timeout->tv_usec/1000); + else + rc = poll(pollinfo, numfds, -1); + + if(rc < 0) { + free(pollinfo); + return rc; + } + + for(i = 0, j = 0, rc = 0; i < nfds; ++i) { + found = 0; + + if((readfds && FD_ISSET(i, readfds)) + || (writefds && FD_ISSET(i, writefds)) + || (exceptfds && FD_ISSET(i, exceptfds))) { + + if(readfds && FD_ISSET(i, readfds)) { + if(pollinfo[j].events & (POLLIN|POLLHUP)) + found = 1; + else + FD_CLR(i, readfds); + } + + if(writefds && FD_ISSET(i, writefds)) { + if(pollinfo[j].events & (POLLOUT|POLLHUP)) + found = 1; + else + FD_CLR(i, writefds); + } + + if(exceptfds && FD_ISSET(i, exceptfds)) { + if(pollinfo[j].events & POLLERR) + found = 1; + else + FD_CLR(i, exceptfds); + } + + if(found) + ++rc; + ++j; + } + } + + free(pollinfo); + + return rc; +} + +// This is much saner than select. +int poll(struct pollfd *fds, nfds_t nfds, int timeout) { + struct pollfd *fds2; + int ret = 0; + + if(fds == NULL) { + errno = EFAULT; + return -1; + } + + fds2 = (struct pollfd *)malloc(nfds * sizeof(struct pollfd)); + if(fds2 == NULL) { + errno = ENOMEM; + return -1; + } + + for(nfds_t i = 0; i < nfds; i++) { + fds2[i].events = fds[i].events; + fds2[i].revents = fds[i].revents; + fds2[i].fd = _socketGetFd(fds[i].fd); + if(fds2[i].fd == -1) { + ret = -1; + break; + } + } + + if(ret != -1) + ret = _socketParseBsdResult(NULL, bsdPoll(fds2, nfds, timeout)); + if(ret != -1) { + for(nfds_t i = 0; i < nfds; i++) { + fds[i].events = fds2[i].events; + fds[i].revents = fds2[i].revents; + } + } + + free(fds2); + return ret; +} + +int sysctl(const int *name, unsigned int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen) { + return _socketParseBsdResult(NULL, bsdSysctl(name, namelen, oldp, oldlenp, newp, newlen)); +} + +int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, const void *newp, size_t newlen) { + int mib[CTL_MAXNAME + 2]; // +2 because most of the relevant code I've seen uses +2 as well + size_t miblen = CTL_MAXNAME + 2; + + if(sysctlnametomib(name, mib, &miblen) == -1) + return -1; + + return sysctl(mib, miblen, oldp, oldlenp, newp, newlen); +} + +int sysctlnametomib(const char *name, int *mibp, size_t *sizep) { + int oid[2] = {0, 3}; // sysctl.name2oid + int ret; + size_t oldlenp; + + if(name == NULL || mibp == NULL || sizep == NULL) { + errno = EFAULT; + return -1; + } + + oldlenp = 4 * (*sizep); + ret = sysctl(oid, 2, mibp, &oldlenp, name, strlen(name)); + *sizep = oldlenp / 4; + + return ret; +} + +int socket(int domain, int type, int protocol) { + int ret, fd, dev; + + dev = FindDevice("soc:"); + if(dev == -1) + return -1; + + fd = __alloc_handle(dev); + if(fd == -1) + return -1; + + ret = _socketParseBsdResult(NULL, bsdSocket(domain, type, protocol)); + if(ret == -1) { + __release_handle(fd); + return -1; + } + else { + *(int *)__get_handle(fd)->fileStruct = ret; + return fd; + } +} + +ssize_t recv(int sockfd, void *buf, size_t len, int flags) { + ssize_t ret; + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + ret = bsdRecv(sockfd, buf, len, flags); + return _socketParseBsdResult(NULL, (int)ret); +} + +ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { + ssize_t ret; + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + ret = bsdRecvFrom(sockfd, buf, len, flags, src_addr, addrlen); + return _socketParseBsdResult(NULL, (int)ret); +} + +ssize_t send(int sockfd, const void* buf, size_t len, int flags) { + ssize_t ret; + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + ret = bsdSend(sockfd, buf, len, flags); + return _socketParseBsdResult(NULL, (int)ret); +} + +ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { + ssize_t ret; + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + ret = bsdSendTo(sockfd, buf, len, flags, dest_addr, addrlen); + return _socketParseBsdResult(NULL, (int)ret); +} + +int accept(int sockfd, struct sockaddr *address, socklen_t *addrlen) { + int ret, fd, dev; + + fd = _socketGetFd(sockfd); + if(fd == -1) + return -1; + + dev = __get_handle(sockfd)->device; + sockfd = fd; + + fd = __alloc_handle(dev); + if(fd == -1) + return -1; + + ret = _socketParseBsdResult(NULL, bsdAccept(sockfd, address, addrlen)); + if(ret == -1) { + __release_handle(fd); + return -1; + } + else { + *(int *)__get_handle(fd)->fileStruct = ret; + return fd; + } +} + +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + return _socketParseBsdResult(NULL, bsdBind(sockfd, addr, addrlen)); +} + +int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + return _socketParseBsdResult(NULL, bsdConnect(sockfd, addr, addrlen)); +} + +int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + return _socketParseBsdResult(NULL, bsdGetPeerName(sockfd, addr, addrlen)); +} + +int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + return _socketParseBsdResult(NULL, bsdGetSockName(sockfd, addr, addrlen)); +} + +int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) { + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + return _socketParseBsdResult(NULL, bsdGetSockOpt(sockfd, level, optname, optval, optlen)); +} + +int listen(int sockfd, int backlog) { + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + return _socketParseBsdResult(NULL, bsdListen(sockfd, backlog)); +} + +int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) { + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + return _socketParseBsdResult(NULL, bsdSetSockOpt(sockfd, level, optname, optval, optlen)); +} + +int ioctl(int fd, int request, ...) { + void *data; + va_list args; + + va_start(args, request); + data = (request & IOC_INOUT) ? va_arg(args, void *) : NULL; + va_end(args); + + if(data == NULL && (request & IOC_INOUT) && IOCPARM_LEN(request) != 0) { + errno = EFAULT; + return -1; + } + + fd = request != FIONBIO ? _socketGetFd(fd) : fd; + if(fd == -1) + return -1; + + switch(request) { + case FIONBIO: { + // See note in fcntl (below) + int flags = fcntl(fd, F_GETFL, 0); + if(flags == -1) + return -1; + flags = *(int *)data != 0 ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK); + return fcntl(fd, F_SETFL, 0); + } + case BIOCSETF: + case BIOCSETWF: + case BIOCSETFNR: { + int ret; + struct bpf_program *prog = (struct bpf_program *)data; + if(prog->bf_len > BPF_MAXBUFSIZE) { + errno = EINVAL; + return -1; + } + + struct bpf_program_serialized *prog_ser = (struct bpf_program_serialized *)malloc(sizeof(struct bpf_program_serialized)); + if(prog_ser == NULL) { + errno = ENOMEM; + return -1; + } + + prog_ser->bf_len = prog->bf_len; + memcpy(prog_ser->bf_insns, prog->bf_insns, prog->bf_len); + + request = _IOC(request & IOC_DIRMASK, IOCGROUP(request), IOCBASECMD(request), sizeof(struct bpf_program_serialized)); + ret = bsdIoctl(fd, request, prog_ser); + free(prog_ser); + return _socketParseBsdResult(NULL, ret); + } + default: + return _socketParseBsdResult(NULL, bsdIoctl(fd, request, data)); + } +} + +int fcntl(int fd, int cmd, ...) { + va_list args; + int flags; + + /* + bsd:u/s only supports F_GETFL and F_SETFL with the O_NONBLOCK flag (or 0). + F_GETFL is implemented using a custom, non-whitelisted IOCTL, whereas + F_SETFL is implemented using FIONBIO. + */ + if(cmd != F_GETFL && cmd != F_SETFL) + return EOPNOTSUPP; + va_start(args, cmd); + flags = va_arg(args, int); + va_end(args); + + fd = _socketGetFd(fd); + if(fd == -1) + return -1; + return _socketParseBsdResult(NULL, bsdFcntl(fd, cmd, flags)); +} + +int shutdown(int sockfd, int how) { + sockfd = _socketGetFd(sockfd); + if(sockfd == -1) + return -1; + return _socketParseBsdResult(NULL, bsdShutdown(sockfd, how)); +} + +int sockatmark(int sockfd) { + int atmark; + return ioctl(sockfd, SIOCATMARK, &atmark) == -1 ? -1 : atmark; +} + +int socketpair(int domain, int type, int protocol, int sv[2]) { + // Unimplementable, function definition written for compliance + errno = ENOSYS; + return -1; +} + +ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) { + if(msg == NULL) { + errno = EFAULT; + return -1; + } + + struct mmsghdr msgvec = { + .msg_hdr = *msg, + .msg_len = 1, + }; + + return recvmmsg(sockfd, &msgvec, 1, flags, NULL); +} + +ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) { + if(msg == NULL) { + errno = EFAULT; + return -1; + } + + struct mmsghdr msgvec = { + .msg_hdr = *msg, + .msg_len = 1, + }; + + return sendmmsg(sockfd, &msgvec, 1, flags); +} + +int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags) { + //TODO: do the necessary RE & implement it + errno = ENOSYS; + return -1; +} +int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout) { + //TODO: do the necessary RE & implement it + errno = ENOSYS; + return -1; +} + +/***********************************************************************************************************************/ + +// Adapted from ctrulib +static int _socketInetAtonDetail(int *outBase, size_t *outNumBytes, const char *cp, struct in_addr *inp) { + int base; + u32 val; + int c; + char bytes[4]; + size_t num_bytes = 0; + + c = *cp; + for(;;) { + if(!isdigit(c)) return 0; + + val = 0; + base = 10; + if(c == '0') { + c = *++cp; + if(c == 'x' || c == 'X') { + base = 16; + c = *++cp; + } + else base = 8; + } + + for(;;) { + if(isdigit(c)) { + if(base == 8 && c >= '8') return 0; + val *= base; + val += c - '0'; + c = *++cp; + } + else if(base == 16 && isxdigit(c)) { + val *= base; + val += c + 10 - (islower(c) ? 'a' : 'A'); + c = *++cp; + } + else break; + } + + if(c == '.') { + if(num_bytes > 3) return 0; + if(val > 0xFF) return 0; + bytes[num_bytes++] = val; + c = *++cp; + } + else break; + } + + if(c != 0) { + *outNumBytes = num_bytes; + *outBase = base; + return 0; + } + + switch(num_bytes) { + case 0: + break; + + case 1: + if(val > 0xFFFFFF) return 0; + val |= bytes[0] << 24; + break; + + case 2: + if(val > 0xFFFF) return 0; + val |= bytes[0] << 24; + val |= bytes[1] << 16; + break; + + case 3: + if(val > 0xFF) return 0; + val |= bytes[0] << 24; + val |= bytes[1] << 16; + val |= bytes[2] << 8; + break; + } + + if(inp) + inp->s_addr = htonl(val); + + *outNumBytes = num_bytes; + *outBase = base; + + return 1; +} + +// Adapted from ctrulib +static const char *inet_ntop4(const void *src, char *dst, socklen_t size) { + const u8 *ip = src; + + char *p; + size_t i; + unsigned int n; + + if(size < INET_ADDRSTRLEN) { + errno = ENOSPC; + return NULL; + } + + for(p = dst, i = 0; i < 4; ++i) { + if(i > 0) *p++ = '.'; + + n = ip[i]; + if(n >= 100) { + *p++ = n/100 + '0'; + n %= 100; + } + if(n >= 10 || ip[i] >= 100) { + *p++ = n/10 + '0'; + n %= 10; + } + *p++ = n + '0'; + } + *p = 0; + + return dst; +} + +static int inet_pton4(const char *src, void *dst) { + int base; + size_t numBytes; + + int ret = _socketInetAtonDetail(&base, &numBytes, src, (struct in_addr *)dst); + return (ret == 1 && base == 10 && numBytes == 4) ? 1 : 0; +} + +/* Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#define INADDRSZ 4 +#define IN6ADDRSZ 16 +#define INT16SZ 2 +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop6(src, dst, size) + const u_char *src; + char *dst; + size_t size; +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best = {0}, cur = {0}; + u_int words[IN6ADDRSZ / INT16SZ]; + int i; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, 0, sizeof words); + for (i = 0; i < IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; + } + //TuxSH: + //sprintf(tp, "%x", words[i]); + { + char hexbuf[8]; + char *e = hexbuf + 7; + u_int word = words[i]; + while(word > 0) { + static const char digits[] = "0123456789abcdef"; + *e-- = digits[word & 0xF]; + word >>= 4; + } + + memcpy(tp, e + 1, hexbuf + 8 - (e + 1)); + } + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} + +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton6(src, dst) + const char *src; + u_char *dst; +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + u_int val; + + memset((tp = tmp), 0, IN6ADDRSZ); + endp = tp + IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = tp - colonp; + int i; + + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + /* bcopy(tmp, dst, IN6ADDRSZ); */ + memcpy(dst, tmp, IN6ADDRSZ); + return (1); +} + +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) { + switch(af) { + case AF_INET: + return inet_ntop4(src, dst, size); + case AF_INET6: + return inet_ntop6(src, dst, size); + default: + errno = EAFNOSUPPORT; + return NULL; + } +} + +int inet_pton(int af, const char *src, void *dst) { + switch(af) { + case AF_INET: + return inet_pton4(src, dst); + case AF_INET6: + return inet_pton6(src, dst); + default: + errno = EAFNOSUPPORT; + return -1; + } +} + +char *inet_ntoa(struct in_addr in) { + static __thread char buffer[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &in.s_addr, buffer, INET_ADDRSTRLEN); + return buffer; +} + +int inet_aton(const char *cp, struct in_addr *inp) { + int base; + size_t numBytes; + return _socketInetAtonDetail(&base, &numBytes, cp, inp); +} + +in_addr_t inet_addr(const char *cp) { + struct in_addr addr = { .s_addr = INADDR_BROADCAST }; + inet_aton(cp, &addr); + return addr.s_addr; +} + +/***********************************************************************************************************************/ + +static struct hostent *_socketDeserializeHostent(int *err, const void *out_he_serialized) { + const char *buf = (const char *)out_he_serialized; + const char *pos, *pos_aliases, *pos_addresses; + size_t name_size, total_aliases_size = 0; + size_t nb_addresses; + size_t nb_aliases = 0; + size_t len; + + int addrtype, addrlen; + struct hostent *he; + + // Calculate the size of the buffer to allocate + pos = buf; + name_size = strlen(pos) + 1; + pos += name_size; + pos_aliases = pos; + for(pos = buf, len = 1; len != 0; pos += len + 1) { + len = strlen(buf); + if(len != 0) + nb_aliases++; + } + + total_aliases_size = pos - pos_aliases - 1; + + // Nintendo uses unsigned short here... + addrtype = ntohl(*(const u16 *)pos); + pos += 2; + addrlen = ntohl(*(const u16 *)pos); + pos += 2; + + // sfdnsres will only return IPv4 addresses for the "host" commands + if(addrtype != AF_INET || addrlen != sizeof(struct in_addr)) { + *err = NO_ADDRESS; + return NULL; + } + + // The official hostent (de)serializer doesn't support IPv6, at least not currently. + pos_addresses = pos; + for(nb_addresses = 0; ((const struct in_addr *)pos)->s_addr != 0; nb_addresses++); + + he = (struct hostent *)malloc( + sizeof(struct hostent) + + name_size + + 8 * (nb_aliases + 1 + nb_addresses + 1) + + total_aliases_size + + addrlen * nb_addresses + ); + + if(he == NULL) { + *err = NO_RECOVERY; + return NULL; + } + + he->h_aliases = (char **)(he->h_name + name_size); + he->h_addrtype = addrtype; + he->h_length = addrlen; + he->h_addr_list = he->h_aliases + nb_aliases + 1; + + if(name_size == 1) + he->h_name = NULL; + else { + he->h_name = (char*)he + sizeof(struct hostent); + memcpy(he->h_name, buf, name_size); + } + + char *alias = (char *)(he->h_addr_list + nb_addresses + 1); + memcpy(alias, pos_aliases, total_aliases_size); + for(size_t i = 0; i < nb_aliases; i++) { + he->h_aliases[i] = alias; + alias += strlen(alias) + 1; + } + he->h_aliases[nb_aliases] = NULL; + + struct in_addr *addresses = (struct in_addr *)(he->h_addr_list + nb_addresses + 1 + total_aliases_size); + memcpy(addresses, pos_addresses, addrlen * nb_addresses); + for(size_t i = 0; i < nb_addresses; i++) { + he->h_addr_list[i] = (char *)&addresses[i]; + addresses[i].s_addr = ntohl(addresses[i].s_addr); // lol Nintendo + } + he->h_addr_list[nb_addresses] = NULL; + + return he; +} + +struct addrinfo_serialized_hdr { + u32 magic; + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + u32 ai_addrlen; +}; + +static size_t _socketSerializeAddrInfo(struct addrinfo_serialized_hdr *hdr, const struct addrinfo *ai) { + size_t subsize1 = (ai->ai_addr == NULL || ai->ai_addrlen == 0) ? 4 : ai->ai_addrlen; // not posix-compliant ? + size_t subsize2 = ai->ai_canonname == NULL ? 1 : (strlen(ai->ai_canonname) + 1); + + hdr->magic = htonl(0xBEEFCAFE); // Seriously. + hdr->ai_flags = htonl(ai->ai_flags); + hdr->ai_family = htonl(ai->ai_family); + hdr->ai_socktype = htonl(ai->ai_socktype); + hdr->ai_protocol = htonl(ai->ai_protocol); + hdr->ai_addrlen = ai->ai_addr == NULL ? 0 : htonl((u32)ai->ai_addrlen); + + if(hdr->ai_addrlen == 0) + *(u32 *)((u8 *)hdr + sizeof(struct addrinfo_serialized_hdr)) = 0; + else { + // Nintendo just byteswaps everything recursively... even fields that are already byteswapped. + switch(ai->ai_family) { + case AF_INET: { + struct sockaddr_in sa = {0}; + memcpy(&sa, ai->ai_addr, subsize1 <= sizeof(struct sockaddr_in) ? subsize1 : sizeof(struct sockaddr_in)); + sa.sin_port = htons(sa.sin_port); + sa.sin_addr.s_addr = htonl(sa.sin_addr.s_addr); + memcpy((u8 *)hdr + sizeof(struct addrinfo_serialized_hdr), &sa, sizeof(struct sockaddr_in)); + break; + } + case AF_INET6: { + struct sockaddr_in6 sa6 = {0}; + memcpy(&sa6, ai->ai_addr, subsize1 <= sizeof(struct sockaddr_in6) ? subsize1 : sizeof(struct sockaddr_in6)); + sa6.sin6_port = htons(sa6.sin6_port); + sa6.sin6_flowinfo = htonl(sa6.sin6_flowinfo); + sa6.sin6_scope_id = htonl(sa6.sin6_scope_id); + memcpy((u8 *)hdr + sizeof(struct addrinfo_serialized_hdr), &sa6, sizeof(struct sockaddr_in6)); + break; + } + default: + memcpy((u8 *)hdr + sizeof(struct addrinfo_serialized_hdr), ai->ai_addr, subsize1); + } + } + + if(ai->ai_canonname == NULL) + *((u8 *)hdr + sizeof(struct addrinfo_serialized_hdr) + subsize1) = 0; + else + memcpy((u8 *)hdr + sizeof(struct addrinfo_serialized_hdr) + subsize1, ai->ai_canonname, subsize2); + + return sizeof(struct addrinfo_serialized_hdr) + subsize1 + subsize2; +} + +static struct addrinfo_serialized_hdr *_socketSerializeAddrInfoList(size_t *out_size, const struct addrinfo *ai) { + size_t total_addrlen = 0, total_namelen = 0, n = 0; + struct addrinfo_serialized_hdr *out, *pos; + + for(const struct addrinfo *node = ai; node != NULL; node = node->ai_next) { + total_addrlen += node->ai_addrlen == 0 ? 4 : node->ai_addrlen; + total_namelen += node->ai_canonname == NULL ? 1 : (strlen(node->ai_canonname) + 1); + n++; + } + + out = (struct addrinfo_serialized_hdr *)malloc(sizeof(struct addrinfo_serialized_hdr) * n + total_addrlen + total_namelen + 4); + if(out == NULL) + return NULL; + + pos = out; + for(const struct addrinfo *node = ai; node != NULL; node = node->ai_next) { + size_t len = _socketSerializeAddrInfo(pos, node); + pos = (struct addrinfo_serialized_hdr *)((u8 *)pos + len); + } + *(u32 *)pos = 0; // Sentinel value + + *out_size = (u8 *)pos - (u8 *)out + 4; + return out; +} + +static struct addrinfo *_socketDeserializeAddrInfo(size_t *out_len, const struct addrinfo_serialized_hdr *hdr) { + struct addrinfo_node { + struct addrinfo info; + struct sockaddr_storage addr; + char canonname[]; + }; + + size_t subsize1 = hdr->ai_addrlen == 0 ? 4 : ntohl(hdr->ai_addrlen); + size_t subsize2 = strlen((const char *)hdr + sizeof(struct addrinfo_serialized_hdr) + subsize1) + 1; + struct addrinfo_node *node = (struct addrinfo_node *)malloc(sizeof(struct addrinfo_node) + subsize2); + + *out_len = sizeof(struct addrinfo_serialized_hdr) + subsize1 + subsize2; + if(node == NULL) + return NULL; + + node->info.ai_flags = ntohl(hdr->ai_flags); + node->info.ai_family = ntohl(hdr->ai_family); + node->info.ai_socktype = ntohl(hdr->ai_socktype); + node->info.ai_protocol = ntohl(hdr->ai_protocol); + node->info.ai_addrlen = ntohl(hdr->ai_addrlen); + + // getaddrinfo enforces addrlen = sizeof(struct sockaddr) and family = AF_INET, ie. only IPv4, anyways... + if(node->info.ai_addrlen > sizeof(struct sockaddr_storage)) + node->info.ai_addrlen = sizeof(struct sockaddr_storage); + + if(node->info.ai_addrlen == 0) + node->info.ai_addr = NULL; + else { + node->info.ai_addr = (struct sockaddr *)&node->addr; + memcpy(node->info.ai_addr, (const u8 *)hdr + sizeof(struct addrinfo_serialized_hdr), node->info.ai_addrlen); + // Nintendo just byteswaps everything recursively... even fields that are already byteswapped. + switch(node->info.ai_family) { + case AF_INET: { + struct sockaddr_in *sa = (struct sockaddr_in *)&node->info.ai_addr; + sa->sin_port = ntohs(sa->sin_port); + sa->sin_addr.s_addr = ntohl(sa->sin_addr.s_addr); + break; + } + case AF_INET6: { + struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&node->info.ai_addr; + sa6->sin6_port = ntohs(sa6->sin6_port); + sa6->sin6_flowinfo = ntohl(sa6->sin6_flowinfo); + sa6->sin6_scope_id = ntohl(sa6->sin6_scope_id); + break; + } + default: + break; + } + } + + if(subsize2 == 1) + node->info.ai_canonname = NULL; + else { + node->info.ai_canonname = node->canonname; + memcpy(node->info.ai_canonname, (const u8 *)hdr + sizeof(struct addrinfo_serialized_hdr) + subsize1, subsize2); + } + + node->info.ai_next = NULL; + + return &node->info; +} + +static struct addrinfo *_socketDeserializeAddrInfoList(struct addrinfo_serialized_hdr *hdr) { + struct addrinfo *first = NULL, *prev = NULL; + + while(hdr->magic == htonl(0xBEEFCAFE)) { + size_t len; + struct addrinfo *node = _socketDeserializeAddrInfo(&len, hdr); + if(node == NULL) { + if(first != NULL) + freeaddrinfo(first); + return NULL; + } + + if(first == NULL) + first = node; + + if(prev != NULL) + prev->ai_next = node; + + prev = node; + hdr = (struct addrinfo_serialized_hdr *)((u8 *)hdr + len); + } + + return first; +} + +void freehostent(struct hostent *he) { + free(he); +} + +void freeaddrinfo(struct addrinfo *ai) { + if(ai == NULL) return; // not specified by POSIX, but that's convenient (FreeBSD does this too, etc.). + for(struct addrinfo *node = ai, *next; node != NULL; node = next) { + next = node->ai_next; + free(node); + } +} + +struct hostent *gethostbyname(const char *name) { + Result rc = 0; + void *out_he_serialized = malloc(g_sfdnsresConfig.serialized_out_hostent_max_size); + struct hostent *he = NULL; + SfdnsresRequestResults ret; + + if(out_he_serialized == NULL) { + h_errno = NO_RECOVERY; + errno = ENOMEM; // POSIX leaves this unspecified + goto cleanup; + } + rc = sfdnsresGetHostByName(&ret, &g_sfdnsresConfig, out_he_serialized, name); + if(rc == 0xD401) { + h_errno = NO_RECOVERY; + errno = EFAULT; // POSIX leaves this unspecified + goto cleanup; + } + else if(R_FAILED(rc) && R_MODULE(rc) == 1) { // Kernel + h_errno = TRY_AGAIN; + errno = EAGAIN; // POSIX leaves this unspecified + goto cleanup; + } + else if(R_FAILED(rc)) { + h_errno = NO_RECOVERY; + errno = EINVAL; // POSIX leaves this unspecified + goto cleanup; + } + if(ret.ret != NETDB_SUCCESS) { + h_errno = ret.ret; + errno = ret.errno_; // POSIX leaves this unspecified + goto cleanup; + } + + he = _socketDeserializeHostent(&h_errno, out_he_serialized); + if(he == NULL) { + h_errno = NO_RECOVERY; + errno = ENOMEM; // POSIX leaves this unspecified + } +cleanup: + g_sfdnsresResult = rc; + free(out_he_serialized); + return he; +} + +struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) { + Result rc = 0; + void *out_he_serialized = malloc(g_sfdnsresConfig.serialized_out_hostent_max_size); + struct hostent *he = NULL; + SfdnsresRequestResults ret; + + if(out_he_serialized == NULL) { + h_errno = NO_RECOVERY; + errno = ENOMEM; // POSIX leaves this unspecified + goto cleanup; + } + rc = sfdnsresGetHostByAddr(&ret, &g_sfdnsresConfig, out_he_serialized, addr, len, type); + if(rc == 0xD401) { + h_errno = NO_RECOVERY; // POSIX leaves this unspecified + errno = EFAULT; + goto cleanup; + } + else if(R_FAILED(rc) && R_MODULE(rc) == 1) { // Kernel + h_errno = TRY_AGAIN; + errno = EAGAIN; // POSIX leaves this unspecified + goto cleanup; + } + else if(R_FAILED(rc)) { + h_errno = NO_RECOVERY; + errno = EINVAL; // POSIX leaves this unspecified + goto cleanup; + } + if(ret.ret != NETDB_SUCCESS) { + h_errno = ret.ret; + errno = ret.errno_; // POSIX leaves this unspecified + goto cleanup; + } + + he = _socketDeserializeHostent(&h_errno, out_he_serialized); + if(he == NULL) { + h_errno = NO_RECOVERY; + errno = ENOMEM; // POSIX leaves this unspecified + } +cleanup: + g_sfdnsresResult = rc; + free(out_he_serialized); + return he; +} + +const char *hstrerror(int err) { + static __thread char buf[0x80]; + Result rc = sfdnsresGetHostStringError(err, buf, 0x80); + if(R_FAILED(rc)) // a bit limiting, given the broad range of errors the kernel can give to us... + strcpy(buf, "System busy, try again."); + g_sfdnsresResult = rc; + return buf; +} + +void herror(const char *str) { + fprintf(stderr, "%s: %s\n", str, hstrerror(h_errno)); +} + +const char *gai_strerror(int err) { + static __thread char buf[0x80]; + Result rc = sfdnsresGetGaiStringError(err, buf, 0x80); + if(R_FAILED(rc)) + strcpy(buf, "System busy, try again."); + g_sfdnsresResult = rc; + return buf; +} + +int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { + int gaie = 0; + Result rc = 0; + size_t hints_sz; + struct addrinfo_serialized_hdr *hints_serialized = _socketSerializeAddrInfoList(&hints_sz, hints); + struct addrinfo_serialized_hdr *out_serialized = NULL; + struct addrinfo *out = NULL; + SfdnsresRequestResults ret; + + if(hints_serialized == NULL) { + gaie = EAI_MEMORY; + goto cleanup; + } + + out_serialized = (struct addrinfo_serialized_hdr *)malloc(g_sfdnsresConfig.serialized_out_addrinfos_max_size); + + if(out_serialized == NULL) { + gaie = EAI_MEMORY; + goto cleanup; + } + + rc = sfdnsresGetAddrInfo(&ret, &g_sfdnsresConfig, node, service, hints_serialized, hints_sz, out_serialized); + + if(rc == 0xD401) { + gaie = EAI_SYSTEM; + errno = EFAULT; + goto cleanup; + } + else if(R_FAILED(rc) && R_MODULE(rc) == 1) { // Kernel + gaie = EAI_AGAIN; + goto cleanup; + } + else if(R_FAILED(rc)) { + gaie = EAI_FAIL; + goto cleanup; + } + + gaie = ret.ret; + if(gaie != 0) { + if(gaie == EAI_SYSTEM) + errno = ret.errno_; + goto cleanup; + } + + out = _socketDeserializeAddrInfoList(out_serialized); + if(out == NULL) + gaie = EAI_MEMORY; +cleanup: + *res = out; + free(hints_serialized); + free(out_serialized); + g_sfdnsresResult = rc; + + return gaie; +} + +int getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *host, socklen_t hostlen, + char *serv, socklen_t servlen, + int flags) { + int gaie = 0; + Result rc = 0; + SfdnsresRequestResults ret; + + rc = sfdnsresGetNameInfo(&ret, &g_sfdnsresConfig, sa, salen, host, hostlen, serv, servlen, flags); + if(rc == 0xD401) { + gaie = EAI_SYSTEM; + errno = EFAULT; + goto cleanup; + } + else if(R_FAILED(rc) && R_MODULE(rc) == 1) { // Kernel + gaie = EAI_AGAIN; + goto cleanup; + } + else if(R_FAILED(rc)) { + gaie = EAI_FAIL; + goto cleanup; + } + + + gaie = ret.ret; + if(gaie != 0) { + if(gaie == EAI_SYSTEM) + errno = ret.errno_; + } + +cleanup: + g_sfdnsresResult = rc; + return gaie; +} + +// Unimplementable functions, left for compliance: +struct hostent *gethostent(void) { return NULL; } +struct netent *getnetbyaddr(uint32_t a, int b) { (void)a; (void)b; return NULL; } +struct netent *getnetbyname(const char *s) { (void)s; return NULL; } +struct netent *getnetent(void) { return NULL; } +struct protoent *getprotobyname(const char *s) { (void)s; return NULL; } +struct protoent *getprotobynumber(int a) { (void)a; return NULL; } +struct protoent *getprotoent(void) { return NULL; } +struct servent *getservbyname(const char *s1, const char *s2) { (void)s1; (void)s2; return NULL; } +struct servent *getservbyport(int a, const char *s) { (void)a; (void)s; return NULL; } +struct servent *getservent(void) { return NULL; } +void sethostent(int a) { (void)a;} +void setnetent(int a) { (void)a;} +void setprotoent(int a) { (void)a; } + +/************************************************************************************************************************/ + +long gethostid(void) { + return INADDR_LOOPBACK; //FIXME +} + +int gethostname(char *name, size_t namelen) { + // The Switch doesn't have a proper name, so let's use its IP + struct in_addr in; + in.s_addr = gethostid(); + const char *hostname = inet_ntop(AF_INET, &in, name, namelen); + return hostname == NULL ? -1 : 0; +} diff --git a/nx/source/services/acc.c b/nx/source/services/acc.c index 7a7787c4..49050b62 100644 --- a/nx/source/services/acc.c +++ b/nx/source/services/acc.c @@ -1,19 +1,25 @@ #include "types.h" +#include "arm/atomics.h" #include "services/acc.h" #include "services/sm.h" static Service g_accSrv; +static u64 g_refCnt; Result accountInitialize(void) { + atomicIncrement64(&g_refCnt); + if (serviceIsActive(&g_accSrv)) - return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + return 0; return smGetService(&g_accSrv, "acc:u1"); } -void accountExit(void) { - serviceClose(&g_accSrv); +void accountExit(void) +{ + if (atomicDecrement64(&g_refCnt) == 0) + serviceClose(&g_accSrv); } Service* accountGetService(void) { diff --git a/nx/source/services/apm.c b/nx/source/services/apm.c index 8e3c6716..00ae5c88 100644 --- a/nx/source/services/apm.c +++ b/nx/source/services/apm.c @@ -1,18 +1,22 @@ #include "types.h" #include "result.h" -#include "ipc.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" #include "services/apm.h" #include "services/sm.h" static Service g_apmSrv; static Service g_apmISession; +static u64 g_refCnt; static Result _apmGetSession(Service* srv, Service* srv_out, u64 cmd_id); Result apmInitialize(void) { + atomicIncrement64(&g_refCnt); + if (serviceIsActive(&g_apmSrv)) - return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + return 0; Result rc = 0; @@ -34,8 +38,10 @@ Result apmInitialize(void) void apmExit(void) { - serviceClose(&g_apmISession); - serviceClose(&g_apmSrv); + if (atomicDecrement64(&g_refCnt) == 0) { + serviceClose(&g_apmISession); + serviceClose(&g_apmSrv); + } } static Result _apmGetSession(Service* srv, Service* srv_out, u64 cmd_id) { diff --git a/nx/source/services/applet.c b/nx/source/services/applet.c index 56d4fae3..94ec34a7 100644 --- a/nx/source/services/applet.c +++ b/nx/source/services/applet.c @@ -1,12 +1,13 @@ #include #include "types.h" #include "result.h" -#include "ipc.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" +#include "kernel/detect.h" #include "services/fatal.h" #include "services/applet.h" #include "services/apm.h" #include "services/sm.h" -#include "kernel/detect.h" __attribute__((weak)) u32 __nx_applet_type = AppletType_Default; __attribute__((weak)) bool __nx_applet_auto_notifyrunning = true; @@ -15,6 +16,7 @@ __attribute__((weak)) u32 __nx_applet_PerformanceConfiguration[2] = {/*0x9222000 static Service g_appletSrv; static Service g_appletProxySession; +static u64 g_refCnt; // From Get*Functions. static Service g_appletIFunctions; @@ -69,8 +71,10 @@ static Result _appletSetPerformanceModeChangedNotification(u8 flag); Result appletInitialize(void) { + atomicIncrement64(&g_refCnt); + if (serviceIsActive(&g_appletSrv)) - return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + return 0; if (__nx_applet_type == AppletType_None) return 0; @@ -234,36 +238,39 @@ Result appletInitialize(void) void appletExit(void) { - apmExit(); + if (atomicDecrement64(&g_refCnt) == 0) + { + apmExit(); - //TODO: Enable this somehow later with more condition(s)? - /*if (__nx_applet_type == AppletType_LibraryApplet) - _appletExitProcessAndReturn();*/ + //TODO: Enable this somehow later with more condition(s)? + /*if (__nx_applet_type == AppletType_LibraryApplet) + _appletExitProcessAndReturn();*/ - if (g_appletMessageEventHandle != INVALID_HANDLE) { - svcCloseHandle(g_appletMessageEventHandle); - g_appletMessageEventHandle = INVALID_HANDLE; + if (g_appletMessageEventHandle != INVALID_HANDLE) { + svcCloseHandle(g_appletMessageEventHandle); + g_appletMessageEventHandle = INVALID_HANDLE; + } + + serviceClose(&g_appletIDebugFunctions); + serviceClose(&g_appletIDisplayController); + serviceClose(&g_appletIAudioController); + serviceClose(&g_appletIWindowController); + serviceClose(&g_appletISelfController); + serviceClose(&g_appletICommonStateGetter); + serviceClose(&g_appletILibraryAppletCreator); + + if (__nx_applet_type != AppletType_LibraryApplet) + serviceClose(&g_appletIFunctions); + + if (__nx_applet_type == AppletType_LibraryApplet) { + serviceClose(&g_appletIProcessWindingController); + serviceClose(&g_appletILibraryAppletSelfAccessor); + } + + serviceClose(&g_appletProxySession); + serviceClose(&g_appletSrv); + g_appletResourceUserId = 0; } - - serviceClose(&g_appletIDebugFunctions); - serviceClose(&g_appletIDisplayController); - serviceClose(&g_appletIAudioController); - serviceClose(&g_appletIWindowController); - serviceClose(&g_appletISelfController); - serviceClose(&g_appletICommonStateGetter); - serviceClose(&g_appletILibraryAppletCreator); - - if (__nx_applet_type != AppletType_LibraryApplet) - serviceClose(&g_appletIFunctions); - - if (__nx_applet_type == AppletType_LibraryApplet) { - serviceClose(&g_appletIProcessWindingController); - serviceClose(&g_appletILibraryAppletSelfAccessor); - } - - serviceClose(&g_appletProxySession); - serviceClose(&g_appletSrv); - g_appletResourceUserId = 0; } static void appletCallHook(AppletHookType hookType) diff --git a/nx/source/services/audin.c b/nx/source/services/audin.c new file mode 100644 index 00000000..1b018c7a --- /dev/null +++ b/nx/source/services/audin.c @@ -0,0 +1,458 @@ +#include +#include "types.h" +#include "result.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" +#include "services/audin.h" +#include "services/sm.h" + +#define DEVICE_NAME_LENGTH 0x100 +#define DEFAULT_SAMPLE_RATE 0xBB80 +#define DEFAULT_CHANNEL_COUNT 0x00020000 + +static Service g_audinSrv; +static Service g_audinIAudioIn; +static u64 g_refCnt; + +static Handle g_audinBufferEventHandle = INVALID_HANDLE; + +static u32 g_sampleRate = 0; +static u32 g_channelCount = 0; +static PcmFormat g_pcmFormat = PcmFormat_Invalid; +static AudioInState g_deviceState = AudioInState_Stopped; + +static Result _audinRegisterBufferEvent(Handle *BufferEvent); + +Result audinInitialize(void) +{ + atomicIncrement64(&g_refCnt); + + if (serviceIsActive(&g_audinSrv)) + return 0; + + Result rc = 0; + rc = smGetService(&g_audinSrv, "audin:u"); + + // Setup the default device + if (R_SUCCEEDED(rc)) + { + // Passing an empty device name will open the default "BuiltInHeadset" + char DeviceNameIn[DEVICE_NAME_LENGTH] = {0}; + char DeviceNameOut[DEVICE_NAME_LENGTH] = {0}; + + // Open audio input device + rc = audinOpenAudioIn(DeviceNameIn, DeviceNameOut, DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_COUNT, &g_sampleRate, &g_channelCount, &g_pcmFormat, &g_deviceState); + } + + // Register global handle for buffer events + if (R_SUCCEEDED(rc)) + rc = _audinRegisterBufferEvent(&g_audinBufferEventHandle); + + if (R_FAILED(rc)) + audinExit(); + + return rc; +} + +void audinExit(void) +{ + if (atomicDecrement64(&g_refCnt) == 0) + { + if (g_audinBufferEventHandle != INVALID_HANDLE) { + svcCloseHandle(g_audinBufferEventHandle); + g_audinBufferEventHandle = INVALID_HANDLE; + } + + g_sampleRate = 0; + g_channelCount = 0; + g_pcmFormat = PcmFormat_Invalid; + g_deviceState = AudioInState_Stopped; + + serviceClose(&g_audinIAudioIn); + serviceClose(&g_audinSrv); + } +} + +u32 audinGetSampleRate(void) { + return g_sampleRate; +} + +u32 audinGetChannelCount(void) { + return g_channelCount; +} + +PcmFormat audinGetPcmFormat(void) { + return g_pcmFormat; +} + +AudioInState audinGetDeviceState(void) { + return g_deviceState; +} + +Result audinWaitCaptureFinish(AudioInBuffer **released, u32* released_count, u64 timeout) { + // Wait on the buffer event handle + Result rc = svcWaitSynchronizationSingle(g_audinBufferEventHandle, timeout); + + if (R_SUCCEEDED(rc)) + { + // Signal the buffer event handle right away + svcResetSignal(g_audinBufferEventHandle); + + // Grab the released buffer + rc = audinGetReleasedAudioInBuffer(released, released_count); + } + + return rc; +} + +Result audinCaptureBuffer(AudioInBuffer *source, AudioInBuffer **released) { + Result rc = 0; + u32 released_count = 0; + + // Try to push the supplied buffer to the audio input device + rc = audinAppendAudioInBuffer(source); + + if (R_SUCCEEDED(rc)) + rc = audinWaitCaptureFinish(released, &released_count, U64_MAX); + + return rc; +} + +Result audinListAudioIns(char *DeviceNames, u32 *DeviceNamesCount) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + ipcAddRecvBuffer(&c, DeviceNames, DEVICE_NAME_LENGTH, 0); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 0; + + Result rc = serviceIpcDispatch(&g_audinSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u32 DeviceNamesCount; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && DeviceNamesCount) + *DeviceNamesCount = resp->DeviceNamesCount; + } + + return rc; +} + +Result audinOpenAudioIn(const char *DeviceNameIn, char *DeviceNameOut, u32 SampleRateIn, u32 ChannelCountIn, u32 *SampleRateOut, u32 *ChannelCountOut, PcmFormat *Format, AudioInState *State) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 sample_rate; + u32 channel_count; + u64 client_pid; + } *raw; + + ipcSendPid(&c); + ipcSendHandleCopy(&c, CUR_PROCESS_HANDLE); + ipcAddSendBuffer(&c, DeviceNameIn, DEVICE_NAME_LENGTH, 0); + ipcAddRecvBuffer(&c, DeviceNameOut, DEVICE_NAME_LENGTH, 0); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 1; + raw->sample_rate = SampleRateIn; + raw->channel_count = ChannelCountIn; + raw->client_pid = 0; + + Result rc = serviceIpcDispatch(&g_audinSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u32 sample_rate; + u32 channel_count; + u32 pcm_format; + u32 state; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + serviceCreate(&g_audinIAudioIn, r.Handles[0]); + + if (SampleRateOut) + *SampleRateOut = resp->sample_rate; + + if (ChannelCountOut) + *ChannelCountOut = resp->channel_count; + + if (Format) + *Format = resp->pcm_format; + + if (State) + *State = resp->state; + } + } + + return rc; +} + +Result audinGetAudioInState(AudioInState *State) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 0; + + Result rc = serviceIpcDispatch(&g_audinIAudioIn); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u32 state; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && State) + *State = resp->state; + } + + return rc; +} + +Result audinStartAudioIn(void) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 1; + + Result rc = serviceIpcDispatch(&g_audinIAudioIn); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result audinStopAudioIn(void) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 2; + + Result rc = serviceIpcDispatch(&g_audinIAudioIn); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result audinAppendAudioInBuffer(AudioInBuffer *Buffer) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 tag; + } *raw; + + ipcAddSendBuffer(&c, Buffer, sizeof(*Buffer), 0); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 3; + raw->tag = (u64)Buffer; + + Result rc = serviceIpcDispatch(&g_audinIAudioIn); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +static Result _audinRegisterBufferEvent(Handle *BufferEvent) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 4; + + Result rc = serviceIpcDispatch(&g_audinIAudioIn); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && BufferEvent) + *BufferEvent = r.Handles[0]; + } + + return rc; +} + +Result audinGetReleasedAudioInBuffer(AudioInBuffer **Buffer, u32 *ReleasedBuffersCount) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + ipcAddRecvBuffer(&c, Buffer, sizeof(*Buffer), 0); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 5; + + Result rc = serviceIpcDispatch(&g_audinIAudioIn); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u32 released_buffers_count; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && ReleasedBuffersCount) + *ReleasedBuffersCount = resp->released_buffers_count; + } + + return rc; +} + +Result audinContainsAudioInBuffer(AudioInBuffer *Buffer, bool *ContainsBuffer) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 tag; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 6; + raw->tag = (u64)Buffer; + + Result rc = serviceIpcDispatch(&g_audinIAudioIn); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u32 contains_buffer; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && ContainsBuffer) + *ContainsBuffer = (resp->contains_buffer & 0x01); + } + + return rc; +} diff --git a/nx/source/services/audout.c b/nx/source/services/audout.c index 6c2a6096..4fde7f3c 100644 --- a/nx/source/services/audout.c +++ b/nx/source/services/audout.c @@ -1,7 +1,8 @@ #include #include "types.h" #include "result.h" -#include "ipc.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" #include "services/audout.h" #include "services/sm.h" @@ -11,6 +12,7 @@ static Service g_audoutSrv; static Service g_audoutIAudioOut; +static u64 g_refCnt; static Handle g_audoutBufferEventHandle = INVALID_HANDLE; @@ -23,8 +25,10 @@ static Result _audoutRegisterBufferEvent(Handle *BufferEvent); Result audoutInitialize(void) { + atomicIncrement64(&g_refCnt); + if (serviceIsActive(&g_audoutSrv)) - return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + return 0; Result rc = 0; rc = smGetService(&g_audoutSrv, "audout:u"); @@ -52,18 +56,21 @@ Result audoutInitialize(void) void audoutExit(void) { - if (g_audoutBufferEventHandle != INVALID_HANDLE) { - svcCloseHandle(g_audoutBufferEventHandle); - g_audoutBufferEventHandle = INVALID_HANDLE; + if (atomicDecrement64(&g_refCnt) == 0) + { + if (g_audoutBufferEventHandle != INVALID_HANDLE) { + svcCloseHandle(g_audoutBufferEventHandle); + g_audoutBufferEventHandle = INVALID_HANDLE; + } + + g_sampleRate = 0; + g_channelCount = 0; + g_pcmFormat = PcmFormat_Invalid; + g_deviceState = AudioOutState_Stopped; + + serviceClose(&g_audoutIAudioOut); + serviceClose(&g_audoutSrv); } - - g_sampleRate = 0; - g_channelCount = 0; - g_pcmFormat = PcmFormat_Invalid; - g_deviceState = AudioOutState_Stopped; - - serviceClose(&g_audoutIAudioOut); - serviceClose(&g_audoutSrv); } u32 audoutGetSampleRate(void) { @@ -82,29 +89,33 @@ AudioOutState audoutGetDeviceState(void) { return g_deviceState; } -Result audoutPlayBuffer(AudioOutBuffer *source, AudioOutBuffer *released) { - // Try to push the supplied buffer to the audio output device - Result do_append = audoutAppendAudioOutBuffer(source); - - if (R_SUCCEEDED(do_append)) - { - // Wait on the buffer event handle - Result do_wait = svcWaitSynchronizationSingle(g_audoutBufferEventHandle, U64_MAX); +Result audoutWaitPlayFinish(AudioOutBuffer **released, u32* released_count, u64 timeout) { + // Wait on the buffer event handle + Result rc = svcWaitSynchronizationSingle(g_audoutBufferEventHandle, timeout); - if (R_SUCCEEDED(do_wait)) - { - svcResetSignal(g_audoutBufferEventHandle); - - u32 released_count = 0; - Result do_release = audoutGetReleasedAudioOutBuffer(released, &released_count); - - // Ensure that all buffers are released and return the last one only - while (R_SUCCEEDED(do_release) && (released_count > 0)) - do_release = audoutGetReleasedAudioOutBuffer(released, &released_count); - } + if (R_SUCCEEDED(rc)) + { + // Signal the buffer event handle right away + svcResetSignal(g_audoutBufferEventHandle); + + // Grab the released buffer + rc = audoutGetReleasedAudioOutBuffer(released, released_count); } - return do_append; + return rc; +} + +Result audoutPlayBuffer(AudioOutBuffer *source, AudioOutBuffer **released) { + Result rc = 0; + u32 released_count = 0; + + // Try to push the supplied buffer to the audio output device + rc = audoutAppendAudioOutBuffer(source); + + if (R_SUCCEEDED(rc)) + rc = audoutWaitPlayFinish(released, &released_count, U64_MAX); + + return rc; } Result audoutListAudioOuts(char *DeviceNames, u32 *DeviceNamesCount) { @@ -313,13 +324,13 @@ Result audoutAppendAudioOutBuffer(AudioOutBuffer *Buffer) { u64 tag; } *raw; - ipcAddSendBuffer(&c, Buffer, sizeof(AudioOutBuffer), 0); + ipcAddSendBuffer(&c, Buffer, sizeof(*Buffer), 0); raw = ipcPrepareHeader(&c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 3; - raw->tag = (u64)&Buffer; + raw->tag = (u64)Buffer; Result rc = serviceIpcDispatch(&g_audoutIAudioOut); @@ -372,7 +383,7 @@ static Result _audoutRegisterBufferEvent(Handle *BufferEvent) { return rc; } -Result audoutGetReleasedAudioOutBuffer(AudioOutBuffer *Buffer, u32 *ReleasedBuffersCount) { +Result audoutGetReleasedAudioOutBuffer(AudioOutBuffer **Buffer, u32 *ReleasedBuffersCount) { IpcCommand c; ipcInitialize(&c); @@ -381,7 +392,7 @@ Result audoutGetReleasedAudioOutBuffer(AudioOutBuffer *Buffer, u32 *ReleasedBuff u64 cmd_id; } *raw; - ipcAddRecvBuffer(&c, Buffer, sizeof(AudioOutBuffer), 0); + ipcAddRecvBuffer(&c, Buffer, sizeof(*Buffer), 0); raw = ipcPrepareHeader(&c, sizeof(*raw)); @@ -423,7 +434,7 @@ Result audoutContainsAudioOutBuffer(AudioOutBuffer *Buffer, bool *ContainsBuffer raw->magic = SFCI_MAGIC; raw->cmd_id = 6; - raw->tag = (u64)&Buffer; + raw->tag = (u64)Buffer; Result rc = serviceIpcDispatch(&g_audoutIAudioOut); diff --git a/nx/source/services/bsd.c b/nx/source/services/bsd.c index b0cfbd6f..f3a92a6f 100644 --- a/nx/source/services/bsd.c +++ b/nx/source/services/bsd.c @@ -1,22 +1,35 @@ // Copyright 2017 plutoo +#include +#include + +// Complete definition of struct timeout: +#include + +#include + +// For ioctls: +#include +#include +#include + #include "types.h" #include "result.h" -#include "ipc.h" -#include "services/bsd.h" -#include "services/sm.h" +#include "kernel/ipc.h" #include "kernel/shmem.h" #include "kernel/rwlock.h" +#include "services/bsd.h" +#include "services/sm.h" -#define EPIPE 32 +__thread Result g_bsdResult; +__thread int g_bsdErrno; static Service g_bsdSrv; static Service g_bsdMonitor; static u64 g_bsdClientPid = -1; -static int g_Errno = 0; static TransferMemory g_bsdTmem; -static const BsdConfig g_defaultBsdConfig = { +static const BsdInitConfig g_defaultBsdInitConfig = { .version = 1, .tcp_tx_buf_size = 0x8000, @@ -35,8 +48,7 @@ static const BsdConfig g_defaultBsdConfig = { Should the transfer memory be smaller than that, the BSD sockets service would only send ZeroWindow packets (for TCP), resulting in a transfer rate not exceeding 1 byte/s. */ -static size_t _bsdGetTransferMemSizeForConfig(const BsdConfig *config) -{ +static size_t _bsdGetTransferMemSizeForConfig(const BsdInitConfig *config) { u32 tcp_tx_buf_max_size = config->tcp_tx_buf_max_size != 0 ? config->tcp_tx_buf_max_size : config->tcp_tx_buf_size; u32 tcp_rx_buf_max_size = config->tcp_rx_buf_max_size != 0 ? config->tcp_rx_buf_max_size : config->tcp_rx_buf_size; u32 sum = tcp_tx_buf_max_size + tcp_rx_buf_max_size + config->udp_tx_buf_size + config->udp_rx_buf_size; @@ -45,7 +57,7 @@ static size_t _bsdGetTransferMemSizeForConfig(const BsdConfig *config) return (size_t)(config->sb_efficiency * sum); } -static Result _bsdRegisterClient(Service* srv, TransferMemory* tmem, const BsdConfig *config, u64* pid_out) { +static Result _bsdRegisterClient(Service* srv, TransferMemory* tmem, const BsdInitConfig *config, u64* pid_out) { IpcCommand c; ipcInitialize(&c); ipcSendPid(&c); @@ -54,10 +66,9 @@ static Result _bsdRegisterClient(Service* srv, TransferMemory* tmem, const BsdCo struct { u64 magic; u64 cmd_id; - BsdConfig config; + BsdInitConfig config; u64 pid_reserved; u64 tmem_sz; - u64 pad[2]; } *raw; raw = ipcPrepareHeader(&c, sizeof(*raw)); @@ -81,7 +92,8 @@ static Result _bsdRegisterClient(Service* srv, TransferMemory* tmem, const BsdCo } *resp = r.Raw; *pid_out = resp->pid; - rc = resp->result; + g_bsdResult = rc = resp->result; + g_bsdErrno = 0; } return rc; @@ -115,17 +127,113 @@ static Result _bsdStartMonitor(Service* srv, u64 pid) { u64 result; } *resp = r.Raw; - rc = resp->result; + g_bsdResult = rc = resp->result; + g_bsdErrno = 0; } return rc; } -const BsdConfig *bsdGetDefaultConfig(void) { - return &g_defaultBsdConfig; +typedef struct { + u64 magic; + u64 result; + int ret; + int errno_; +} BsdIpcResponseBase; + +static int _bsdDispatchBasicCommand(IpcCommand *c, IpcParsedCommand *rOut) { + Result rc = serviceIpcDispatch(&g_bsdSrv); + IpcParsedCommand r; + int ret = -1; + + if (R_SUCCEEDED(rc)) { + ipcParse(&r); + + BsdIpcResponseBase *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + ret = resp->ret; + g_bsdErrno = (ret < 0) ? resp->errno_ : 0; + } + } + + if (R_FAILED(rc)) + g_bsdErrno = -1; + + if(rOut != NULL) + *rOut = r; + + g_bsdResult = rc; + return ret; } -Result bsdInitialize(const BsdConfig *config) { +static int _bsdDispatchCommandWithOutAddrlen(IpcCommand *c, socklen_t *addrlen) { + IpcParsedCommand r; + int ret = _bsdDispatchBasicCommand(c, &r); + if(ret != -1 && addrlen != NULL) { + struct { + BsdIpcResponseBase bsd_resp; + socklen_t addrlen; + } *resp = r.Raw; + *addrlen = resp->addrlen; + } + return ret; +} + +static int _bsdNameGetterCommand(u32 cmd_id, int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + IpcCommand c; + ipcInitialize(&c); + + socklen_t maxaddrlen = addrlen == NULL ? 0 : *addrlen; + + ipcAddRecvBuffer(&c, addr, maxaddrlen, 0); + ipcAddRecvStatic(&c, addr, maxaddrlen, 0); + + struct { + u64 magic; + u64 cmd_id; + int sockfd; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = cmd_id; + raw->sockfd = sockfd; + + return _bsdDispatchCommandWithOutAddrlen(&c, addrlen); +} + +static int _bsdSocketCreationCommand(u32 cmd_id, int domain, int type, int protocol) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + int domain; + int type; + int protocol; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = cmd_id; + raw->domain = domain; + raw->type = type; + raw->protocol = protocol; + + return _bsdDispatchBasicCommand(&c, NULL); +} + +const BsdInitConfig *bsdGetDefaultInitConfig(void) { + return &g_defaultBsdInitConfig; +} + +Result bsdInitialize(const BsdInitConfig *config) { const char* bsd_srv = "bsd:s"; if(serviceIsActive(&g_bsdSrv) || serviceIsActive(&g_bsdMonitor)) @@ -164,70 +272,148 @@ void bsdExit(void) { tmemClose(&g_bsdTmem); } -int bsdGetErrno(void) { - return g_Errno; +int bsdSocket(int domain, int type, int protocol) { + return _bsdSocketCreationCommand(2, domain, type, protocol); } -int bsdSocket(int domain, int type, int protocol) { +int bsdSocketExempt(int domain, int type, int protocol) { + return _bsdSocketCreationCommand(3, domain, type, protocol); +} + +int bsdOpen(const char *pathname, int flags) { IpcCommand c; ipcInitialize(&c); + size_t pathlen = strlen(pathname) + 1; + ipcAddSendBuffer(&c, pathname, pathlen, 0); + ipcAddSendStatic(&c, pathname, pathlen, 0); + struct { u64 magic; u64 cmd_id; - u32 domain; - u32 type; - u32 protocol; - u32 pad[4]; + int flags; } *raw; raw = ipcPrepareHeader(&c, sizeof(*raw)); raw->magic = SFCI_MAGIC; - raw->cmd_id = 2; - raw->domain = domain; - raw->type = type; - raw->protocol = protocol; + raw->cmd_id = 4; + raw->flags = flags; - Result rc = serviceIpcDispatch(&g_bsdSrv); - int fd = -1; - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - u32 fd; - u32 errno; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - g_Errno = resp->errno; - fd = resp->fd; - } - } - - if (R_FAILED(rc)) { - g_Errno = EPIPE; - } - - return fd; + return _bsdDispatchBasicCommand(&c, NULL); } -int bsdRecv(int sockfd, void* buffer, size_t length, int flags) { + +int bsdSelect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { IpcCommand c; ipcInitialize(&c); - ipcAddRecvBuffer(&c, buffer, length, 0); - ipcAddRecvStatic(&c, buffer, length, 0); + + ipcAddSendBuffer(&c, readfds, readfds == NULL ? 0 : sizeof(fd_set), 0); + ipcAddSendStatic(&c, readfds, readfds == NULL ? 0 : sizeof(fd_set), 0); + ipcAddSendBuffer(&c, writefds, writefds == NULL ? 0 : sizeof(fd_set), 0); + ipcAddSendStatic(&c, writefds, writefds == NULL ? 0 : sizeof(fd_set), 0); + ipcAddSendBuffer(&c, exceptfds, exceptfds == NULL ? 0 : sizeof(fd_set), 0); + ipcAddSendStatic(&c, exceptfds, exceptfds == NULL ? 0 : sizeof(fd_set), 0); + + ipcAddRecvBuffer(&c, readfds, readfds == NULL ? 0 : sizeof(fd_set), 0); + ipcAddRecvStatic(&c, readfds, readfds == NULL ? 0 : sizeof(fd_set), 0); + ipcAddRecvBuffer(&c, writefds, writefds == NULL ? 0 : sizeof(fd_set), 0); + ipcAddRecvStatic(&c, writefds, writefds == NULL ? 0 : sizeof(fd_set), 0); + ipcAddRecvBuffer(&c, exceptfds, exceptfds == NULL ? 0 : sizeof(fd_set), 0); + ipcAddRecvStatic(&c, exceptfds, exceptfds == NULL ? 0 : sizeof(fd_set), 0); struct { u64 magic; u64 cmd_id; - u32 sockfd; - u32 flags; + int nfds; + struct timeval timeout; + bool nullTimeout; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 5; + raw->nfds = nfds; + if(!(raw->nullTimeout = timeout == NULL)) + raw->timeout = *timeout; + + return _bsdDispatchBasicCommand(&c, NULL); +} + +int bsdPoll(struct pollfd *fds, nfds_t nfds, int timeout) { + IpcCommand c; + ipcInitialize(&c); + + ipcAddSendBuffer(&c, fds, nfds * sizeof(struct pollfd), 0); + ipcAddSendStatic(&c, fds, nfds * sizeof(struct pollfd), 0); + + ipcAddRecvBuffer(&c, fds, nfds * sizeof(struct pollfd), 0); + ipcAddRecvStatic(&c, fds, nfds * sizeof(struct pollfd), 0); + + struct { + u64 magic; + u64 cmd_id; + nfds_t nfds; + int timeout; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 6; + raw->nfds = nfds; + raw->timeout = timeout; + + return _bsdDispatchBasicCommand(&c, NULL); +} + +int bsdSysctl(const int *name, unsigned int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen) { + IpcCommand c; + size_t inlen = oldlenp == NULL ? 0 : *oldlenp; + + ipcInitialize(&c); + + ipcAddSendBuffer(&c, name, 4 * namelen, 0); + ipcAddSendStatic(&c, name, 4 * namelen, 0); + ipcAddSendBuffer(&c, newp, newlen, 0); + ipcAddSendStatic(&c, newp, newlen, 0); + + ipcAddRecvBuffer(&c, oldp, inlen, 0); + ipcAddRecvStatic(&c, oldp, inlen, 0); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 7; + + IpcParsedCommand r; + int ret = _bsdDispatchBasicCommand(&c, &r); + if(ret != -1 && oldlenp != NULL) { + struct { + BsdIpcResponseBase bsd_resp; + size_t oldlenp; + } *resp = r.Raw; + *oldlenp = resp->oldlenp; + } + return ret; +} + +ssize_t bsdRecv(int sockfd, void *buf, size_t len, int flags) { + IpcCommand c; + ipcInitialize(&c); + ipcAddRecvBuffer(&c, buf, len, 0); + ipcAddRecvStatic(&c, buf, len, 0); + + struct { + u64 magic; + u64 cmd_id; + int sockfd; + int flags; } *raw; raw = ipcPrepareHeader(&c, sizeof(*raw)); @@ -237,46 +423,48 @@ int bsdRecv(int sockfd, void* buffer, size_t length, int flags) { raw->sockfd = sockfd; raw->flags = flags; - Result rc = serviceIpcDispatch(&g_bsdSrv); - int ret = -1; - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - u32 ret; - u32 errno; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - g_Errno = resp->errno; - ret = resp->ret; - } - } - - if (R_FAILED(rc)) { - g_Errno = rc; //EPIPE; - } - - return ret; + return _bsdDispatchBasicCommand(&c, NULL); } -int bsdSend(int sockfd, const void* buffer, size_t length, int flags) { +ssize_t bsdRecvFrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen){ IpcCommand c; + socklen_t inaddrlen = addrlen == NULL ? 0 : *addrlen; + ipcInitialize(&c); - ipcAddSendBuffer(&c, buffer, length, 0); - ipcAddSendStatic(&c, buffer, length, 0); + + ipcAddRecvBuffer(&c, buf, len, 0); + ipcAddRecvStatic(&c, buf, len, 0); + ipcAddRecvBuffer(&c, src_addr, inaddrlen, 0); + ipcAddRecvBuffer(&c, src_addr, inaddrlen, 0); struct { u64 magic; u64 cmd_id; - u32 sockfd; - u32 flags; + int sockfd; + int flags; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 9; + raw->sockfd = sockfd; + raw->flags = flags; + + return _bsdDispatchCommandWithOutAddrlen(&c, addrlen); +} + +ssize_t bsdSend(int sockfd, const void* buf, size_t len, int flags) { + IpcCommand c; + ipcInitialize(&c); + ipcAddSendBuffer(&c, buf, len, 0); + ipcAddSendStatic(&c, buf, len, 0); + + struct { + u64 magic; + u64 cmd_id; + int sockfd; + int flags; } *raw; raw = ipcPrepareHeader(&c, sizeof(*raw)); @@ -286,49 +474,23 @@ int bsdSend(int sockfd, const void* buffer, size_t length, int flags) { raw->sockfd = sockfd; raw->flags = flags; - Result rc = serviceIpcDispatch(&g_bsdSrv); - int ret = -1; - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - u32 ret; - u32 errno; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - g_Errno = resp->errno; - ret = resp->ret; - } - } - - if (R_FAILED(rc)) { - g_Errno = EPIPE; - } - - return ret; + return _bsdDispatchBasicCommand(&c, NULL); } -int bsdSendTo(int sockfd, const void* buffer, size_t length, int flags, const struct bsd_sockaddr_in *dest_addr, size_t dest_len) { +ssize_t bsdSendTo(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { IpcCommand c; ipcInitialize(&c); - ipcAddSendBuffer(&c, buffer, length, 0); - ipcAddSendStatic(&c, buffer, length, 0); + ipcAddSendBuffer(&c, buf, len, 0); + ipcAddSendStatic(&c, buf, len, 0); - ipcAddSendBuffer(&c, dest_addr, dest_len, 0); - ipcAddSendStatic(&c, dest_addr, dest_len, 0); + ipcAddSendBuffer(&c, dest_addr, addrlen, 1); + ipcAddSendStatic(&c, dest_addr, addrlen, 1); struct { u64 magic; u64 cmd_id; - u32 sockfd; - u32 flags; + int sockfd; + int flags; } *raw; raw = ipcPrepareHeader(&c, sizeof(*raw)); @@ -338,36 +500,14 @@ int bsdSendTo(int sockfd, const void* buffer, size_t length, int flags, const st raw->sockfd = sockfd; raw->flags = flags; - Result rc = serviceIpcDispatch(&g_bsdSrv); - int ret = -1; - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - u32 ret; - u32 errno; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - g_Errno = resp->errno; - ret = resp->ret; - } - } - - if (R_FAILED(rc)) { - g_Errno = EPIPE; - } - - return ret; + return _bsdDispatchBasicCommand(&c, NULL); } -int bsdConnect(int sockfd, const void* addr, u32 addrlen) { +int bsdAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + return _bsdNameGetterCommand(12, sockfd, addr, addrlen); +} + +int bsdBind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { IpcCommand c; ipcInitialize(&c); ipcAddSendBuffer(&c, addr, addrlen, 0); @@ -376,8 +516,28 @@ int bsdConnect(int sockfd, const void* addr, u32 addrlen) { struct { u64 magic; u64 cmd_id; - u32 sockfd; - u32 pad[4]; + int sockfd; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 13; + raw->sockfd = sockfd; + + return _bsdDispatchBasicCommand(&c, NULL); +} + +int bsdConnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + IpcCommand c; + ipcInitialize(&c); + ipcAddSendBuffer(&c, addr, addrlen, 0); + ipcAddSendStatic(&c, addr, addrlen, 0); + + struct { + u64 magic; + u64 cmd_id; + int sockfd; } *raw; raw = ipcPrepareHeader(&c, sizeof(*raw)); @@ -386,79 +546,43 @@ int bsdConnect(int sockfd, const void* addr, u32 addrlen) { raw->cmd_id = 14; raw->sockfd = sockfd; - Result rc = serviceIpcDispatch(&g_bsdSrv); - int fd = -1; - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - u32 fd; - u32 errno; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - g_Errno = resp->errno; - fd = resp->fd; - } - } - - if (R_FAILED(rc)) { - g_Errno = EPIPE; - } - - return fd; + return _bsdDispatchBasicCommand(&c, NULL); } -int bsdBind(int sockfd, const void* addr, u32 addrlen) { +int bsdGetPeerName(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + return _bsdNameGetterCommand(15, sockfd, addr, addrlen); +} + +int bsdGetSockName(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + return _bsdNameGetterCommand(16, sockfd, addr, addrlen); +} + +int bsdGetSockOpt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) { IpcCommand c; ipcInitialize(&c); - ipcAddSendBuffer(&c, addr, addrlen, 0); - ipcAddSendStatic(&c, addr, addrlen, 0); + + socklen_t inoptlen = optlen == NULL ? 0 : *optlen; + + ipcAddRecvBuffer(&c, optval, inoptlen, 0); + ipcAddRecvStatic(&c, optval, inoptlen, 0); struct { u64 magic; u64 cmd_id; - u32 pad[5]; + int sockfd; + int level; + int optname; } *raw; raw = ipcPrepareHeader(&c, sizeof(*raw)); raw->magic = SFCI_MAGIC; - raw->cmd_id = 13; + raw->cmd_id = 17; + raw->sockfd = sockfd; + raw->level = level; + raw->optname = optname; - Result rc = serviceIpcDispatch(&g_bsdSrv); - int ret = -1; - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - u32 ret; - u32 errno; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - g_Errno = resp->errno; - ret = resp->ret; - } - } - - if (R_FAILED(rc)) { - g_Errno = EPIPE; - } - - return ret; + return _bsdDispatchBasicCommand(&c, NULL); } int bsdListen(int sockfd, int backlog) { @@ -468,9 +592,8 @@ int bsdListen(int sockfd, int backlog) { struct { u64 magic; u64 cmd_id; - u32 sockfd; - u32 backlog; - u32 pad[4]; + int sockfd; + int backlog; } *raw; raw = ipcPrepareHeader(&c, sizeof(*raw)); @@ -480,48 +603,142 @@ int bsdListen(int sockfd, int backlog) { raw->sockfd = sockfd; raw->backlog = backlog; - Result rc = serviceIpcDispatch(&g_bsdSrv); - int ret = -1; + return _bsdDispatchBasicCommand(&c, NULL); +} - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); +int bsdIoctl(int fd, int request, void *data) { + IpcCommand c; - struct { - u64 magic; - u64 result; - u32 ret; - u32 errno; - } *resp = r.Raw; + const void *in1 = NULL, *in2 = NULL, *in3 = NULL, *in4 = NULL; + size_t in1sz = 0, in2sz = 0, in3sz = 0, in4sz = 0; - rc = resp->result; + void *out1 = NULL, *out2 = NULL, *out3 = NULL, *out4 = NULL; + size_t out1sz = 0, out2sz = 0, out3sz = 0, out4sz = 0; - if (R_SUCCEEDED(rc)) { - g_Errno = resp->errno; - ret = resp->ret; + int bufcount = 1; + + switch(request) { + case SIOCGIFCONF: { + struct ifconf *data_ = (struct ifconf *)data; + in1 = out1 = data; + in1sz = out1sz = sizeof(struct ifconf); + in2 = out2 = data_->ifc_req; + in2sz = out2sz = data_->ifc_len; + bufcount = 2; + break; + } + case SIOCGIFMEDIA: + case SIOCGIFXMEDIA: { + struct ifmediareq *data_ = (struct ifmediareq *)data; + in1 = out1 = data; + in1sz = out1sz = sizeof(struct ifmediareq); + in2 = out2 = data_->ifm_ulist; + in2sz = out2sz = 8 * data_->ifm_count; + bufcount = 2; + break; + } + // Generic ioctl + default: { + void *data_ = NULL; + if(request & IOC_INOUT) + data_ = data; + if(request & IOC_IN) { + in1 = data_; + in1sz = IOCPARM_LEN(request); + } + if(request & IOC_OUT) { + out1 = data_; + out1sz = IOCPARM_LEN(request); + } + break; } } - if (R_FAILED(rc)) { - g_Errno = EPIPE; - } - - return ret; -} - -int bsdSetSockOpt(int sockfd, int level, int option_name, const void *option_value, size_t option_size) { - IpcCommand c; ipcInitialize(&c); - ipcAddSendBuffer(&c, option_value, option_size, 0); - ipcAddSendStatic(&c, option_value, option_size, 0); + ipcAddSendBuffer(&c, in1, in1sz, 0); + ipcAddSendStatic(&c, in1, in1sz, 0); + ipcAddSendBuffer(&c, in2, in2sz, 0); + ipcAddSendStatic(&c, in2, in2sz, 0); + ipcAddSendBuffer(&c, in3, in3sz, 0); + ipcAddSendStatic(&c, in3, in3sz, 0); + ipcAddSendBuffer(&c, in4, in4sz, 0); + ipcAddSendStatic(&c, in4, in4sz, 0); + + ipcAddRecvBuffer(&c, out1, out1sz, 0); + ipcAddRecvStatic(&c, out1, out1sz, 0); + ipcAddRecvBuffer(&c, out2, out2sz, 0); + ipcAddRecvStatic(&c, out2, out2sz, 0); + ipcAddRecvBuffer(&c, out3, out3sz, 0); + ipcAddRecvStatic(&c, out3, out3sz, 0); + ipcAddRecvBuffer(&c, out4, out4sz, 0); + ipcAddRecvStatic(&c, out4, out4sz, 0); struct { u64 magic; u64 cmd_id; - u32 sockfd; - u32 level; - u32 option_name; + int fd; + int request; + int bufcount; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 19; + raw->fd = fd; + raw->request = request; + raw->bufcount = bufcount; + + return _bsdDispatchBasicCommand(&c, NULL); +} + +int bsdFcntl(int fd, int cmd, int flags) { + IpcCommand c; + + if(cmd != F_GETFL && cmd != F_SETFL) { + g_bsdResult = 0; + g_bsdErrno = EOPNOTSUPP; + return -1; + } + + if(cmd == F_GETFL) + flags = 0; + + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + int fd; + int cmd; + int flags; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 20; + raw->fd = fd; + raw->cmd = cmd; + raw->flags = flags; + + return _bsdDispatchBasicCommand(&c, NULL); +} + +int bsdSetSockOpt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) { + IpcCommand c; + ipcInitialize(&c); + + ipcAddSendBuffer(&c, optval, optlen, 0); + ipcAddSendStatic(&c, optval, optlen, 0); + + struct { + u64 magic; + u64 cmd_id; + int sockfd; + int level; + int optname; } *raw; raw = ipcPrepareHeader(&c, sizeof(*raw)); @@ -530,80 +747,129 @@ int bsdSetSockOpt(int sockfd, int level, int option_name, const void *option_val raw->cmd_id = 21; raw->sockfd = sockfd; raw->level = level; - raw->option_name = option_name; + raw->optname = optname; - Result rc = serviceIpcDispatch(&g_bsdSrv); - int ret = -1; - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - u32 ret; - u32 errno; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - g_Errno = resp->errno; - ret = resp->ret; - } - } - - if (R_FAILED(rc)) { - g_Errno = EPIPE; - } - - return ret; + return _bsdDispatchBasicCommand(&c, NULL); } -int bsdWrite(int sockfd, const void* buffer, size_t length) { +int bsdShutdown(int sockfd, int how) { IpcCommand c; ipcInitialize(&c); - ipcAddSendBuffer(&c, buffer, length, 0); - ipcAddSendStatic(&c, buffer, length, 0); struct { u64 magic; u64 cmd_id; - u32 sockfd; + int sockfd; + int how; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 22; + raw->sockfd = sockfd; + raw->how = how; + + return _bsdDispatchBasicCommand(&c, NULL); +} + +int bsdShutdownAllSockets(int how) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + int how; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 23; + raw->how = how; + + return _bsdDispatchBasicCommand(&c, NULL); +} + +ssize_t bsdWrite(int fd, const void *buf, size_t count) { + IpcCommand c; + ipcInitialize(&c); + ipcAddSendBuffer(&c, buf, count, 0); + ipcAddSendStatic(&c, buf, count, 0); + + struct { + u64 magic; + u64 cmd_id; + int fd; } *raw; raw = ipcPrepareHeader(&c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 24; - raw->sockfd = sockfd; + raw->fd = fd; - Result rc = serviceIpcDispatch(&g_bsdSrv); - int ret = -1; - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - u32 ret; - u32 errno; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - g_Errno = resp->errno; - ret = resp->ret; - } - } - - if (R_FAILED(rc)) { - g_Errno = EPIPE; - } - - return ret; + return _bsdDispatchBasicCommand(&c, NULL); +} + +ssize_t bsdRead(int fd, void *buf, size_t count) { + IpcCommand c; + ipcInitialize(&c); + ipcAddRecvBuffer(&c, buf, count, 0); + ipcAddRecvStatic(&c, buf, count, 0); + + struct { + u64 magic; + u64 cmd_id; + int fd; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 25; + raw->fd = fd; + + return _bsdDispatchBasicCommand(&c, NULL); +} + +int bsdClose(int fd) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + int fd; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 26; + raw->fd = fd; + + return _bsdDispatchBasicCommand(&c, NULL); +} + +int bsdDuplicateSocket(int sockfd) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + int sockfd; + u64 reserved; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 27; + raw->sockfd = sockfd; + raw->reserved = 0; + + return _bsdDispatchBasicCommand(&c, NULL); } diff --git a/nx/source/services/fatal.c b/nx/source/services/fatal.c index 99dbc0cc..43aad860 100644 --- a/nx/source/services/fatal.c +++ b/nx/source/services/fatal.c @@ -1,11 +1,11 @@ // Copyright 2017 plutoo #include "types.h" #include "result.h" -#include "ipc.h" -#include "services/fatal.h" -#include "services/sm.h" +#include "kernel/ipc.h" #include "kernel/detect.h" #include "kernel/svc.h" +#include "services/fatal.h" +#include "services/sm.h" void fatalSimple(Result err) { Result rc = 0; diff --git a/nx/source/services/fs.c b/nx/source/services/fs.c index 013a5779..22634b72 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -2,13 +2,18 @@ #include #include "types.h" #include "result.h" -#include "ipc.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" #include "services/fs.h" #include "services/sm.h" static Service g_fsSrv; +static u64 g_refCnt; + +Result fsInitialize(void) +{ + atomicIncrement64(&g_refCnt); -Result fsInitialize(void) { if (serviceIsActive(&g_fsSrv)) return 0; @@ -49,8 +54,10 @@ Result fsInitialize(void) { return rc; } -void fsExit(void) { - serviceClose(&g_fsSrv); +void fsExit(void) +{ + if (atomicDecrement64(&g_refCnt) == 0) + serviceClose(&g_fsSrv); } Service* fsGetServiceSession(void) { diff --git a/nx/source/services/hid.c b/nx/source/services/hid.c index cad32029..24d5e77c 100644 --- a/nx/source/services/hid.c +++ b/nx/source/services/hid.c @@ -1,15 +1,17 @@ #include #include "types.h" #include "result.h" -#include "ipc.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" +#include "kernel/shmem.h" +#include "kernel/rwlock.h" #include "services/applet.h" #include "services/hid.h" #include "services/sm.h" -#include "kernel/shmem.h" -#include "kernel/rwlock.h" static Service g_hidSrv; static Service g_hidIAppletResource; +static u64 g_refCnt; static SharedMemory g_hidSharedmem; static HidTouchScreenEntry g_touchEntry; @@ -32,10 +34,14 @@ static RwLock g_hidLock; static Result _hidCreateAppletResource(Service* srv, Service* srv_out, u64 AppletResourceUserId); static Result _hidGetSharedMemoryHandle(Service* srv, Handle* handle_out); +static Result _hidSetDualModeAll(void); + Result hidInitialize(void) { + atomicIncrement64(&g_refCnt); + if (serviceIsActive(&g_hidSrv)) - return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + return 0; Result rc; Handle sharedmem_handle; @@ -61,6 +67,9 @@ Result hidInitialize(void) rc = shmemMap(&g_hidSharedmem); } + if (R_SUCCEEDED(rc)) + rc = _hidSetDualModeAll(); + if (R_FAILED(rc)) hidExit(); @@ -70,9 +79,14 @@ Result hidInitialize(void) void hidExit(void) { - serviceClose(&g_hidIAppletResource); - serviceClose(&g_hidSrv); - shmemClose(&g_hidSharedmem); + if (atomicDecrement64(&g_refCnt) == 0) + { + _hidSetDualModeAll(); + + serviceClose(&g_hidIAppletResource); + serviceClose(&g_hidSrv); + shmemClose(&g_hidSharedmem); + } } void hidReset(void) @@ -151,7 +165,7 @@ void hidScanInput(void) { u64 latestTouchEntry = sharedMem->touchscreen.header.latestEntry; HidTouchScreenEntry *newTouchEntry = &sharedMem->touchscreen.entries[latestTouchEntry]; - if ((s64)(newTouchEntry->header.timestamp - g_touchTimestamp) > 0) { + if ((s64)(newTouchEntry->header.timestamp - g_touchTimestamp) >= 0) { memcpy(&g_touchEntry, newTouchEntry, sizeof(HidTouchScreenEntry)); g_touchTimestamp = newTouchEntry->header.timestamp; @@ -161,7 +175,7 @@ void hidScanInput(void) { u64 latestMouseEntry = sharedMem->mouse.header.latestEntry; HidMouseEntry *newMouseEntry = &sharedMem->mouse.entries[latestMouseEntry]; - if ((s64)(newMouseEntry->timestamp - g_mouseTimestamp) > 0) { + if ((s64)(newMouseEntry->timestamp - g_mouseTimestamp) >= 0) { memcpy(&g_mouseEntry, newMouseEntry, sizeof(HidMouseEntry)); g_mouseTimestamp = newMouseEntry->timestamp; @@ -172,7 +186,7 @@ void hidScanInput(void) { u64 latestKeyboardEntry = sharedMem->keyboard.header.latestEntry; HidKeyboardEntry *newKeyboardEntry = &sharedMem->keyboard.entries[latestKeyboardEntry]; - if ((s64)(newKeyboardEntry->timestamp - g_keyboardTimestamp) > 0) { + if ((s64)(newKeyboardEntry->timestamp - g_keyboardTimestamp) >= 0) { memcpy(&g_keyboardEntry, newKeyboardEntry, sizeof(HidKeyboardEntry)); g_keyboardTimestamp = newKeyboardEntry->timestamp; @@ -192,7 +206,7 @@ void hidScanInput(void) { HidControllerLayout *currentLayout = &sharedMem->controllers[i].layouts[g_controllerLayout[i]]; u64 latestControllerEntry = currentLayout->header.latestEntry; HidControllerInputEntry *newInputEntry = ¤tLayout->entries[latestControllerEntry]; - if ((s64)(newInputEntry->timestamp - g_controllerTimestamps[i]) > 0) { + if ((s64)(newInputEntry->timestamp - g_controllerTimestamps[i]) >= 0) { memcpy(&g_controllerEntries[i], newInputEntry, sizeof(HidControllerInputEntry)); g_controllerTimestamps[i] = newInputEntry->timestamp; @@ -356,6 +370,18 @@ void hidJoystickRead(JoystickPosition *pos, HidControllerID id, HidControllerJoy } } +static Result _hidSetDualModeAll(void) { + Result rc; + int i; + + for (i=0; i<8; i++) { + rc = hidSetNpadJoyAssignmentModeDual(i); + if (R_FAILED(rc)) break; + } + + return rc; +} + static Result _hidCreateAppletResource(Service* srv, Service* srv_out, u64 AppletResourceUserId) { IpcCommand c; ipcInitialize(&c); @@ -430,3 +456,319 @@ static Result _hidGetSharedMemoryHandle(Service* srv, Handle* handle_out) { return rc; } +Result hidSetNpadJoyAssignmentModeSingleByDefault(HidControllerID id) { + Result rc; + u64 AppletResourceUserId; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + return rc; + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 id; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 122; + raw->id = id; + raw->AppletResourceUserId = AppletResourceUserId; + + rc = serviceIpcDispatch(&g_hidSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result hidSetNpadJoyAssignmentModeDual(HidControllerID id) { + Result rc; + u64 AppletResourceUserId; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + return rc; + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 id; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 124; + raw->id = id; + raw->AppletResourceUserId = AppletResourceUserId; + + rc = serviceIpcDispatch(&g_hidSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +static Result _hidCreateActiveVibrationDeviceList(Service* srv_out) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 203; + + Result rc = serviceIpcDispatch(&g_hidSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + serviceCreate(srv_out, r.Handles[0]); + } + } + + return rc; +} + +static Result _hidActivateVibrationDevice(Service* srv, u32 VibrationDeviceHandle) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 VibrationDeviceHandle; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 0; + raw->VibrationDeviceHandle = VibrationDeviceHandle; + + Result rc = serviceIpcDispatch(srv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result hidSendVibrationValue(u32 *VibrationDeviceHandle, HidVibrationValue *VibrationValue) { + Result rc; + u64 AppletResourceUserId; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + return rc; + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 VibrationDeviceHandle; + HidVibrationValue VibrationValue; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 201; + raw->VibrationDeviceHandle = *VibrationDeviceHandle; + raw->AppletResourceUserId = AppletResourceUserId; + memcpy(&raw->VibrationValue, VibrationValue, sizeof(HidVibrationValue)); + + rc = serviceIpcDispatch(&g_hidSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result hidPermitVibration(bool flag) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u8 flag; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 204; + raw->flag = !!flag; + + Result rc = serviceIpcDispatch(&g_hidSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result hidIsVibrationPermitted(bool *flag) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 205; + + Result rc = serviceIpcDispatch(&g_hidSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u8 flag; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && flag) + *flag = resp->flag & 1; + } + + return rc; +} + +Result hidInitializeVibrationDevices(u32 *VibrationDeviceHandles, size_t total_handles, HidControllerID id, HidControllerLayoutType type) { + Result rc=0; + Service srv; + u32 tmp_type = type & 0xff; + size_t i; + + if (total_handles == 0 || total_handles > 2) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + + if (tmp_type < 5) { + if (tmp_type == 4) tmp_type |= 0x010000; + tmp_type+= 3; + } + else { + if (tmp_type == 5) tmp_type = 0x20; + if (tmp_type == 6) tmp_type = 0x21; + } + + //TODO: Is type correct? + VibrationDeviceHandles[0] = tmp_type | (id & 0xff)<<8; + + if (total_handles > 1) { + tmp_type &= 0xff; + if (tmp_type!=6 && tmp_type!=7) { + VibrationDeviceHandles[1] = VibrationDeviceHandles[0] | 0x010000; + } + else { + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + } + } + + for (i=0; i #include "types.h" #include "result.h" -#include "ipc.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" +#include "kernel/shmem.h" +#include "kernel/tmem.h" #include "services/applet.h" #include "services/irs.h" #include "services/hid.h" #include "services/sm.h" -#include "kernel/shmem.h" + +typedef struct { + bool initialized; + u32 IrCameraHandle; + TransferMemory transfermem; +} irsCameraEntry; static Service g_irsSrv; +static u64 g_refCnt; static SharedMemory g_irsSharedmem; -bool g_irsSensorActivated; +static bool g_irsSensorActivated; + +static irsCameraEntry g_irsCameras[8]; static Result _irsGetIrsensorSharedMemoryHandle(Handle* handle_out, u64 AppletResourceUserId); Result irsInitialize(void) { + atomicIncrement64(&g_refCnt); + if (serviceIsActive(&g_irsSrv)) - return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + return 0; Result rc; Handle sharedmem_handle; u64 AppletResourceUserId=0; + g_irsSensorActivated = 0; + memset(g_irsCameras, 0, sizeof(g_irsCameras)); + rc = appletGetAppletResourceUserId(&AppletResourceUserId); if (R_FAILED(rc)) return rc; @@ -48,10 +64,76 @@ Result irsInitialize(void) void irsExit(void) { - irsActivateIrsensor(0); + if (atomicDecrement64(&g_refCnt) == 0) + { + size_t entrycount = sizeof(g_irsCameras)/sizeof(irsCameraEntry); + irsCameraEntry *entry; - serviceClose(&g_irsSrv); - shmemClose(&g_irsSharedmem); + int i; + for(i=0; iinitialized) continue; + irsStopImageProcessor(entry->IrCameraHandle); + } + + irsActivateIrsensor(0); + + serviceClose(&g_irsSrv); + shmemClose(&g_irsSharedmem); + } +} + +static Result _irsCameraEntryAlloc(u32 IrCameraHandle, irsCameraEntry **out_entry) { + int i; + size_t entrycount = sizeof(g_irsCameras)/sizeof(irsCameraEntry); + int empty_entry = -1; + irsCameraEntry *entry; + + if (out_entry) *out_entry = NULL; + + for(i=0; iinitialized) { + if (entry->IrCameraHandle == IrCameraHandle) + return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + } + else if (empty_entry == -1) + empty_entry = i; + } + + if (empty_entry == -1) + return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + + entry = &g_irsCameras[empty_entry]; + + entry->initialized = 1; + entry->IrCameraHandle = IrCameraHandle; + + if (out_entry) *out_entry = entry; + + return 0; +} + +static Result _irsCameraEntryGet(u32 IrCameraHandle, irsCameraEntry **out_entry) { + int i; + size_t entrycount = sizeof(g_irsCameras)/sizeof(irsCameraEntry); + irsCameraEntry *entry; + *out_entry = NULL; + + for(i=0; iinitialized && entry->IrCameraHandle == IrCameraHandle) { + *out_entry = entry; + return 0; + } + } + + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); +} + +static void _irsCameraEntryFree(irsCameraEntry *entry) { + tmemClose(&entry->transfermem); + memset(entry, 0, sizeof(irsCameraEntry)); } Service* irsGetSessionService(void) { @@ -147,6 +229,207 @@ static Result _irsGetIrsensorSharedMemoryHandle(Handle* handle_out, u64 AppletRe return rc; } +static Result _irsStopImageProcessor(u32 IrCameraHandle, u64 AppletResourceUserId) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 IrCameraHandle; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 305; + raw->IrCameraHandle = IrCameraHandle; + raw->AppletResourceUserId = AppletResourceUserId; + + Result rc = serviceIpcDispatch(&g_irsSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result irsStopImageProcessor(u32 IrCameraHandle) { + Result rc=0; + u64 AppletResourceUserId=0; + irsCameraEntry *entry = NULL; + + if (!serviceIsActive(&g_irsSrv)) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + return rc; + + rc = _irsCameraEntryGet(IrCameraHandle, &entry); + if (R_FAILED(rc)) + return rc; + + if (entry->transfermem.handle == INVALID_HANDLE) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + rc = _irsStopImageProcessor(IrCameraHandle, AppletResourceUserId); + _irsCameraEntryFree(entry); + return rc; +} + +static Result _irsRunImageTransferProcessor(u32 IrCameraHandle, u64 AppletResourceUserId, irsPackedImageTransferProcessorConfig *config, Handle transfermem, u64 transfermem_size) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 IrCameraHandle; + u64 AppletResourceUserId; + irsPackedImageTransferProcessorConfig config; + u64 TransferMemory_size; + } *raw; + + ipcSendPid(&c); + ipcSendHandleCopy(&c, transfermem); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 308; + raw->IrCameraHandle = IrCameraHandle; + raw->AppletResourceUserId = AppletResourceUserId; + raw->TransferMemory_size = transfermem_size; + + memcpy(&raw->config, config, sizeof(raw->config)); + + Result rc = serviceIpcDispatch(&g_irsSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result irsRunImageTransferProcessor(u32 IrCameraHandle, irsImageTransferProcessorConfig *config, size_t size) { + Result rc=0; + u64 AppletResourceUserId=0; + irsCameraEntry *entry = NULL; + irsPackedImageTransferProcessorConfig packed_config; + + memset(&packed_config, 0, sizeof(packed_config)); + + packed_config.exposure = config->exposure; + packed_config.ir_leds = config->ir_leds; + packed_config.digital_gain = config->digital_gain; + packed_config.color_invert = config->color_invert; + packed_config.unk_constant = 0xa0003; + packed_config.sensor_res = config->sensor_res; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + return rc; + + rc = _irsCameraEntryAlloc(IrCameraHandle, &entry); + if (R_FAILED(rc)) + return rc; + + rc = tmemCreate(&entry->transfermem, size, Perm_None); + if (R_FAILED(rc)) return rc; + + rc = _irsRunImageTransferProcessor(IrCameraHandle, AppletResourceUserId, &packed_config, entry->transfermem.handle, size); + + if (R_FAILED(rc)) _irsCameraEntryFree(entry); + + return rc; +} + +static Result _irsGetImageTransferProcessorState(u32 IrCameraHandle, u64 AppletResourceUserId, void* buffer, size_t size, irsImageTransferProcessorState *state) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 IrCameraHandle; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + ipcAddRecvBuffer(&c, buffer, size, 0); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 309; + raw->IrCameraHandle = IrCameraHandle; + raw->AppletResourceUserId = AppletResourceUserId; + + Result rc = serviceIpcDispatch(&g_irsSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + irsImageTransferProcessorState state; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && state) + memcpy(state, &resp->state, sizeof(irsImageTransferProcessorState)); + } + + return rc; +} + +Result irsGetImageTransferProcessorState(u32 IrCameraHandle, void* buffer, size_t size, irsImageTransferProcessorState *state) { + Result rc=0; + u64 AppletResourceUserId=0; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + return rc; + + rc = _irsGetImageTransferProcessorState(IrCameraHandle, AppletResourceUserId, buffer, size, state); + return rc; +} + +void irsGetDefaultImageTransferProcessorConfig(irsImageTransferProcessorConfig *config) { + memset(config, 0, sizeof(irsImageTransferProcessorConfig)); + + config->exposure = 300000; + config->ir_leds = 0; + config->digital_gain = 8; + config->color_invert = 0; + config->sensor_res = 0; +} + Result irsGetIrCameraHandle(u32 *IrCameraHandle, HidControllerID id) { IpcCommand c; ipcInitialize(&c); @@ -185,3 +468,52 @@ Result irsGetIrCameraHandle(u32 *IrCameraHandle, HidControllerID id) { return rc; } +static Result _irsSuspendImageProcessor(u32 IrCameraHandle, u64 AppletResourceUserId) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 IrCameraHandle; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 313; + raw->IrCameraHandle = IrCameraHandle; + raw->AppletResourceUserId = AppletResourceUserId; + + Result rc = serviceIpcDispatch(&g_irsSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result irsSuspendImageProcessor(u32 IrCameraHandle) { + Result rc=0; + u64 AppletResourceUserId=0; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + return rc; + + rc = _irsSuspendImageProcessor(IrCameraHandle, AppletResourceUserId); + return rc; +} + diff --git a/nx/source/services/nv.c b/nx/source/services/nv.c index 6c003dd9..a056ecea 100644 --- a/nx/source/services/nv.c +++ b/nx/source/services/nv.c @@ -1,7 +1,7 @@ #include #include "types.h" #include "result.h" -#include "ipc.h" +#include "kernel/ipc.h" #include "services/applet.h" #include "nvidia/ioctl.h" #include "services/nv.h" @@ -18,7 +18,7 @@ static Result _nvSetClientPID(u64 AppletResourceUserId); Result nvInitialize(nvServiceType servicetype, size_t transfermem_size) { - if(g_nvServiceType!=-1) + if (g_nvServiceType != -1) return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); Result rc = 0; @@ -70,7 +70,7 @@ Result nvInitialize(nvServiceType servicetype, size_t transfermem_size) void nvExit(void) { - if(g_nvServiceType == -1) + if (g_nvServiceType == -1) return; g_nvServiceType = -1; diff --git a/nx/source/services/pm.c b/nx/source/services/pm.c index fe61ad40..073a6802 100644 --- a/nx/source/services/pm.c +++ b/nx/source/services/pm.c @@ -1,16 +1,31 @@ // Copyright 2017 plutoo #include "types.h" #include "result.h" -#include "ipc.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" #include "services/pm.h" #include "services/sm.h" static Service g_pmdmntSrv; +static u64 g_refCnt; + +Result pmdmntInitialize(void) +{ + atomicIncrement64(&g_refCnt); + + if (serviceIsActive(&g_pmdmntSrv)) + return 0; -Result pmdmntInitialize(void) { return smGetService(&g_pmdmntSrv, "pm:dmnt"); } +void pmdmntExit(void) +{ + if (atomicDecrement64(&g_refCnt) == 0) { + serviceClose(&g_pmdmntSrv); + } +} + Result pmdmntStartProcess(u64 pid) { IpcCommand c; ipcInitialize(&c); diff --git a/nx/source/services/set.c b/nx/source/services/set.c index ff207aed..ae66fad0 100644 --- a/nx/source/services/set.c +++ b/nx/source/services/set.c @@ -7,7 +7,8 @@ */ #include "types.h" #include "result.h" -#include "ipc.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" #include "kernel/detect.h" #include "services/set.h" #include "services/sm.h" @@ -15,6 +16,8 @@ static Service g_setSrv; static Service g_setsysSrv; +static u64 g_refCnt; +static u64 g_refCntSys; static bool g_setLanguageCodesInitialized; static u64 g_setLanguageCodes[0x40]; @@ -24,8 +27,10 @@ static Result _setMakeLanguageCode(s32 Language, u64 *LanguageCode); Result setInitialize(void) { + atomicIncrement64(&g_refCnt); + if (serviceIsActive(&g_setSrv)) - return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + return 0; g_setLanguageCodesInitialized = 0; @@ -34,11 +39,15 @@ Result setInitialize(void) void setExit(void) { - serviceClose(&g_setSrv); + if (atomicDecrement64(&g_refCnt) == 0) { + serviceClose(&g_setSrv); + } } Result setsysInitialize(void) { + atomicIncrement64(&g_refCntSys); + if (serviceIsActive(&g_setsysSrv)) return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); @@ -47,7 +56,9 @@ Result setsysInitialize(void) void setsysExit(void) { - serviceClose(&g_setsysSrv); + if (atomicDecrement64(&g_refCntSys) == 0) { + serviceClose(&g_setsysSrv); + } } static Result setInitializeLanguageCodesCache(void) { diff --git a/nx/source/services/sfdnsres.c b/nx/source/services/sfdnsres.c new file mode 100644 index 00000000..63924862 --- /dev/null +++ b/nx/source/services/sfdnsres.c @@ -0,0 +1,274 @@ +#include "types.h" +#include "result.h" +#include "kernel/ipc.h" +#include "services/sm.h" +#include "services/sfdnsres.h" + +#include + +static Result _sfdnsresDispatchCommand(IpcParsedCommand *r, IpcCommand *c, const void *raw, size_t raw_size) { + Service sfdnsres; + + Result rc = smGetService(&sfdnsres, "sfdnsres"); + if(R_FAILED(rc)) goto cleanup; + + memcpy(ipcPrepareHeader(c, raw_size), raw, raw_size); + + rc = serviceIpcDispatch(&sfdnsres); + if(R_FAILED(rc)) goto cleanup; + + ipcParse(r); + +cleanup: + serviceClose(&sfdnsres); + return rc; +} + +static Result _sfdnsresDispatchDnsRequest(IpcCommand *c, SfdnsresRequestResults *ret, const void *raw, size_t raw_size, bool has_serialized_data_out) { + Result rc; + IpcParsedCommand r; + ipcSendPid(c); + + rc = _sfdnsresDispatchCommand(&r, c, &raw, sizeof(raw)); + if(R_FAILED(rc)) return rc; + + struct { + u64 magic; + u64 result; + int ret; + int errno_; + int out_serialized_size; // OOB if !has_serialized_data + } *resp = r.Raw; + + rc = resp->result; + if(R_FAILED(rc)) return rc; + + ret->ret = resp->ret; + ret->errno_ = resp->errno_; + ret->out_serialized_size = has_serialized_data_out ? resp->out_serialized_size : 0; + + return rc; +} + +static Result _sfdnsresDnsRequestCommand(IpcCommand *c, u64 cmd_id, SfdnsresRequestResults *ret, const SfdnsresConfig *config, bool has_serialized_data_out, int *arg) { + struct { + u64 magic; + u64 cmd_id; + int arg; + int timeout; + u64 pid_placeholder; + } raw; + + raw.magic = SFCI_MAGIC; + raw.cmd_id = cmd_id; + raw.arg = arg == NULL ? (config->bypass_nsd ? 0 : 1) : *arg; + raw.timeout = config->timeout; + raw.pid_placeholder = 0; + + return _sfdnsresDispatchDnsRequest(c, ret, &raw, sizeof(raw), has_serialized_data_out); +} + +static Result _sfdnsresErrorStringGetterCommand(u64 cmd_id, int err, char *str, size_t str_size) { + IpcCommand c; + Result rc; + IpcParsedCommand r; + + ipcInitialize(&c); + ipcAddRecvBuffer(&c, str, str_size, 0); + + struct { + u64 magic; + u64 cmd_id; + int err; + } raw; + + raw.magic = SFCI_MAGIC; + raw.cmd_id = cmd_id; + raw.err = err; + + rc = _sfdnsresDispatchCommand(&r, &c, &raw, sizeof(raw)); + if(R_FAILED(rc)) return rc; + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + return rc; +} + +Result sfdnsresGetHostByName(SfdnsresRequestResults *ret, const SfdnsresConfig *config, void *out_he_serialized, const char *name) { + IpcCommand c; + ipcInitialize(&c); + ipcAddSendBuffer(&c, name, name == NULL ? 0 : strlen(name) + 1, 0); + ipcAddRecvBuffer(&c, out_he_serialized, config->serialized_out_hostent_max_size, 0); + + return _sfdnsresDnsRequestCommand(&c, 2, ret, config, true, NULL); +} + +Result sfdnsresGetHostByAddr(SfdnsresRequestResults *ret, const SfdnsresConfig *config, void *out_he_serialized, const void *addr, socklen_t len, int type) { + IpcCommand c; + struct { + u64 magic; + u64 cmd_id; + socklen_t len; // wtf nintendo + int type; + int timeout; + u64 pid_placeholder; + } raw; + + ipcInitialize(&c); + ipcAddSendBuffer(&c, addr, addr == NULL ? 0 : len, 0); + ipcAddRecvBuffer(&c, out_he_serialized, config->serialized_out_hostent_max_size, 0); + + raw.magic = SFCI_MAGIC; + raw.cmd_id = 3; + raw.len = len; + raw.type = type; + raw.timeout = config->timeout; + raw.pid_placeholder = 0; + + return _sfdnsresDispatchDnsRequest(&c, ret, &raw, sizeof(raw), true); +} + +Result sfdnsresGetHostStringError(int err, char *str, size_t str_size) { + return _sfdnsresErrorStringGetterCommand(4, err, str, str_size); +} + +Result sfdnsresGetGaiStringError(int err, char *str, size_t str_size) { + return _sfdnsresErrorStringGetterCommand(5, err, str, str_size); +} + +Result sfdnsresGetAddrInfo(SfdnsresRequestResults *ret, const SfdnsresConfig *config, const char *node, const char *service, + const void *hints_serialized, size_t hints_serialized_size, void *res_serialized) { + IpcCommand c; + size_t node_size = node == NULL ? 0 : strlen(node) + 1; + size_t service_size = service == NULL ? 0 : strlen(service) + 1; + hints_serialized_size = hints_serialized == NULL ? 0 : hints_serialized_size; + + ipcInitialize(&c); + ipcAddSendBuffer(&c, node, node_size, 0); + ipcAddSendBuffer(&c, service, service_size, 0); + ipcAddSendBuffer(&c, hints_serialized, hints_serialized_size, 0); + + ipcAddRecvBuffer(&c, res_serialized, config->serialized_out_hostent_max_size, 0); + + return _sfdnsresDnsRequestCommand(&c, 6, ret, config, true, NULL); +} + +Result sfdnsresGetNameInfo(SfdnsresRequestResults *ret, const SfdnsresConfig *config, + const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, + char *serv, size_t servlen, int flags) { + IpcCommand c; + + salen = sa == NULL ? 0 : salen; + hostlen = host == NULL ? 0 : hostlen; + servlen = serv == NULL ? 0 : servlen; + + ipcInitialize(&c); + ipcAddSendBuffer(&c, sa, salen, 0); + + ipcAddRecvBuffer(&c, host, hostlen, 0); + ipcAddRecvBuffer(&c, serv, servlen, 0); + + return _sfdnsresDnsRequestCommand(&c, 7, ret, config, false, &flags); +} + +Result sfdnsresRequestCancelHandle(u32 *out_handle) { + Result rc; + IpcCommand c; + IpcParsedCommand r; + struct { + u64 magic; + u64 cmd_id; + u64 pid_placeholder; + } raw; + + ipcInitialize(&c); + ipcSendPid(&c); + + raw.magic = SFCI_MAGIC; + raw.cmd_id = 8; + raw.pid_placeholder = 0; + + rc = _sfdnsresDispatchCommand(&r, &c, &raw, sizeof(raw)); + if(R_FAILED(rc)) return rc; + + struct { + u64 magic; + u64 result; + u32 handle; + } *resp = r.Raw; + + rc = resp->result; + if(R_FAILED(rc)) return rc; + + *out_handle = resp->handle; + + return rc; +} + +/// Bug: always sets errno ? +Result sfdnsresCancelSocketCall(SfdnsresRequestResults *ret, u32 handle) { + IpcCommand c; + struct { + u64 magic; + u64 cmd_id; + u32 handle; + u64 pid_placeholder; + } raw; + + ipcInitialize(&c); + + raw.magic = SFCI_MAGIC; + raw.cmd_id = 9; + raw.handle = handle; + raw.pid_placeholder = 0; + + return _sfdnsresDispatchDnsRequest(&c, ret, &raw, sizeof(raw), false); +} + +/// Bug: always sets errno ? +Result sfdnsresCancelAllSocketCalls(SfdnsresRequestResults *ret) { + IpcCommand c; + struct { + u64 magic; + u64 cmd_id; + u64 pid_placeholder; + } raw; + + ipcInitialize(&c); + + raw.magic = SFCI_MAGIC; + raw.cmd_id = 10; + raw.pid_placeholder = 0; + + return _sfdnsresDispatchDnsRequest(&c, ret, &raw, sizeof(raw), false); +} + +Result sfdnsresClearDnsIpServerAddressArray(void) { + Result rc; + IpcCommand c; + IpcParsedCommand r; + struct { + u64 magic; + u64 cmd_id; + } raw; + + ipcInitialize(&c); + + raw.magic = SFCI_MAGIC; + raw.cmd_id = 11; + + rc = _sfdnsresDispatchCommand(&r, &c, &raw, sizeof(raw)); + if(R_FAILED(rc)) return rc; + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + return rc; +} diff --git a/nx/source/services/sm.c b/nx/source/services/sm.c index c232d968..43c71ca1 100644 --- a/nx/source/services/sm.c +++ b/nx/source/services/sm.c @@ -1,11 +1,13 @@ // Copyright 2017 plutoo #include "types.h" #include "result.h" -#include "ipc.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" #include "services/fatal.h" #include "services/sm.h" static Handle g_smHandle = INVALID_HANDLE; +static u64 g_refCnt; #define MAX_OVERRIDES 32 @@ -48,6 +50,8 @@ bool smHasInitialized(void) { Result smInitialize(void) { + atomicIncrement64(&g_refCnt); + if (smHasInitialized()) return 0; @@ -93,9 +97,12 @@ Result smInitialize(void) return rc; } -void smExit(void) { - svcCloseHandle(g_smHandle); - g_smHandle = INVALID_HANDLE; +void smExit(void) +{ + if (atomicDecrement64(&g_refCnt) == 0) { + svcCloseHandle(g_smHandle); + g_smHandle = INVALID_HANDLE; + } } u64 smEncodeName(const char* name) diff --git a/nx/source/services/time.c b/nx/source/services/time.c index 67cc89c0..e710e993 100644 --- a/nx/source/services/time.c +++ b/nx/source/services/time.c @@ -1,7 +1,8 @@ #include #include "types.h" #include "result.h" -#include "ipc.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" #include "services/time.h" #include "services/sm.h" @@ -10,13 +11,16 @@ static Service g_timeUserSystemClock; static Service g_timeNetworkSystemClock; static Service g_timeTimeZoneService; static Service g_timeLocalSystemClock; +static u64 g_refCnt; static Result _timeGetSession(Service* srv_out, u64 cmd_id); Result timeInitialize(void) { + atomicIncrement64(&g_refCnt); + if (serviceIsActive(&g_timeSrv)) - return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + return 0; Result rc; @@ -46,14 +50,14 @@ Result timeInitialize(void) void timeExit(void) { - if (!serviceIsActive(&g_timeSrv)) - return; - - serviceClose(&g_timeLocalSystemClock); - serviceClose(&g_timeTimeZoneService); - serviceClose(&g_timeNetworkSystemClock); - serviceClose(&g_timeUserSystemClock); - serviceClose(&g_timeSrv); + if (atomicDecrement64(&g_refCnt) == 0) + { + serviceClose(&g_timeLocalSystemClock); + serviceClose(&g_timeTimeZoneService); + serviceClose(&g_timeNetworkSystemClock); + serviceClose(&g_timeUserSystemClock); + serviceClose(&g_timeSrv); + } } Service* timeGetSessionService(void) { diff --git a/nx/source/services/usb.c b/nx/source/services/usb.c index 01f7099b..41050780 100644 --- a/nx/source/services/usb.c +++ b/nx/source/services/usb.c @@ -1,8 +1,8 @@ #include #include "types.h" #include "result.h" -#include "ipc.h" #include "arm/cache.h" +#include "kernel/ipc.h" #include "kernel/detect.h" #include "services/usb.h" #include "services/sm.h" @@ -25,7 +25,8 @@ static Result _usbDsSetVidPidBcd(const usbDsDeviceInfo* deviceinfo); static Result _usbDsGetSession(Service* srv, Service* srv_out, u64 cmd_id, const void* buf0, size_t buf0size, const void* buf1, size_t buf1size); -Result usbDsInitialize(UsbComplexId complexId, const usbDsDeviceInfo* deviceinfo) { +Result usbDsInitialize(UsbComplexId complexId, const usbDsDeviceInfo* deviceinfo) +{ if (serviceIsActive(&g_usbDsSrv)) return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); diff --git a/nx/source/services/vi.c b/nx/source/services/vi.c index 6802c946..0a6a67c1 100644 --- a/nx/source/services/vi.c +++ b/nx/source/services/vi.c @@ -1,9 +1,9 @@ #include #include "types.h" #include "result.h" -#include "ipc.h" #include "services/applet.h" #include "services/vi.h" +#include "kernel/ipc.h" #include "kernel/detect.h" static Service g_viSrv;