mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Add networking stack.
This change adds all the kernel parts of a network stack. The network stack is partial but implements many of the important parts. Add if(4) network interface abstraction. Network interfaces are registered in a global list that can be iterated and each assigned an unique integer identifier. Add reference counted packets with a cache that recycles recent packets. Add support for lo(4) loopback and ether(4) ethernet network interfaces. The /dev/lo0 loopback device is created automatically on boot. Add arp(4) address resolution protocol driver for translation of inet(4) network layer addresses into ether(4) link layer addresses. arp(4) entries are cached and evicted from the cache when needed or when the entry has not been used for a while. The cache is limited to 256 entries for now. Add ip(4) internet protocol version 4 support. IP fragmentation and options are not implemented yet. Add tcp(4) transmission control protocol sockets for a reliable transport layer protocol that provides a reliable byte stream connection between two hosts. The implementation is incomplete and does not yet implement out of band data, options, and high performance extensions. Add udp(4) user datagram protocol sockets for a connectionless transport layer that provides best-effort delivery of datagrams. Add ping(4) sockets for a best-effort delivery of echo datagrams. Change type of sa_family_t from unsigned short to uint16_t. Add --disable-network-drivers to the kernel(7) options and expose it with a bootloader menu. tix-iso-bootconfig can set this option by default. Import CRC32 code from libz for the Ethernet checksum. This is a compatible ABI change that adds features to socket(2) (AF_INET, IPPROTO_TCP, IPPROTO_UDP, IPPROTO_PING), the ioctls for if(4), socket options, and the lo0 loopback interface. This commit is based on work by Meisaka Yukara contributed as the commit bbf7f1e8a5238a2bd1fe8eb1d2cc5c9c2421e2c4. Almost no lines of this work remains in this final commit as it has been rewritten or refactored away over the years, see the individual file headers for which files contain remnants of this work. Co-authored-by: Meisaka Yukara <Meisaka.Yukara@gmail.com>
This commit is contained in:
parent
3154492dcf
commit
2ef6804ead
63 changed files with 11172 additions and 69 deletions
2
Makefile
2
Makefile
|
@ -222,7 +222,7 @@ sysroot-system: sysroot-fsh sysroot-base-headers
|
|||
echo 'ID=sortix' && \
|
||||
echo 'VERSION_ID="$(VERSION)"' && \
|
||||
echo 'PRETTY_NAME="Sortix $(VERSION)"' && \
|
||||
echo 'SORTIX_ABI=1.2' && \
|
||||
echo 'SORTIX_ABI=1.3' && \
|
||||
true) > "$(SYSROOT)/etc/sortix-release"
|
||||
echo /etc/sortix-release >> "$(SYSROOT)/tix/manifest/system"
|
||||
ln -sf sortix-release "$(SYSROOT)/etc/os-release"
|
||||
|
|
4
README
4
README
|
@ -11,8 +11,8 @@ tinkering.
|
|||
It has been in development since 2011 by a single developer and contributors.
|
||||
Though the system is stable and capable right now, it is still early in
|
||||
development, and a number of crucial features haven't been made yet. Releases
|
||||
are made yearly and future releases will add features such as networking, SMP,
|
||||
and USB that were skipped in favor of becoming self-hosting now.
|
||||
are made yearly and future releases will add features such as SMP, and USB that
|
||||
were skipped in favor of becoming self-hosting now.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
|
|
@ -185,6 +185,7 @@ else
|
|||
no_random_seed=--no-random-seed
|
||||
fi
|
||||
set enable_src=true
|
||||
set enable_network_drivers=
|
||||
|
||||
export version
|
||||
export machine
|
||||
|
@ -194,6 +195,7 @@ export timeout
|
|||
export default
|
||||
export no_random_seed
|
||||
export enable_src
|
||||
export enable_network_drivers
|
||||
EOF
|
||||
|
||||
if [ -n "$ports" ]; then
|
||||
|
@ -280,7 +282,7 @@ esac
|
|||
cat << EOF
|
||||
hook_kernel_pre
|
||||
echo -n "Loading /$kernel ($(human_size $kernel)) ... "
|
||||
multiboot /$kernel \$no_random_seed "\$@"
|
||||
multiboot /$kernel \$no_random_seed \$enable_network_drivers "\$@"
|
||||
echo done
|
||||
hook_kernel_post
|
||||
if [ \$no_random_seed != --no-random-seed ]; then
|
||||
|
@ -418,6 +420,18 @@ else
|
|||
}
|
||||
fi
|
||||
|
||||
if [ "\$enable_network_drivers" = --disable-network-drivers ]; then
|
||||
menuentry "Enable networking drivers" {
|
||||
enable_network_drivers=
|
||||
configfile /boot/grub/advanced.cfg
|
||||
}
|
||||
else
|
||||
menuentry "Disable networking drivers" {
|
||||
enable_network_drivers=--disable-network-drivers
|
||||
configfile /boot/grub/advanced.cfg
|
||||
}
|
||||
fi
|
||||
|
||||
menuentry "Select binary packages..." {
|
||||
configfile /boot/grub/tix.cfg
|
||||
}
|
||||
|
|
|
@ -75,7 +75,8 @@ Delete a resolver:
|
|||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr getdnsconfig 2 ,
|
||||
.Xr setdnsconfig 2
|
||||
.Xr setdnsconfig 2 ,
|
||||
.Xr inet 4
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
originally appeared in Sortix 1.1.
|
||||
|
|
|
@ -82,6 +82,7 @@ alarm.o \
|
|||
clock.o \
|
||||
com.o \
|
||||
copy.o \
|
||||
crc32.o \
|
||||
descriptor.o \
|
||||
disk/ahci/ahci.o \
|
||||
disk/ahci/hba.o \
|
||||
|
@ -124,8 +125,17 @@ logterminal.o \
|
|||
memorymanagement.o \
|
||||
mouse/ps2.o \
|
||||
mtable.o \
|
||||
net/arp.o \
|
||||
net/ether.o \
|
||||
net/fs.o \
|
||||
net/if.o \
|
||||
net/ip.o \
|
||||
net/lo/lo.o \
|
||||
net/packet.o \
|
||||
net/ping.o \
|
||||
net/socket.o \
|
||||
net/tcp.o \
|
||||
net/udp.o \
|
||||
op-new.o \
|
||||
panic.o \
|
||||
partition.o \
|
||||
|
|
499
kernel/crc32.cpp
Normal file
499
kernel/crc32.cpp
Normal file
|
@ -0,0 +1,499 @@
|
|||
/*
|
||||
* Copyright (c) 1995-2006, 2010, 2011, 2012 Mark Adler.
|
||||
* Copyright (c) 2015 Josiah Worcester.
|
||||
* Copyright (c) 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Jean-loup Gailly Mark Adler
|
||||
* jloup@gzip.org madler@alumni.caltech.edu
|
||||
*
|
||||
* This file is based on zlib work by Mark Adler, forked into Sortix libz by
|
||||
* Jonas 'Sortie' Termansen, improved by Josiah Worcester, then adapted for the
|
||||
* Sortix kernel by Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* crc32.cpp
|
||||
* CRC32 checksum.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Sortix {
|
||||
|
||||
static const uint32_t crc_table[8][256] =
|
||||
{
|
||||
{
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
|
||||
0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
|
||||
0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
|
||||
0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
|
||||
0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
|
||||
0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
|
||||
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
|
||||
0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
|
||||
0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
|
||||
0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
|
||||
0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
|
||||
0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
|
||||
0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
|
||||
0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
|
||||
0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
|
||||
0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
|
||||
0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
|
||||
0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
|
||||
0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
|
||||
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
|
||||
0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
|
||||
0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
|
||||
0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
|
||||
0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
|
||||
0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
|
||||
0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
|
||||
0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
|
||||
0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
|
||||
0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
|
||||
0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
|
||||
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
|
||||
0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
|
||||
0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
|
||||
0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
|
||||
0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
|
||||
0x2d02ef8d
|
||||
},
|
||||
{
|
||||
0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504,
|
||||
0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49,
|
||||
0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e,
|
||||
0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,
|
||||
0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859,
|
||||
0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c,
|
||||
0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620,
|
||||
0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,
|
||||
0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae,
|
||||
0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2,
|
||||
0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175,
|
||||
0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,
|
||||
0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05,
|
||||
0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40,
|
||||
0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f,
|
||||
0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
|
||||
0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850,
|
||||
0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d,
|
||||
0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da,
|
||||
0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,
|
||||
0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af,
|
||||
0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea,
|
||||
0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74,
|
||||
0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,
|
||||
0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa,
|
||||
0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a,
|
||||
0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd,
|
||||
0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,
|
||||
0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a,
|
||||
0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f,
|
||||
0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290,
|
||||
0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
|
||||
0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed,
|
||||
0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0,
|
||||
0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167,
|
||||
0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,
|
||||
0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0,
|
||||
0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5,
|
||||
0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc,
|
||||
0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,
|
||||
0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842,
|
||||
0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e,
|
||||
0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299,
|
||||
0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,
|
||||
0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec,
|
||||
0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9,
|
||||
0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66,
|
||||
0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
|
||||
0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9,
|
||||
0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4,
|
||||
0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33,
|
||||
0x9324fd72
|
||||
},
|
||||
{
|
||||
0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc,
|
||||
0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f,
|
||||
0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a,
|
||||
0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,
|
||||
0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8,
|
||||
0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023,
|
||||
0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e,
|
||||
0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,
|
||||
0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84,
|
||||
0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7,
|
||||
0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922,
|
||||
0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,
|
||||
0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0,
|
||||
0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b,
|
||||
0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816,
|
||||
0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
|
||||
0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c,
|
||||
0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f,
|
||||
0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba,
|
||||
0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,
|
||||
0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98,
|
||||
0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873,
|
||||
0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e,
|
||||
0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,
|
||||
0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134,
|
||||
0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7,
|
||||
0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732,
|
||||
0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,
|
||||
0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0,
|
||||
0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b,
|
||||
0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26,
|
||||
0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
|
||||
0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc,
|
||||
0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef,
|
||||
0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a,
|
||||
0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,
|
||||
0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8,
|
||||
0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43,
|
||||
0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e,
|
||||
0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,
|
||||
0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24,
|
||||
0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07,
|
||||
0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982,
|
||||
0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,
|
||||
0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0,
|
||||
0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b,
|
||||
0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576,
|
||||
0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
|
||||
0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c,
|
||||
0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f,
|
||||
0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda,
|
||||
0xbe9834ed
|
||||
},
|
||||
{
|
||||
0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757,
|
||||
0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a,
|
||||
0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733,
|
||||
0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,
|
||||
0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70,
|
||||
0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42,
|
||||
0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5,
|
||||
0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,
|
||||
0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086,
|
||||
0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4,
|
||||
0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d,
|
||||
0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,
|
||||
0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d,
|
||||
0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f,
|
||||
0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859,
|
||||
0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
|
||||
0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5,
|
||||
0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028,
|
||||
0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891,
|
||||
0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,
|
||||
0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec,
|
||||
0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde,
|
||||
0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817,
|
||||
0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,
|
||||
0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24,
|
||||
0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e,
|
||||
0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7,
|
||||
0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,
|
||||
0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4,
|
||||
0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196,
|
||||
0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0,
|
||||
0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
|
||||
0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52,
|
||||
0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f,
|
||||
0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36,
|
||||
0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,
|
||||
0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675,
|
||||
0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647,
|
||||
0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d,
|
||||
0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,
|
||||
0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be,
|
||||
0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc,
|
||||
0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645,
|
||||
0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,
|
||||
0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138,
|
||||
0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a,
|
||||
0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c,
|
||||
0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
|
||||
0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0,
|
||||
0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d,
|
||||
0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194,
|
||||
0xde0506f1
|
||||
},
|
||||
{
|
||||
0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0,
|
||||
0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271,
|
||||
0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61,
|
||||
0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52,
|
||||
0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43,
|
||||
0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333,
|
||||
0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64,
|
||||
0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314,
|
||||
0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205,
|
||||
0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136,
|
||||
0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26,
|
||||
0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997,
|
||||
0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849,
|
||||
0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739,
|
||||
0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8,
|
||||
0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,
|
||||
0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b,
|
||||
0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba,
|
||||
0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa,
|
||||
0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d,
|
||||
0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c,
|
||||
0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc,
|
||||
0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af,
|
||||
0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf,
|
||||
0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce,
|
||||
0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922,
|
||||
0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532,
|
||||
0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183,
|
||||
0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710,
|
||||
0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860,
|
||||
0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1,
|
||||
0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,
|
||||
0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956,
|
||||
0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7,
|
||||
0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7,
|
||||
0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4,
|
||||
0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5,
|
||||
0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5,
|
||||
0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb,
|
||||
0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb,
|
||||
0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da,
|
||||
0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9,
|
||||
0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9,
|
||||
0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48,
|
||||
0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df,
|
||||
0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af,
|
||||
0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e,
|
||||
0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,
|
||||
0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d,
|
||||
0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c,
|
||||
0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c,
|
||||
0xca64c78c
|
||||
},
|
||||
{
|
||||
0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216,
|
||||
0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8,
|
||||
0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170,
|
||||
0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035,
|
||||
0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6,
|
||||
0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145,
|
||||
0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d,
|
||||
0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e,
|
||||
0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d,
|
||||
0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408,
|
||||
0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0,
|
||||
0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e,
|
||||
0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c,
|
||||
0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf,
|
||||
0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a,
|
||||
0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,
|
||||
0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1,
|
||||
0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f,
|
||||
0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987,
|
||||
0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4,
|
||||
0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37,
|
||||
0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84,
|
||||
0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca,
|
||||
0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79,
|
||||
0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba,
|
||||
0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d,
|
||||
0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5,
|
||||
0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b,
|
||||
0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643,
|
||||
0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0,
|
||||
0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525,
|
||||
0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,
|
||||
0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8,
|
||||
0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026,
|
||||
0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e,
|
||||
0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db,
|
||||
0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118,
|
||||
0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab,
|
||||
0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf,
|
||||
0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c,
|
||||
0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf,
|
||||
0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a,
|
||||
0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32,
|
||||
0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec,
|
||||
0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82,
|
||||
0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31,
|
||||
0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4,
|
||||
0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,
|
||||
0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f,
|
||||
0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1,
|
||||
0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869,
|
||||
0xe4c4abcc
|
||||
},
|
||||
{
|
||||
0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413,
|
||||
0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3,
|
||||
0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d,
|
||||
0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653,
|
||||
0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9,
|
||||
0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e,
|
||||
0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5,
|
||||
0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712,
|
||||
0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8,
|
||||
0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6,
|
||||
0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068,
|
||||
0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8,
|
||||
0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579,
|
||||
0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade,
|
||||
0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37,
|
||||
0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,
|
||||
0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4,
|
||||
0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64,
|
||||
0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea,
|
||||
0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678,
|
||||
0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282,
|
||||
0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25,
|
||||
0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102,
|
||||
0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5,
|
||||
0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f,
|
||||
0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146,
|
||||
0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8,
|
||||
0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08,
|
||||
0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c,
|
||||
0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b,
|
||||
0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972,
|
||||
0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,
|
||||
0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d,
|
||||
0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd,
|
||||
0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833,
|
||||
0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d,
|
||||
0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7,
|
||||
0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60,
|
||||
0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2,
|
||||
0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105,
|
||||
0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff,
|
||||
0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1,
|
||||
0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f,
|
||||
0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf,
|
||||
0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617,
|
||||
0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0,
|
||||
0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959,
|
||||
0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,
|
||||
0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca,
|
||||
0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a,
|
||||
0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184,
|
||||
0x92364a30
|
||||
},
|
||||
{
|
||||
0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa,
|
||||
0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b,
|
||||
0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232,
|
||||
0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8,
|
||||
0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e,
|
||||
0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa,
|
||||
0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b,
|
||||
0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f,
|
||||
0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719,
|
||||
0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3,
|
||||
0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa,
|
||||
0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b,
|
||||
0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed,
|
||||
0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89,
|
||||
0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25,
|
||||
0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,
|
||||
0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c,
|
||||
0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed,
|
||||
0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4,
|
||||
0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758,
|
||||
0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e,
|
||||
0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a,
|
||||
0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed,
|
||||
0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889,
|
||||
0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df,
|
||||
0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544,
|
||||
0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d,
|
||||
0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c,
|
||||
0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1,
|
||||
0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95,
|
||||
0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839,
|
||||
0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,
|
||||
0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976,
|
||||
0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7,
|
||||
0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be,
|
||||
0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144,
|
||||
0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12,
|
||||
0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376,
|
||||
0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a,
|
||||
0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e,
|
||||
0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278,
|
||||
0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682,
|
||||
0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b,
|
||||
0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a,
|
||||
0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561,
|
||||
0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05,
|
||||
0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9,
|
||||
0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,
|
||||
0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0,
|
||||
0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61,
|
||||
0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678,
|
||||
0x264b06e6
|
||||
}
|
||||
};
|
||||
|
||||
// Implement crc32 using Intel's "slicing by 8" algorithm. Significantly faster
|
||||
// than most other common approachs on common CPUs at the time of this writing.
|
||||
uint32_t crc32(uint32_t crc, const unsigned char* buf, size_t len)
|
||||
{
|
||||
if ( !buf )
|
||||
return 0;
|
||||
crc = crc ^ 0xffffffff;
|
||||
for ( ; 9 < len && (uintptr_t) buf & 7; len--, buf++ )
|
||||
crc = crc_table[0][(crc & 0xff) ^ *buf] ^ (crc >> 8);
|
||||
for ( ; 8 <= len; len -= 8, buf += 8 )
|
||||
{
|
||||
crc = crc_table[7][(buf[0] ^ (crc )) & 0xff]
|
||||
^ crc_table[6][(buf[1] ^ (crc >> 8 )) & 0xff]
|
||||
^ crc_table[5][(buf[2] ^ (crc >> 16)) & 0xff]
|
||||
^ crc_table[4][(buf[3] ^ (crc >> 24)) & 0xff]
|
||||
^ crc_table[3][buf[4]]
|
||||
^ crc_table[2][buf[5]]
|
||||
^ crc_table[1][buf[6]]
|
||||
^ crc_table[0][buf[7]];
|
||||
}
|
||||
for ( ; 0 < len; len--, buf++ )
|
||||
crc = crc_table[0][(crc & 0xff) ^ *buf] ^ (crc >> 8);
|
||||
return crc ^ 0xffffffff;
|
||||
}
|
||||
|
||||
} // namespace Sortix
|
|
@ -997,7 +997,11 @@ int Descriptor::bind(ioctx_t* ctx, const uint8_t* addr, size_t addrlen)
|
|||
|
||||
int Descriptor::connect(ioctx_t* ctx, const uint8_t* addr, size_t addrlen)
|
||||
{
|
||||
return vnode->connect(ctx, addr, addrlen);
|
||||
int old_ctx_dflags = ctx->dflags;
|
||||
ctx->dflags = ContextFlags(old_ctx_dflags, dflags);
|
||||
int result = vnode->connect(ctx, addr, addrlen);
|
||||
ctx->dflags = old_ctx_dflags;
|
||||
return result;
|
||||
}
|
||||
|
||||
int Descriptor::listen(ioctx_t* ctx, int backlog)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -40,4 +40,22 @@
|
|||
#define TIOCGPTN __IOCTL(7, __IOCTL_TYPE_PTR)
|
||||
#define TIOCGDISPLAYS __IOCTL(8, __IOCTL_TYPE_PTR)
|
||||
|
||||
#define IOC_TYPE(x) ((x) >> 0 & 0xFF)
|
||||
#define IOC_TYPE_BLOCK_DEVICE 1
|
||||
#define IOC_TYPE_NETWORK_INTERFACE 2
|
||||
#define IOC_SUBTYPE(x) ((x) >> 8 & 0xFF)
|
||||
#define IOC_SUBTYPE_BLOCK_DEVICE_HARDDISK 1
|
||||
#define IOC_SUBTYPE_BLOCK_DEVICE_PARTITION 2
|
||||
#define IOC_MAKE_TYPE(type, subtype) ((type) << 0 | (subtype) << 8)
|
||||
#define IOCGETTYPE __IOCTL(9, __IOCTL_TYPE_VOID)
|
||||
|
||||
#define NIOC_GETINFO __IOCTL(10, __IOCTL_TYPE_PTR)
|
||||
#define NIOC_GETSTATUS __IOCTL(11, __IOCTL_TYPE_PTR)
|
||||
#define NIOC_GETCONFIG __IOCTL(12, __IOCTL_TYPE_PTR)
|
||||
#define NIOC_SETCONFIG __IOCTL(13, __IOCTL_TYPE_PTR)
|
||||
#define NIOC_GETCONFIG_ETHER __IOCTL(14, __IOCTL_TYPE_PTR)
|
||||
#define NIOC_SETCONFIG_ETHER __IOCTL(15, __IOCTL_TYPE_PTR)
|
||||
#define NIOC_GETCONFIG_INET __IOCTL(16, __IOCTL_TYPE_PTR)
|
||||
#define NIOC_SETCONFIG_INET __IOCTL(17, __IOCTL_TYPE_PTR)
|
||||
|
||||
#endif
|
||||
|
|
32
kernel/include/sortix/kernel/crc32.h
Normal file
32
kernel/include/sortix/kernel/crc32.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* sortix/kernel/crc32.h
|
||||
* CRC32 checksum.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SORTIX_KERNEL_CRC32_H
|
||||
#define _INCLUDE_SORTIX_KERNEL_CRC32_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Sortix {
|
||||
|
||||
uint32_t crc32(uint32_t crc, const unsigned char* buf, size_t len);
|
||||
|
||||
} // namespace Sortix
|
||||
|
||||
#endif
|
70
kernel/include/sortix/kernel/if.h
Normal file
70
kernel/include/sortix/kernel/if.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Meisaka Yukara.
|
||||
* Copyright (c) 2016, 2017, 2022 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* sortix/kernel/if.h
|
||||
* Network Interface.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SORTIX_KERNEL_IF_H
|
||||
#define _INCLUDE_SORTIX_KERNEL_IF_H
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <sortix/kernel/descriptor.h>
|
||||
#include <sortix/kernel/kthread.h>
|
||||
#include <sortix/kernel/packet.h>
|
||||
#include <sortix/kernel/poll.h>
|
||||
|
||||
namespace Sortix {
|
||||
|
||||
namespace ARP {
|
||||
struct arp_table;
|
||||
} // namespace ARP
|
||||
|
||||
class NetworkInterface
|
||||
{
|
||||
public:
|
||||
NetworkInterface();
|
||||
virtual ~NetworkInterface();
|
||||
|
||||
public:
|
||||
virtual bool Send(Ref<Packet> pkt) = 0;
|
||||
|
||||
public:
|
||||
int poll(ioctx_t* ctx, PollNode* node);
|
||||
short PollEventStatus();
|
||||
|
||||
public:
|
||||
kthread_mutex_t cfg_lock;
|
||||
kthread_cond_t cfg_cond;
|
||||
struct if_info ifinfo;
|
||||
struct if_status ifstatus;
|
||||
struct if_config cfg;
|
||||
struct ARP::arp_table* arp_table;
|
||||
PollChannel poll_channel;
|
||||
|
||||
};
|
||||
|
||||
bool RegisterNetworkInterface(NetworkInterface* netif,
|
||||
Ref<Descriptor> dev);
|
||||
|
||||
extern kthread_mutex_t netifs_lock;
|
||||
extern NetworkInterface** netifs;
|
||||
extern size_t netifs_count;
|
||||
|
||||
} // namespace Sortix
|
||||
|
||||
#endif
|
|
@ -41,6 +41,7 @@ enum page_usage
|
|||
PAGE_USAGE_USER_SPACE,
|
||||
PAGE_USAGE_EXECUTE,
|
||||
PAGE_USAGE_DRIVER,
|
||||
PAGE_USAGE_NETWORK_PACKET,
|
||||
PAGE_USAGE_NUM_KINDS,
|
||||
PAGE_USAGE_WASNT_ALLOCATED,
|
||||
};
|
||||
|
|
55
kernel/include/sortix/kernel/packet.h
Normal file
55
kernel/include/sortix/kernel/packet.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Meisaka Yukara.
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* sortix/kernel/packet.h
|
||||
* Reference counted network packets.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SORTIX_KERNEL_PACKET_H
|
||||
#define _INCLUDE_SORTIX_KERNEL_PACKET_H
|
||||
|
||||
#include <endian.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sortix/kernel/addralloc.h>
|
||||
#include <sortix/kernel/pci-mmio.h>
|
||||
#include <sortix/kernel/refcount.h>
|
||||
|
||||
namespace Sortix {
|
||||
|
||||
class NetworkInterface;
|
||||
|
||||
class Packet : public Refcountable
|
||||
{
|
||||
public:
|
||||
Packet(paddrmapped_t pmap);
|
||||
virtual ~Packet();
|
||||
|
||||
public:
|
||||
paddrmapped_t pmap;
|
||||
unsigned char* from;
|
||||
size_t length;
|
||||
size_t offset;
|
||||
NetworkInterface* netif;
|
||||
Ref<Packet> next;
|
||||
|
||||
};
|
||||
|
||||
Ref<Packet> GetPacket();
|
||||
|
||||
} // namespace Sortix
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2013, 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -22,23 +22,14 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* TODO: Nicely wrap this in an enum, as in glibc's header? */
|
||||
#define SOCK_TYPE_MASK ((1<<20)-1)
|
||||
#define SOCK_RAW 0 /* Will Sortix support this? */
|
||||
#define SOCK_DGRAM 1
|
||||
#define SOCK_SEQPACKET 2
|
||||
#define SOCK_STREAM 3
|
||||
#define SOCK_RAW 4
|
||||
|
||||
#define SOCK_NONBLOCK (1<<20)
|
||||
#define SOCK_CLOEXEC (1<<21)
|
||||
#define SOCK_CLOFORK (1<<22)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -84,6 +84,10 @@
|
|||
#include "mouse/ps2.h"
|
||||
#include "multiboot.h"
|
||||
#include "net/fs.h"
|
||||
#include "net/lo/lo.h"
|
||||
#include "net/ping.h"
|
||||
#include "net/tcp.h"
|
||||
#include "net/udp.h"
|
||||
#include "poll.h"
|
||||
#include "pty.h"
|
||||
#include "uart.h"
|
||||
|
@ -111,6 +115,7 @@ static void SystemIdleThread(void* user);
|
|||
static int argc;
|
||||
static char** argv;
|
||||
static multiboot_info_t* bootinfo;
|
||||
static bool enable_network_drivers = true;
|
||||
|
||||
static char* cmdline_tokenize(char** saved)
|
||||
{
|
||||
|
@ -291,6 +296,10 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo_p)
|
|||
HaltKernel();
|
||||
}
|
||||
}
|
||||
else if ( !strcmp(arg, "--disable-network-drivers") )
|
||||
enable_network_drivers = false;
|
||||
else if ( !strcmp(arg, "--enable-network-drivers") )
|
||||
enable_network_drivers = true;
|
||||
else if ( !strcmp(arg, "--no-random-seed") )
|
||||
no_random_seed = true;
|
||||
else
|
||||
|
@ -610,6 +619,23 @@ static void BootThread(void* /*user*/)
|
|||
// Initialize the filesystem network.
|
||||
NetFS::Init();
|
||||
|
||||
// Initialize the ping protocol.
|
||||
Ping::Init();
|
||||
|
||||
// Initialize the TCP.
|
||||
TCP::Init();
|
||||
|
||||
// Initialize the UDP.
|
||||
UDP::Init();
|
||||
|
||||
// Initialize the loopback driver.
|
||||
Loopback::Init("/dev", slashdev);
|
||||
|
||||
// Initialize the network drivers.
|
||||
if ( enable_network_drivers )
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Stage 6. Executing Hosted Environment ("User-Space")
|
||||
//
|
||||
|
|
740
kernel/net/arp.cpp
Normal file
740
kernel/net/arp.cpp
Normal file
|
@ -0,0 +1,740 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/arp.cpp
|
||||
* Address resolution protocol.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <timespec.h>
|
||||
|
||||
#include <sortix/kernel/clock.h>
|
||||
#include <sortix/kernel/kernel.h>
|
||||
#include <sortix/kernel/kthread.h>
|
||||
#include <sortix/kernel/if.h>
|
||||
#include <sortix/kernel/packet.h>
|
||||
#include <sortix/kernel/refcount.h>
|
||||
#include <sortix/kernel/time.h>
|
||||
#include <sortix/kernel/timer.h>
|
||||
|
||||
#include "arp.h"
|
||||
#include "ether.h"
|
||||
|
||||
// Every network interface has its own ARP table of cached entries. The table
|
||||
// is a hash map of IP address to an ARP entry. The hash function is the
|
||||
// bytewise xor of each byte in the IP address. The table can contain up to 256
|
||||
// entries, which all start out in a linked list of unused entries.
|
||||
//
|
||||
// The used entries of an table are in a linked list sorted in order of last
|
||||
// use. The unused entries are in a linked list in no particular order. The
|
||||
// entries currently being resolved are in the deadline linked list sorted in
|
||||
// order of the request deadline. The entries currently resolved and valid are
|
||||
// in a linked list sorted in order of their expiration.
|
||||
//
|
||||
// To evict an entry from the cache, remove the entry from the appropriate
|
||||
// linked lists, discard the entry's transmission queue, clear it, and add it to
|
||||
// the table's list of unused entries.
|
||||
//
|
||||
// To allocate an entry for an IP address, the hash table is searched for an
|
||||
// existing entry to return. If an existing entry is found, it is moved to the
|
||||
// front of the hash table in case of a collision. Otherwise, the first unused
|
||||
// entry is used. If the table was full, the least recently used entry is
|
||||
// evicted and then used. The new entry is assigned the IP address and added to
|
||||
// the hash table.
|
||||
//
|
||||
// When a packet is sent to an IP address, an ARP table is made for the network
|
||||
// interface if it doesn't already have one. If the IP address is outside the
|
||||
// network interface's IP subnet, or if the network interface has no IP address
|
||||
// configured, the request fails. An ARP entry for the destination IP address is
|
||||
// searched for, or if none exists, then a new one is allocated. The entry is
|
||||
// marked as USED and is moved to the front of the table's list of entries in
|
||||
// order of last use. If the entry is marked as RESOLVED, the packet is just
|
||||
// sent to the entry's Ethernet address. Otherwise if the entry has not been
|
||||
// marked as RESOLVING, an initial request for the IP address is broadcast on
|
||||
// the local network, the entry is added to the end of the deadline linked list,
|
||||
// and the deadline timer is set to fire when the request times out. The packet
|
||||
// is added to the entry's transmission queue unless it is already full.
|
||||
//
|
||||
// If the deadline timer fires, the entry is removed from the deadline linked
|
||||
// list. If too many attempts failed, the entry is evicted. Otherwise, the IP
|
||||
// address resolution is attempted again and the entry's request attempt counter
|
||||
// is incremented.
|
||||
//
|
||||
// When an ARP message is received, the message is discarded if the source or
|
||||
// destination IP is outside the network interface's subnet, or if the network
|
||||
// interface did not have an IP address configured. The entry for the source
|
||||
// IP address is located in the network interface's table, or if none exists and
|
||||
// the table is not currently full, an entry is allocated. The entry is removed
|
||||
// from the deadline linked list if it is RESOLVING. The entry is removed from
|
||||
// the expiration linked list if it is EXPIRING. The entry is marked as RESOLVED
|
||||
// and the source Ethernet address is assigned to the entry. The entry is marked
|
||||
// as EXPIRING and is added to the end of the expiring linked list and the
|
||||
// expiration is set to fire when the entry expires. Every packet in the entry's
|
||||
// transmission queue is sent to the source Ethernet address.
|
||||
//
|
||||
// If the message is a request, and the destination IP address is that of the
|
||||
// network interface. Otherwise, an ARP reply message is sent back with the
|
||||
// Ethernet address of the network interface.
|
||||
//
|
||||
// When the expiration timer fires, the entry is removed from the expiration
|
||||
// linked list. If the entry was not marked as USED, it is evicted. Otherwise
|
||||
// the entry is marked as RESOLVING, the attempt request attempt counter is
|
||||
// reset, and the address resolution is attempted again. Until the renewal
|
||||
// succeeds or times out, the entry remains marked RESOLVED and is used to route
|
||||
// traffic from its IP address to its Ethernet address.
|
||||
|
||||
#define ETHERTYPE_ETHER 1
|
||||
|
||||
#define ARP_REQUEST 1
|
||||
#define ARP_REPLY 2
|
||||
|
||||
// The entry contains a valid Ethernet address that has been resolved.
|
||||
#define ARP_STATUS_RESOLVED (1 << 0)
|
||||
|
||||
// The entry is currently being resolved, the deadline timeout has been set and
|
||||
// the deadline timer will fire when the resolution times out. This status is
|
||||
// mutually exclusive with the EXPIRING status.
|
||||
#define ARP_STATUS_RESOLVING (1 << 1)
|
||||
|
||||
// The entry has been resolved and is currently waiting until it expires, the
|
||||
// expiration timeout has been set and the expiration timer will fire when the
|
||||
// entry expires. This status is mutually exclusive with the RESOLVING status.
|
||||
#define ARP_STATUS_EXPIRING (1 << 2)
|
||||
|
||||
// The entry has been used to route a packet and should be renewed on expiry.
|
||||
#define ARP_STATUS_USED (1 << 3)
|
||||
|
||||
// The number of entries in an ARP table, this value is documented in arp(4).
|
||||
#define ARP_TABLE_LENGTH 256
|
||||
|
||||
// The number of entries in the ARP table hashmap, this value is documented
|
||||
// in arp(4).
|
||||
#define ARP_HASHTABLE_LENGTH 256
|
||||
|
||||
// Attempt to resolve an address this many times before giving up, this value is
|
||||
// documented in arp(4).
|
||||
#define ARP_MAX_ATTEMPTS 3
|
||||
|
||||
// The maximum number of packets in an ARP entry's transmission queue, this
|
||||
// value is documented in arp(4).
|
||||
#define ARP_MAX_PENDING 16
|
||||
|
||||
namespace Sortix {
|
||||
namespace ARP {
|
||||
|
||||
// The duration to wait before giving up on an attempt to resolve an address,
|
||||
// this value is documented in arp(4).
|
||||
static const struct timespec REQUEST_TIMEOUT = { .tv_sec = 1, .tv_nsec = 0 };
|
||||
|
||||
// The duration before the entry expires and renewal begins, this value is
|
||||
// documented in arp(4).
|
||||
static const struct timespec ENTRY_TIMEOUT = { .tv_sec = 60, .tv_nsec = 0 };
|
||||
|
||||
struct arp
|
||||
{
|
||||
uint16_t hrd; /* Hardware address space */
|
||||
uint16_t pro; /* Protocol address space */
|
||||
uint8_t hln; /* Byte length of each hardware address */
|
||||
uint8_t pln; /* Byte length of each protocol address */
|
||||
uint16_t op; /* opcode */
|
||||
uint8_t sha[6]; /* Hardware address of sender */
|
||||
uint8_t spa[4]; /* Protocol address of sender */
|
||||
uint8_t tha[6]; /* Hardware address of target */
|
||||
uint8_t tpa[4]; /* Protocol address of target */
|
||||
};
|
||||
|
||||
struct arp_entry
|
||||
{
|
||||
struct arp_table* table;
|
||||
struct arp_entry* prev_by_table;
|
||||
struct arp_entry* next_by_table;
|
||||
struct arp_entry* prev_by_hash;
|
||||
struct arp_entry* next_by_hash;
|
||||
struct arp_entry* prev_by_timer;
|
||||
struct arp_entry* next_by_timer;
|
||||
struct timespec timeout;
|
||||
struct in_addr addr;
|
||||
struct ether_addr ether;
|
||||
uint16_t status;
|
||||
uint16_t attempts;
|
||||
uint16_t pending;
|
||||
Ref<Packet> pending_first;
|
||||
Ref<Packet> pending_last;
|
||||
};
|
||||
|
||||
struct arp_table
|
||||
{
|
||||
NetworkInterface* netif;
|
||||
struct arp_entry* first_unused;
|
||||
struct arp_entry* first_used;
|
||||
struct arp_entry* last_unused;
|
||||
struct arp_entry* last_used;
|
||||
struct arp_entry* hashtable[ARP_HASHTABLE_LENGTH];
|
||||
struct arp_entry entries[ARP_TABLE_LENGTH];
|
||||
};
|
||||
|
||||
static void OnDeadline(Clock* clock, Timer* timer, void* context);
|
||||
static void OnExpiration(Clock* clock, Timer* timer, void* context);
|
||||
|
||||
kthread_mutex_t arp_lock = KTHREAD_MUTEX_INITIALIZER;
|
||||
static struct arp_entry* first_by_deadline;
|
||||
static struct arp_entry* last_by_deadline;
|
||||
static struct arp_entry* first_by_expiration;
|
||||
static struct arp_entry* last_by_expiration;
|
||||
static Timer* deadline_timer;
|
||||
static Timer* expiration_timer;
|
||||
static bool deadline_timer_armed;
|
||||
static bool expiration_timer_armed;
|
||||
|
||||
// This hash function is perfect if the subnet is at least /24, with no more
|
||||
// than remaining bits for the address of the machine on the subnet.
|
||||
static inline uint8_t HashAddress(const struct in_addr* addr)
|
||||
{
|
||||
uint32_t value = be32toh(addr->s_addr);
|
||||
return (value << 0 & 0xFF) ^ (value << 8 & 0xFF) ^
|
||||
(value << 16 & 0xFF) ^ (value << 24 & 0xFF);
|
||||
}
|
||||
|
||||
// arp_lock locked
|
||||
static struct arp_table* GetTable(NetworkInterface* netif)
|
||||
{
|
||||
if ( netif->arp_table )
|
||||
return netif->arp_table;
|
||||
struct arp_table* table = new struct arp_table;
|
||||
if ( !table )
|
||||
return NULL;
|
||||
memset(table, 0, sizeof(*table));
|
||||
netif->arp_table = table;
|
||||
table->netif = netif;
|
||||
// Enter every entry into the table's unused linked list.
|
||||
table->first_unused = &table->entries[0];
|
||||
for ( size_t i = 0; i < ARP_TABLE_LENGTH; i++ )
|
||||
{
|
||||
table->entries[i].table = table;
|
||||
if ( i )
|
||||
table->entries[i].prev_by_table = &table->entries[i-1];
|
||||
if ( i + 1 < ARP_TABLE_LENGTH )
|
||||
table->entries[i].next_by_table = &table->entries[i+1];
|
||||
}
|
||||
table->last_unused = &table->entries[ARP_TABLE_LENGTH-1];
|
||||
return table;
|
||||
}
|
||||
|
||||
// arp_lock locked
|
||||
static void EvictEntry(struct arp_table* table, struct arp_entry* entry)
|
||||
{
|
||||
unsigned char hash = HashAddress(&entry->addr);
|
||||
|
||||
// Remove from the table's used linked list.
|
||||
(entry->next_by_table ?
|
||||
entry->next_by_table->prev_by_table :
|
||||
table->last_used) = entry->prev_by_table;
|
||||
(entry->prev_by_table ?
|
||||
entry->prev_by_table->next_by_table :
|
||||
table->first_used) = entry->next_by_table;
|
||||
entry->prev_by_table = NULL;
|
||||
entry->next_by_table = NULL;
|
||||
|
||||
// Remove from the hash table.
|
||||
if ( entry->next_by_hash )
|
||||
entry->next_by_hash->prev_by_hash = entry->prev_by_hash;
|
||||
(entry->prev_by_hash ?
|
||||
entry->prev_by_hash->next_by_hash :
|
||||
table->hashtable[hash]) = entry->next_by_hash;
|
||||
entry->prev_by_hash = NULL;
|
||||
entry->next_by_hash = NULL;
|
||||
|
||||
// Remove from deadline linked list.
|
||||
if ( entry->status & ARP_STATUS_RESOLVING )
|
||||
{
|
||||
(entry->next_by_timer ?
|
||||
entry->next_by_timer->prev_by_timer :
|
||||
last_by_deadline) = entry->prev_by_timer;
|
||||
(entry->prev_by_timer ?
|
||||
entry->prev_by_timer->next_by_timer :
|
||||
first_by_deadline) = entry->next_by_timer;
|
||||
entry->prev_by_timer = NULL;
|
||||
entry->next_by_timer = NULL;
|
||||
}
|
||||
|
||||
// Remove from expiration linked list.
|
||||
else if ( entry->status & ARP_STATUS_EXPIRING )
|
||||
{
|
||||
(entry->next_by_timer ?
|
||||
entry->next_by_timer->prev_by_timer :
|
||||
last_by_expiration) = entry->prev_by_timer;
|
||||
(entry->prev_by_timer ?
|
||||
entry->prev_by_timer->next_by_timer :
|
||||
first_by_expiration) = entry->next_by_timer;
|
||||
entry->prev_by_timer = NULL;
|
||||
entry->next_by_timer = NULL;
|
||||
}
|
||||
|
||||
// Drain the transmission queue while avoiding a stack overflow in packet
|
||||
// recursive destructor.
|
||||
while ( entry->pending_first )
|
||||
{
|
||||
Ref<Packet> next = entry->pending_first->next;
|
||||
entry->pending_first->next.Reset();
|
||||
entry->pending_first = next;
|
||||
entry->pending--;
|
||||
if ( !entry->pending_first )
|
||||
entry->pending_last.Reset();
|
||||
}
|
||||
|
||||
// Clear the entry.
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
entry->table = table;
|
||||
|
||||
// Insert the entry into the table's unused linked list.
|
||||
(table->first_unused ?
|
||||
table->first_unused->prev_by_table :
|
||||
table->last_unused) = entry;
|
||||
entry->prev_by_table = NULL;
|
||||
entry->next_by_table = table->first_unused;
|
||||
table->first_unused = entry;
|
||||
}
|
||||
|
||||
// arp_lock locked
|
||||
static struct arp_entry* AllocateEntry(struct arp_table* table,
|
||||
const struct in_addr* addr,
|
||||
bool evict)
|
||||
{
|
||||
// Search for an existing entry.
|
||||
unsigned char hash = HashAddress(addr);
|
||||
for ( struct arp_entry* entry = table->hashtable[hash];
|
||||
entry;
|
||||
entry = entry->next_by_hash )
|
||||
{
|
||||
if ( be32toh(addr->s_addr) == be32toh(entry->addr.s_addr) )
|
||||
{
|
||||
// Move to the front of the hash table if not already.
|
||||
if ( entry->prev_by_hash )
|
||||
{
|
||||
if ( entry->next_by_hash )
|
||||
entry->next_by_hash->prev_by_hash = entry->prev_by_hash;
|
||||
entry->prev_by_hash->next_by_hash = entry->next_by_hash;
|
||||
entry->prev_by_hash = NULL;
|
||||
entry->next_by_hash = table->hashtable[hash];
|
||||
table->hashtable[hash]->prev_by_hash = entry;
|
||||
table->hashtable[hash] = entry;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate a new entry, potentially evicting the least recently used entry.
|
||||
struct arp_entry* entry = table->first_unused;
|
||||
if ( !table->first_unused )
|
||||
{
|
||||
if ( !evict )
|
||||
return NULL;
|
||||
EvictEntry(table, table->last_used);
|
||||
assert(table->first_unused);
|
||||
entry = table->first_unused;
|
||||
}
|
||||
|
||||
// Remove from the table's unused list.
|
||||
table->first_unused = entry->next_by_table;
|
||||
(table->first_unused ?
|
||||
table->first_unused->prev_by_table :
|
||||
table->last_unused) = NULL;
|
||||
|
||||
// Initialize the entry.
|
||||
entry->addr.s_addr = addr->s_addr;
|
||||
|
||||
// Insert into the table's used list.
|
||||
(table->last_used ?
|
||||
table->last_used->next_by_table :
|
||||
table->first_used) = entry;
|
||||
entry->prev_by_table = table->last_used;
|
||||
entry->next_by_table = NULL;
|
||||
table->last_used = entry;
|
||||
|
||||
// Add to the front of the hash table.
|
||||
if ( table->hashtable[hash] )
|
||||
table->hashtable[hash]->prev_by_hash = entry;
|
||||
entry->prev_by_hash = NULL;
|
||||
entry->next_by_hash = table->hashtable[hash];
|
||||
table->hashtable[hash] = entry;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
// arp_lock locked
|
||||
static bool Resolve(NetworkInterface* netif, struct arp_entry* entry)
|
||||
{
|
||||
if ( !deadline_timer )
|
||||
{
|
||||
if ( !(deadline_timer = new Timer()) )
|
||||
return false;
|
||||
deadline_timer->Attach(Time::GetClock(CLOCK_MONOTONIC));
|
||||
}
|
||||
struct ether_addr src_ether_addr;
|
||||
struct in_addr src_in_addr;
|
||||
kthread_mutex_lock(&netif->cfg_lock);
|
||||
struct if_config* cfg = &netif->cfg;
|
||||
memcpy(&src_ether_addr, &cfg->ether.address, sizeof(struct ether_addr));
|
||||
memcpy(&src_in_addr, &cfg->inet.address, sizeof(struct in_addr));
|
||||
kthread_mutex_unlock(&netif->cfg_lock);
|
||||
struct arp arp;
|
||||
arp.hrd = htobe16(ETHERTYPE_ETHER);
|
||||
arp.pro = htobe16(ETHERTYPE_IP);
|
||||
arp.hln = sizeof(struct ether_addr);
|
||||
arp.pln = sizeof(struct in_addr);
|
||||
arp.op = htobe16(ARP_REQUEST);
|
||||
memcpy(arp.sha, &src_ether_addr, sizeof(struct ether_addr));
|
||||
memcpy(arp.spa, &src_in_addr, sizeof(struct in_addr));
|
||||
memcpy(arp.tha, ðeraddr_broadcast, sizeof(struct ether_addr));
|
||||
memcpy(arp.tpa, &entry->addr, sizeof(struct in_addr));
|
||||
Ref<Packet> pkt = GetPacket();
|
||||
if ( !pkt )
|
||||
return false;
|
||||
if ( pkt->pmap.size < sizeof(arp) )
|
||||
return errno = EMSGSIZE, false;
|
||||
pkt->length = sizeof(arp);
|
||||
memcpy(pkt->from, &arp, sizeof(arp));
|
||||
if ( !Ether::Send(pkt, &src_ether_addr, ðeraddr_broadcast, ETHERTYPE_ARP,
|
||||
netif) )
|
||||
return false;
|
||||
entry->status |= ARP_STATUS_RESOLVING;
|
||||
entry->attempts++;
|
||||
struct timespec now = Time::Get(CLOCK_MONOTONIC);
|
||||
entry->timeout = timespec_add(now, REQUEST_TIMEOUT);
|
||||
// Add entry to end of deadline linked list.
|
||||
(last_by_deadline ?
|
||||
last_by_deadline->next_by_timer :
|
||||
first_by_deadline) = entry;
|
||||
entry->prev_by_timer = last_by_deadline;
|
||||
entry->next_by_timer = NULL;
|
||||
last_by_deadline = entry;
|
||||
if ( !deadline_timer_armed )
|
||||
{
|
||||
struct itimerspec its;
|
||||
its.it_value = REQUEST_TIMEOUT;
|
||||
its.it_interval = timespec_nul();
|
||||
deadline_timer->Set(&its, NULL, 0, OnDeadline, NULL);
|
||||
deadline_timer_armed = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void OnDeadline(Clock* clock, Timer* timer, void* /*context*/)
|
||||
{
|
||||
ScopedLock lock(&arp_lock);
|
||||
struct timespec now;
|
||||
clock->Get(&now, NULL);
|
||||
struct arp_entry* entry;
|
||||
while ( (entry = first_by_deadline) )
|
||||
{
|
||||
if ( timespec_lt(now, entry->timeout) )
|
||||
{
|
||||
struct itimerspec its;
|
||||
its.it_value = timespec_sub(entry->timeout, now);
|
||||
its.it_interval = timespec_nul();
|
||||
timer->Set(&its, NULL, 0, OnDeadline, NULL);
|
||||
return;
|
||||
}
|
||||
struct arp_table* table = entry->table;
|
||||
// Remove from the deadline linked list.
|
||||
entry->status &= ~ARP_STATUS_RESOLVING;
|
||||
first_by_deadline = entry->next_by_timer;
|
||||
(first_by_deadline ?
|
||||
first_by_deadline->prev_by_timer :
|
||||
last_by_deadline) = NULL;
|
||||
entry->prev_by_timer = NULL;
|
||||
entry->next_by_timer = NULL;
|
||||
if ( entry->attempts < ARP_MAX_ATTEMPTS )
|
||||
Resolve(table->netif, entry);
|
||||
else
|
||||
EvictEntry(table, entry);
|
||||
}
|
||||
deadline_timer_armed = false;
|
||||
}
|
||||
|
||||
static void OnExpiration(Clock* clock, Timer* timer, void* /*context*/)
|
||||
{
|
||||
ScopedLock lock(&arp_lock);
|
||||
struct timespec now;
|
||||
clock->Get(&now, NULL);
|
||||
struct arp_entry* entry;
|
||||
while ( (entry = first_by_expiration) )
|
||||
{
|
||||
if ( timespec_lt(now, entry->timeout) )
|
||||
{
|
||||
struct itimerspec its;
|
||||
its.it_value = timespec_sub(entry->timeout, now);
|
||||
its.it_interval = timespec_nul();
|
||||
timer->Set(&its, NULL, 0, OnExpiration, NULL);
|
||||
return;
|
||||
}
|
||||
struct arp_table* table = entry->table;
|
||||
// Remove the entry from the expiration linked list.
|
||||
entry->status &= ~ARP_STATUS_EXPIRING;
|
||||
first_by_expiration = entry->next_by_timer;
|
||||
(first_by_expiration ?
|
||||
first_by_expiration->prev_by_timer :
|
||||
last_by_expiration) = NULL;
|
||||
entry->prev_by_timer = NULL;
|
||||
entry->next_by_timer = NULL;
|
||||
if ( entry->status & ARP_STATUS_USED )
|
||||
{
|
||||
entry->status &= ~ARP_STATUS_USED;
|
||||
entry->attempts = 0;
|
||||
Resolve(table->netif, entry);
|
||||
}
|
||||
else
|
||||
EvictEntry(table, entry);
|
||||
}
|
||||
expiration_timer_armed = false;
|
||||
}
|
||||
|
||||
bool RouteIPEthernet(NetworkInterface* netif,
|
||||
Ref<Packet> pkt,
|
||||
const struct in_addr* dst)
|
||||
{
|
||||
struct ether_addr local_ether;
|
||||
struct in_addr local_in;
|
||||
struct in_addr local_subnet;
|
||||
kthread_mutex_lock(&netif->cfg_lock);
|
||||
memcpy(&local_ether, &netif->cfg.ether.address, sizeof(struct ether_addr));
|
||||
memcpy(&local_in, &netif->cfg.inet.address, sizeof(struct in_addr));
|
||||
memcpy(&local_subnet, &netif->cfg.inet.subnet, sizeof(struct in_addr));
|
||||
kthread_mutex_unlock(&netif->cfg_lock);
|
||||
if ( be32toh(local_in.s_addr) == INADDR_ANY )
|
||||
return errno = ENETUNREACH, false;
|
||||
if ( (local_in.s_addr & local_subnet.s_addr) !=
|
||||
(dst->s_addr &local_subnet.s_addr) )
|
||||
return errno = ENETUNREACH, false;
|
||||
ScopedLock lock(&arp_lock);
|
||||
struct arp_table* table = GetTable(netif);
|
||||
if ( !table )
|
||||
return false;
|
||||
struct arp_entry* entry = AllocateEntry(table, dst, true);
|
||||
assert(entry);
|
||||
// Mark as USED and move the entry to the front of table's used linked list.
|
||||
entry->status |= ARP_STATUS_USED;
|
||||
if ( entry->prev_by_table )
|
||||
{
|
||||
(entry->next_by_table ?
|
||||
entry->next_by_table->prev_by_table :
|
||||
table->last_used) = entry->prev_by_table;
|
||||
entry->prev_by_table->next_by_table = entry->next_by_table;
|
||||
entry->prev_by_table = NULL;
|
||||
entry->next_by_table = table->first_used;
|
||||
table->first_used->prev_by_table = entry;
|
||||
table->first_used = entry;
|
||||
}
|
||||
if ( entry->status & ARP_STATUS_RESOLVED )
|
||||
{
|
||||
struct ether_addr dst_ether = entry->ether;
|
||||
lock.Reset();
|
||||
return Ether::Send(pkt, &local_ether, &dst_ether, ETHERTYPE_IP, netif);
|
||||
}
|
||||
assert(!pkt->next);
|
||||
if ( !(entry->status & ARP_STATUS_RESOLVING) && !Resolve(netif, entry) )
|
||||
return false;
|
||||
// Drop the packet if the transmission queue is full.
|
||||
if ( ARP_MAX_PENDING <= entry->pending )
|
||||
return true;
|
||||
(entry->pending_last ?
|
||||
entry->pending_last->next :
|
||||
entry->pending_first) = pkt;
|
||||
entry->pending_last = pkt;
|
||||
entry->pending++;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Handle(Ref<Packet> pkt,
|
||||
const struct ether_addr* src_ether_of_packet,
|
||||
const struct ether_addr* /*dst_ether*/,
|
||||
bool /*dst_ether*/)
|
||||
{
|
||||
const unsigned char* in = pkt->from + pkt->offset;
|
||||
size_t inlen = pkt->length - pkt->offset;
|
||||
NetworkInterface* netif = pkt->netif;
|
||||
struct arp hdr;
|
||||
if ( inlen < sizeof(hdr) )
|
||||
return;
|
||||
memcpy(&hdr, in, sizeof(hdr));
|
||||
hdr.hrd = be16toh(hdr.hrd);
|
||||
hdr.pro = be16toh(hdr.pro);
|
||||
hdr.op = be16toh(hdr.op);
|
||||
|
||||
// Drop unsupported or invalid packets.
|
||||
if ( !(hdr.hrd == ETHERTYPE_ETHER && hdr.hln == 6) )
|
||||
return;
|
||||
if ( !(hdr.pro == ETHERTYPE_IP && hdr.pln == 4) )
|
||||
return;
|
||||
if ( !(hdr.op == ARP_REQUEST || hdr.op == ARP_REPLY) )
|
||||
return;
|
||||
|
||||
struct in_addr src;
|
||||
struct in_addr dst;
|
||||
memcpy(&src, hdr.spa, sizeof(src));
|
||||
memcpy(&dst, hdr.tpa, sizeof(dst));
|
||||
struct ether_addr src_ether;
|
||||
memcpy(&src_ether, hdr.sha, sizeof(src_ether));
|
||||
struct ether_addr local_eth;
|
||||
struct in_addr local_in;
|
||||
struct in_addr local_subnet;
|
||||
kthread_mutex_lock(&netif->cfg_lock);
|
||||
memcpy(&local_eth, &netif->cfg.ether.address, sizeof(struct ether_addr));
|
||||
memcpy(&local_in, &netif->cfg.inet.address, sizeof(struct in_addr));
|
||||
memcpy(&local_subnet, &netif->cfg.inet.subnet, sizeof(struct in_addr));
|
||||
kthread_mutex_unlock(&netif->cfg_lock);
|
||||
|
||||
// Drop packets if the network interface does not have an IP address
|
||||
// configured, or if the source or destination IP address are outside of the
|
||||
// network interface's IP subnet.
|
||||
if ( be32toh(local_in.s_addr) == INADDR_ANY )
|
||||
return;
|
||||
if ( (local_in.s_addr & local_subnet.s_addr) !=
|
||||
(src.s_addr & local_subnet.s_addr))
|
||||
return;
|
||||
if ( (local_in.s_addr & local_subnet.s_addr) !=
|
||||
(dst.s_addr & local_subnet.s_addr) )
|
||||
return;
|
||||
|
||||
ScopedLock lock(&arp_lock);
|
||||
|
||||
if ( !expiration_timer )
|
||||
{
|
||||
if ( !(expiration_timer = new Timer()) )
|
||||
return;
|
||||
expiration_timer->Attach(Time::GetClock(CLOCK_MONOTONIC));
|
||||
}
|
||||
|
||||
struct arp_table* table = GetTable(netif);
|
||||
if ( !table )
|
||||
return;
|
||||
struct arp_entry* entry = AllocateEntry(table, &src, false);
|
||||
|
||||
if ( entry )
|
||||
{
|
||||
// Remove from pending request linked list.
|
||||
if ( entry->status & ARP_STATUS_RESOLVING )
|
||||
{
|
||||
entry->status &= ~ARP_STATUS_RESOLVING;
|
||||
(entry->next_by_timer ?
|
||||
entry->next_by_timer->prev_by_timer :
|
||||
last_by_deadline) = entry->prev_by_timer;
|
||||
(entry->prev_by_timer ?
|
||||
entry->prev_by_timer->next_by_timer :
|
||||
first_by_deadline) = entry->next_by_timer;
|
||||
entry->prev_by_timer = NULL;
|
||||
entry->next_by_timer = NULL;
|
||||
}
|
||||
|
||||
// Remove from expiration linked list.
|
||||
else if ( entry->status & ARP_STATUS_EXPIRING )
|
||||
{
|
||||
entry->status &= ~ARP_STATUS_EXPIRING;
|
||||
(entry->next_by_timer ?
|
||||
entry->next_by_timer->prev_by_timer :
|
||||
last_by_expiration) = entry->prev_by_timer;
|
||||
(entry->prev_by_timer ?
|
||||
entry->prev_by_timer->next_by_timer :
|
||||
first_by_expiration) = entry->next_by_timer;
|
||||
entry->prev_by_timer = NULL;
|
||||
entry->next_by_timer = NULL;
|
||||
}
|
||||
|
||||
// Mark entry as RESOLVED.
|
||||
entry->status |= ARP_STATUS_RESOLVED;
|
||||
memcpy(&entry->ether, &src_ether, sizeof(src_ether));
|
||||
|
||||
// Mark entry as EXPIRING and add to end of the expiration linked list.
|
||||
entry->status |= ARP_STATUS_EXPIRING;
|
||||
(last_by_expiration ?
|
||||
last_by_expiration->next_by_timer :
|
||||
first_by_expiration) = entry;
|
||||
entry->prev_by_timer = last_by_expiration;
|
||||
entry->next_by_timer = NULL;
|
||||
last_by_expiration = entry;
|
||||
struct timespec now = Time::Get(CLOCK_MONOTONIC);
|
||||
entry->timeout = timespec_add(now, ENTRY_TIMEOUT);
|
||||
if ( !expiration_timer_armed )
|
||||
{
|
||||
struct itimerspec its;
|
||||
its.it_value = ENTRY_TIMEOUT;
|
||||
its.it_interval = timespec_nul();
|
||||
expiration_timer->Set(&its, NULL, 0, OnExpiration, NULL);
|
||||
expiration_timer_armed = true;
|
||||
}
|
||||
|
||||
// Transmit the transission queue.
|
||||
while ( entry->pending_first )
|
||||
{
|
||||
Ref<Packet> pending = entry->pending_first;
|
||||
entry->pending_first = pending->next;
|
||||
pending->next.Reset();
|
||||
Ether::Send(pending, &local_eth, &src_ether, ETHERTYPE_IP, netif);
|
||||
if ( !entry->pending_first )
|
||||
entry->pending_last.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Send an ARP reply if our local address was requested.
|
||||
if ( hdr.op == ARP_REQUEST &&
|
||||
!memcmp(&local_in, &dst, sizeof(struct in_addr)) )
|
||||
{
|
||||
Ref<Packet> packet = GetPacket();
|
||||
if ( !packet )
|
||||
return;
|
||||
struct arp arp;
|
||||
arp.hrd = htobe16(ETHERTYPE_ETHER);
|
||||
arp.pro = htobe16(ETHERTYPE_IP);
|
||||
arp.hln = sizeof(struct ether_addr);
|
||||
arp.pln = sizeof(struct in_addr);
|
||||
arp.op = htobe16(ARP_REPLY);
|
||||
memcpy(arp.sha, &local_eth, sizeof(struct ether_addr));
|
||||
memcpy(arp.spa, &local_in, sizeof(struct in_addr));
|
||||
memcpy(arp.tha, &src_ether, sizeof(struct ether_addr));
|
||||
memcpy(arp.tpa, &src, sizeof(struct in_addr));
|
||||
if ( packet->pmap.size < sizeof(arp) )
|
||||
return;
|
||||
packet->length = sizeof(arp);
|
||||
unsigned char* out = packet->from;
|
||||
memcpy(out, &arp, sizeof(arp));
|
||||
Ether::Send(packet, &local_eth, src_ether_of_packet, ETHERTYPE_ARP,
|
||||
netif);
|
||||
}
|
||||
}
|
||||
|
||||
// arp_lock locked, netif->cfg_lock locked.
|
||||
void OnConfiguration(NetworkInterface* netif,
|
||||
const struct if_config* old_cfg,
|
||||
const struct if_config* new_cfg)
|
||||
{
|
||||
// Purge the ARP cache if the ether or inet configuration changed.
|
||||
if ( !memcmp(&old_cfg->ether, &new_cfg->ether, sizeof(new_cfg->ether)) &&
|
||||
!memcmp(&old_cfg->inet, &new_cfg->inet, sizeof(new_cfg->inet)) )
|
||||
return;
|
||||
struct arp_table* table = GetTable(netif);
|
||||
if ( !table )
|
||||
return;
|
||||
while ( table->first_used )
|
||||
EvictEntry(table, table->first_used);
|
||||
}
|
||||
|
||||
} // namespace ARP
|
||||
} // namespace Sortix
|
53
kernel/net/arp.h
Normal file
53
kernel/net/arp.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/arp.h
|
||||
* Address resolution protocol.
|
||||
*/
|
||||
|
||||
#ifndef NET_ARP_H
|
||||
#define NET_ARP_H
|
||||
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <sortix/kernel/packet.h>
|
||||
|
||||
struct if_config;
|
||||
|
||||
namespace Sortix {
|
||||
class NetworkInterface;
|
||||
} // namespace Sortix
|
||||
|
||||
namespace Sortix {
|
||||
namespace ARP {
|
||||
|
||||
extern kthread_mutex_t arp_lock;
|
||||
|
||||
bool RouteIPEthernet(NetworkInterface* netif,
|
||||
Ref<Packet> pkt,
|
||||
const struct in_addr* dst);
|
||||
void Handle(Ref<Packet> pkt,
|
||||
const struct ether_addr* src,
|
||||
const struct ether_addr* dst,
|
||||
bool dst_broadcast);
|
||||
void OnConfiguration(NetworkInterface* netif,
|
||||
const struct if_config* old_cfg,
|
||||
const struct if_config* new_cfg);
|
||||
|
||||
} // namespace ARP
|
||||
} // namespace Sortix
|
||||
|
||||
#endif
|
139
kernel/net/ether.cpp
Normal file
139
kernel/net/ether.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/ether.cpp
|
||||
* Ethernet.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <endian.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sortix/kernel/crc32.h>
|
||||
#include <sortix/kernel/kernel.h>
|
||||
#include <sortix/kernel/if.h>
|
||||
#include <sortix/kernel/packet.h>
|
||||
|
||||
#include "arp.h"
|
||||
#include "ether.h"
|
||||
#include "ip.h"
|
||||
|
||||
namespace Sortix {
|
||||
namespace Ether {
|
||||
|
||||
size_t GetMTU(NetworkInterface* netif)
|
||||
{
|
||||
(void) netif;
|
||||
return ETHERMTU;
|
||||
}
|
||||
|
||||
void Handle(Ref<Packet> pkt, bool checksum_offloaded)
|
||||
{
|
||||
assert(pkt->netif);
|
||||
assert(pkt->offset <= pkt->length);
|
||||
const unsigned char* in = pkt->from + pkt->offset;
|
||||
size_t inlen = pkt->length - pkt->offset;
|
||||
struct ether_header hdr;
|
||||
if ( !checksum_offloaded )
|
||||
{
|
||||
struct ether_footer ftr;
|
||||
if ( inlen < sizeof(hdr) + sizeof(ftr) /* ETHER_LEN */ )
|
||||
return;
|
||||
size_t ftr_offset = inlen - sizeof(ftr);
|
||||
memcpy(&ftr, in + ftr_offset, sizeof(ftr));
|
||||
pkt->length -= sizeof(ftr);
|
||||
inlen -= sizeof(ftr);
|
||||
ftr.ether_crc = le32toh(ftr.ether_crc);
|
||||
if ( ftr.ether_crc != crc32(0, in, inlen) )
|
||||
return;
|
||||
}
|
||||
else if ( inlen < sizeof(hdr) /* ETHER_HDR_LEN */ )
|
||||
return;
|
||||
memcpy(&hdr, in, sizeof(hdr));
|
||||
hdr.ether_type = be16toh(hdr.ether_type);
|
||||
pkt->offset += sizeof(hdr);
|
||||
const struct ether_addr* src = (const struct ether_addr*) &hdr.ether_shost;
|
||||
const struct ether_addr* dst = (const struct ether_addr*) &hdr.ether_dhost;
|
||||
// Drop invalid frames with broadcast source.
|
||||
if ( !memcmp(src, ðeraddr_broadcast, sizeof(struct ether_addr)) )
|
||||
return;
|
||||
// Accept only frames with destination being broadcast or our address.
|
||||
bool dst_broadcast =
|
||||
!memcmp(dst, ðeraddr_broadcast, sizeof(struct ether_addr));
|
||||
if ( !dst_broadcast )
|
||||
{
|
||||
ScopedLock(&pkt->netif->cfg_lock);
|
||||
const struct ether_addr* local = &pkt->netif->cfg.ether.address;
|
||||
if ( pkt->netif->ifinfo.type != IF_TYPE_LOOPBACK &&
|
||||
memcmp(dst, local, sizeof(struct ether_addr)) != 0 )
|
||||
return;
|
||||
}
|
||||
switch ( hdr.ether_type )
|
||||
{
|
||||
case ETHERTYPE_IP: // IPv4
|
||||
IP::Handle(pkt, src, dst, dst_broadcast);
|
||||
break;
|
||||
case ETHERTYPE_ARP: // Address Resolution Protocol
|
||||
ARP::Handle(pkt, src, dst, dst_broadcast);
|
||||
break;
|
||||
case ETHERTYPE_IPV6: // IPv6
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Send(Ref<Packet> pktin,
|
||||
const struct ether_addr* src,
|
||||
const struct ether_addr* dst,
|
||||
uint16_t ether_type,
|
||||
NetworkInterface* netif)
|
||||
{
|
||||
if ( ETHERMTU < pktin->length )
|
||||
return errno = EMSGSIZE, false;
|
||||
Ref<Packet> pkt = GetPacket();
|
||||
if ( !pkt )
|
||||
return false;
|
||||
const unsigned char* in = pktin->from;
|
||||
size_t inlen = pktin->length;
|
||||
size_t padding = inlen < ETHERMIN ? ETHERMIN - inlen : 0;
|
||||
unsigned char* out = pkt->from;
|
||||
struct ether_header hdr;
|
||||
struct ether_footer ftr;
|
||||
size_t outlen = sizeof(hdr) /* ETHER_HDR_LEN */ + inlen + padding;
|
||||
if ( !(netif->ifinfo.features & IF_FEATURE_ETHERNET_CRC_OFFLOAD) )
|
||||
outlen += sizeof(ftr) /* ETHER_CRC_LEN */;
|
||||
if ( pkt->pmap.size < outlen )
|
||||
return errno = EMSGSIZE, false;
|
||||
pkt->length = outlen;
|
||||
memcpy(&hdr.ether_dhost, dst, sizeof(struct ether_addr));
|
||||
memcpy(&hdr.ether_shost, src, sizeof(struct ether_addr));
|
||||
hdr.ether_type = htobe16(ether_type);
|
||||
memcpy(out, &hdr, sizeof(hdr));
|
||||
memcpy(out + sizeof(hdr), in, inlen);
|
||||
memset(out + sizeof(hdr) + inlen, 0, padding);
|
||||
if ( !(netif->ifinfo.features & IF_FEATURE_ETHERNET_CRC_OFFLOAD) )
|
||||
{
|
||||
ftr.ether_crc = htole32(crc32(0, out, pkt->length));
|
||||
memcpy(out + sizeof(hdr) + inlen + padding, &ftr, sizeof(ftr));
|
||||
}
|
||||
return netif->Send(pkt);
|
||||
}
|
||||
|
||||
} // namespace Ether
|
||||
} // namespace Sortix
|
46
kernel/net/ether.h
Normal file
46
kernel/net/ether.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/ether.h
|
||||
* Ethernet.
|
||||
*/
|
||||
|
||||
#ifndef SORTIX_NET_ETHER_H
|
||||
#define SORTIX_NET_ETHER_H
|
||||
|
||||
#include <netinet/if_ether.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sortix/kernel/packet.h>
|
||||
|
||||
namespace Sortix {
|
||||
class NetworkInterface;
|
||||
} // namespace Sortix
|
||||
|
||||
namespace Sortix {
|
||||
namespace Ether {
|
||||
|
||||
size_t GetMTU(NetworkInterface* netif);
|
||||
void Handle(Ref<Packet> pkt, bool checksum_offloaded);
|
||||
bool Send(Ref<Packet> pkt,
|
||||
const struct ether_addr* src,
|
||||
const struct ether_addr* dst,
|
||||
uint16_t ether_type,
|
||||
NetworkInterface* netif);
|
||||
|
||||
} // namespace Ether
|
||||
} // namespace Sortix
|
||||
|
||||
#endif
|
237
kernel/net/if.cpp
Normal file
237
kernel/net/if.cpp
Normal file
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Meisaka Yukara.
|
||||
* Copyright (c) 2016, 2017, 2022 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/if.cpp
|
||||
* Network Interface.
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <poll.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sortix/stat.h>
|
||||
|
||||
#include <sortix/kernel/addralloc.h>
|
||||
#include <sortix/kernel/copy.h>
|
||||
#include <sortix/kernel/descriptor.h>
|
||||
#include <sortix/kernel/if.h>
|
||||
#include <sortix/kernel/inode.h>
|
||||
#include <sortix/kernel/ioctx.h>
|
||||
#include <sortix/kernel/kthread.h>
|
||||
#include <sortix/kernel/log.h>
|
||||
#include <sortix/kernel/memorymanagement.h>
|
||||
#include <sortix/kernel/packet.h>
|
||||
#include <sortix/kernel/panic.h>
|
||||
#include <sortix/kernel/pci.h>
|
||||
#include <sortix/kernel/pci-mmio.h>
|
||||
#include <sortix/kernel/refcount.h>
|
||||
|
||||
#include "arp.h"
|
||||
|
||||
namespace Sortix {
|
||||
|
||||
kthread_mutex_t netifs_lock = KTHREAD_MUTEX_INITIALIZER;
|
||||
NetworkInterface** netifs = NULL;
|
||||
size_t netifs_count = 0;
|
||||
static size_t netifs_allocated = 0;
|
||||
|
||||
class NetworkInterfaceNode : public AbstractInode
|
||||
{
|
||||
public:
|
||||
NetworkInterfaceNode(dev_t dev, uid_t owner, gid_t group, mode_t mode,
|
||||
NetworkInterface* netif);
|
||||
virtual ~NetworkInterfaceNode();
|
||||
|
||||
public:
|
||||
virtual int ioctl(ioctx_t* ctx, int cmd, uintptr_t ptr);
|
||||
virtual int poll(ioctx_t* ctx, PollNode* node);
|
||||
|
||||
private:
|
||||
NetworkInterface* netif;
|
||||
|
||||
};
|
||||
|
||||
bool RegisterNetworkInterface(NetworkInterface* netif,
|
||||
Ref<Descriptor> dev)
|
||||
{
|
||||
ScopedLock lock(&netifs_lock);
|
||||
if ( netifs_count == netifs_allocated )
|
||||
{
|
||||
size_t new_length_half = netifs_allocated;
|
||||
if ( new_length_half == 0 )
|
||||
new_length_half = 8;
|
||||
NetworkInterface** new_netifs =
|
||||
(NetworkInterface**) reallocarray(netifs, new_length_half,
|
||||
2 * sizeof(NetworkInterface*));
|
||||
if ( !new_netifs )
|
||||
return false;
|
||||
netifs = new_netifs;
|
||||
netifs_allocated = new_length_half * 2;
|
||||
}
|
||||
Ref<Inode> node(new NetworkInterfaceNode(dev->dev, 0, 0, 0666, netif));
|
||||
if ( !node )
|
||||
return false;
|
||||
ioctx_t ctx; SetupKernelIOCtx(&ctx);
|
||||
if ( LinkInodeInDir(&ctx, dev, netif->ifinfo.name, node) != 0 )
|
||||
return false;
|
||||
// Interfaces are counted from 1 inclusive up to UINT_MAX exclusive.
|
||||
if ( netifs_count == 0 )
|
||||
netifs[netifs_count++] = NULL;
|
||||
if ( UINT_MAX <= netifs_count + 1 )
|
||||
return errno = EOVERFLOW, false;
|
||||
unsigned int linkid = netifs_count++;
|
||||
netifs[linkid] = netif;
|
||||
netif->ifinfo.linkid = linkid;
|
||||
return true;
|
||||
}
|
||||
|
||||
NetworkInterface::NetworkInterface()
|
||||
{
|
||||
cfg_lock = KTHREAD_MUTEX_INITIALIZER;
|
||||
cfg_cond = KTHREAD_COND_INITIALIZER;
|
||||
memset(&ifinfo, 0, sizeof(ifinfo));
|
||||
memset(&ifstatus, 0, sizeof(ifstatus));
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
arp_table = NULL;
|
||||
// poll_channel is initialized by its constructor.
|
||||
}
|
||||
|
||||
NetworkInterface::~NetworkInterface()
|
||||
{
|
||||
}
|
||||
|
||||
short NetworkInterface::PollEventStatus()
|
||||
{
|
||||
short status = 0;
|
||||
if ( ifstatus.flags & IF_STATUS_FLAGS_UP )
|
||||
status |= POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM;
|
||||
return status;
|
||||
}
|
||||
|
||||
int NetworkInterface::poll(ioctx_t* /*ctx*/, PollNode* node)
|
||||
{
|
||||
ScopedLock lock(&cfg_lock);
|
||||
short ret_status = PollEventStatus() & node->events;
|
||||
if ( ret_status )
|
||||
{
|
||||
node->master->revents |= ret_status;
|
||||
return 0;
|
||||
}
|
||||
poll_channel.Register(node);
|
||||
return errno = EAGAIN, -1;
|
||||
}
|
||||
|
||||
NetworkInterfaceNode::NetworkInterfaceNode(dev_t dev, uid_t owner, gid_t group,
|
||||
mode_t mode, NetworkInterface* netif)
|
||||
{
|
||||
inode_type = INODE_TYPE_UNKNOWN;
|
||||
if ( !dev )
|
||||
dev = (dev_t) this;
|
||||
ino = (ino_t) this;
|
||||
this->type = S_IFCHR;
|
||||
this->dev = dev;
|
||||
this->stat_uid = owner;
|
||||
this->stat_gid = group;
|
||||
this->stat_mode = (mode & S_SETABLE) | this->type;
|
||||
this->netif = netif;
|
||||
}
|
||||
|
||||
NetworkInterfaceNode::~NetworkInterfaceNode()
|
||||
{
|
||||
}
|
||||
|
||||
int NetworkInterfaceNode::ioctl(ioctx_t* ctx, int cmd, uintptr_t arg)
|
||||
{
|
||||
void* ptr = (void*) arg;
|
||||
|
||||
if ( cmd == NIOC_SETCONFIG ||
|
||||
cmd == NIOC_SETCONFIG_ETHER ||
|
||||
cmd == NIOC_SETCONFIG_INET )
|
||||
{
|
||||
ScopedLock outer(&ARP::arp_lock);
|
||||
ScopedLock inner(&netif->cfg_lock);
|
||||
struct if_config new_cfg;
|
||||
memcpy(&new_cfg, &netif->cfg, sizeof(new_cfg));
|
||||
switch ( cmd )
|
||||
{
|
||||
case NIOC_SETCONFIG:
|
||||
if ( !ctx->copy_from_src(&new_cfg, ptr, sizeof(new_cfg)) )
|
||||
return -1;
|
||||
break;
|
||||
case NIOC_SETCONFIG_ETHER:
|
||||
if ( !ctx->copy_from_src(&new_cfg.ether, ptr,
|
||||
sizeof(new_cfg.ether)) )
|
||||
return -1;
|
||||
break;
|
||||
case NIOC_SETCONFIG_INET:
|
||||
if ( !ctx->copy_from_src(&new_cfg.inet, ptr, sizeof(new_cfg.inet)) )
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
// Let the ARP cache know the configuration changed, so it can purge any
|
||||
// entries that are no longer valid.
|
||||
ARP::OnConfiguration(netif, &netif->cfg, &new_cfg);
|
||||
memcpy(&netif->cfg, &new_cfg, sizeof(new_cfg));
|
||||
kthread_cond_broadcast(&netif->cfg_cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ScopedLock lock(&netif->cfg_lock);
|
||||
switch ( cmd )
|
||||
{
|
||||
case IOCGETTYPE:
|
||||
return IOC_MAKE_TYPE(IOC_TYPE_NETWORK_INTERFACE, 0);
|
||||
case NIOC_GETINFO:
|
||||
if ( !ctx->copy_to_dest(ptr, &netif->ifinfo, sizeof(netif->ifinfo)) )
|
||||
return -1;
|
||||
return 0;
|
||||
case NIOC_GETSTATUS:
|
||||
if ( !ctx->copy_to_dest(ptr, &netif->ifstatus,
|
||||
sizeof(netif->ifstatus)) )
|
||||
return -1;
|
||||
return 0;
|
||||
case NIOC_GETCONFIG:
|
||||
if ( !ctx->copy_to_dest(ptr, &netif->cfg, sizeof(netif->cfg)) )
|
||||
return -1;
|
||||
return 0;
|
||||
case NIOC_GETCONFIG_ETHER:
|
||||
if ( !ctx->copy_to_dest(ptr, &netif->cfg.ether,
|
||||
sizeof(netif->cfg.ether)) )
|
||||
return -1;
|
||||
return 0;
|
||||
case NIOC_GETCONFIG_INET:
|
||||
if ( !ctx->copy_to_dest(ptr, &netif->cfg.inet,
|
||||
sizeof(netif->cfg.inet)) )
|
||||
return -1;
|
||||
return 0;
|
||||
default:
|
||||
return errno = ENOTTY, -1;
|
||||
}
|
||||
}
|
||||
|
||||
int NetworkInterfaceNode::poll(ioctx_t* ctx, PollNode* node)
|
||||
{
|
||||
return netif->poll(ctx, node);
|
||||
}
|
||||
|
||||
} // namespace Sortix
|
453
kernel/net/ip.cpp
Normal file
453
kernel/net/ip.cpp
Normal file
|
@ -0,0 +1,453 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/ip.cpp
|
||||
* Internet Protocol Version 4.
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
#include <timespec.h>
|
||||
|
||||
#include <sortix/kernel/kernel.h>
|
||||
#include <sortix/kernel/if.h>
|
||||
#include <sortix/kernel/packet.h>
|
||||
#include <sortix/kernel/refcount.h>
|
||||
|
||||
#include "arp.h"
|
||||
#include "ether.h"
|
||||
#include "ping.h"
|
||||
#include "tcp.h"
|
||||
#include "udp.h"
|
||||
|
||||
namespace Sortix {
|
||||
namespace IP {
|
||||
|
||||
struct ipv4
|
||||
{
|
||||
uint8_t version_ihl;
|
||||
uint8_t dscp_ecn;
|
||||
uint16_t length;
|
||||
uint16_t identification;
|
||||
uint16_t fragment;
|
||||
uint8_t ttl;
|
||||
uint8_t protocol;
|
||||
uint16_t checksum;
|
||||
uint8_t source[4];
|
||||
uint8_t destination[4];
|
||||
};
|
||||
|
||||
#define IPV4_IHL(x) ((x) >> 0 & 0xF)
|
||||
#define IPV4_VERSION(x) ((x) >> 4 & 0xF)
|
||||
#define IPV4_IHL_MAKE(x) (((x) & 0xF) << 0)
|
||||
#define IPV4_VERSION_MAKE(x) (((x) & 0xF) << 4)
|
||||
#define IPV4_FRAGMENT(x) (((x) >> 0) & 0x1FFF)
|
||||
#define IPV4_FRAGMENT_MAKE(x) (((x) & 0x1FFF) << 0)
|
||||
#define IPV4_FRAGMENT_MORE (1 << (13 + 0))
|
||||
#define IPV4_FRAGMENT_DONT (1 << (13 + 1))
|
||||
#define IPV4_FRAGMENT_EVIL (1 << (13 + 2))
|
||||
|
||||
uint16_t ipsum_word(uint16_t sum, uint16_t word)
|
||||
{
|
||||
uint32_t result = sum + word;
|
||||
if ( result & 0x10000 )
|
||||
return (result + 1) & 0xFFFF;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t ipsum_buf(uint16_t sum, const void* bufptr, size_t size)
|
||||
{
|
||||
const uint8_t* buf = (const uint8_t*) bufptr;
|
||||
for ( size_t i = 0; i < (size & ~1UL); i += 2 )
|
||||
sum = ipsum_word(sum, buf[i] << 8 | buf[i + 1]);
|
||||
// Odd sizes only work correctly if this is the final byte being summed.
|
||||
if ( size & 1 )
|
||||
sum = ipsum_word(sum, buf[size - 1] << 8);
|
||||
return sum;
|
||||
}
|
||||
|
||||
uint16_t ipsum_finish(uint16_t sum)
|
||||
{
|
||||
return ~sum;
|
||||
}
|
||||
|
||||
uint16_t ipsum(const void* bufptr, size_t size)
|
||||
{
|
||||
uint16_t sum = ipsum_buf(0, bufptr, size);
|
||||
return ipsum_finish(sum);
|
||||
}
|
||||
|
||||
static NetworkInterface* LocateInterface(const struct in_addr* src,
|
||||
const struct in_addr* dst,
|
||||
unsigned int ifindex)
|
||||
{
|
||||
ScopedLock ifs_lock(&netifs_lock);
|
||||
in_addr_t any_ip = htobe32(INADDR_ANY);
|
||||
in_addr_t broadcast_ip = htobe32(INADDR_BROADCAST);
|
||||
|
||||
// Refuse to route to the any address.
|
||||
if ( !memcmp(&any_ip, dst, sizeof(in_addr_t)) )
|
||||
return errno = ENETUNREACH, (NetworkInterface*) NULL;
|
||||
// If src is set, but ifindex is not set, search for a fitting interface.
|
||||
if ( !ifindex && memcmp(&any_ip, src, sizeof(in_addr_t)) != 0 )
|
||||
{
|
||||
for ( unsigned int i = 1; i < netifs_count; i++ )
|
||||
{
|
||||
NetworkInterface* netif = netifs[i];
|
||||
if ( !netif )
|
||||
continue;
|
||||
ScopedLock cfg_lock(&netif->cfg_lock);
|
||||
if ( memcmp(&netif->cfg.inet.address, src, sizeof(in_addr_t)) != 0 )
|
||||
continue;
|
||||
ifindex = i;
|
||||
break;
|
||||
}
|
||||
// No interface had the correct address.
|
||||
if ( !ifindex )
|
||||
return errno = EADDRNOTAVAIL, (NetworkInterface*) NULL;
|
||||
}
|
||||
// If ifindex is set, route to that interface.
|
||||
if ( ifindex )
|
||||
{
|
||||
// Can't route to non-existent interface.
|
||||
if ( netifs_count <= ifindex )
|
||||
return errno = EADDRNOTAVAIL, (NetworkInterface*) NULL;
|
||||
NetworkInterface* netif = netifs[ifindex];
|
||||
if ( !netif )
|
||||
return errno = EADDRNOTAVAIL, (NetworkInterface*) NULL;
|
||||
ScopedLock cfg_lock(&netif->cfg_lock);
|
||||
// Can't route to down interfaces.
|
||||
if ( !(netif->ifstatus.flags & IF_STATUS_FLAGS_UP) )
|
||||
return errno = ENETDOWN, (NetworkInterface*) NULL;
|
||||
// If src is set, it must be the interface's address.
|
||||
if ( memcmp(src, &any_ip, sizeof(in_addr_t)) != 0 &&
|
||||
memcmp(src, &netif->cfg.inet.address, sizeof(in_addr_t)) != 0 )
|
||||
return errno = EADDRNOTAVAIL, (NetworkInterface*) NULL;
|
||||
in_addr_t dstaddr = be32toh(dst->s_addr);
|
||||
in_addr_t ifaddr = be32toh(netif->cfg.inet.address.s_addr);
|
||||
in_addr_t subnet = be32toh(netif->cfg.inet.subnet.s_addr);
|
||||
in_addr_t loopaddr = INADDR_LOOPBACK;
|
||||
in_addr_t loopmask = INADDR_LOOPMASK;
|
||||
if ( netif->ifinfo.type == IF_TYPE_LOOPBACK )
|
||||
{
|
||||
// The destination must be on the interface's subnet.
|
||||
if ( (dstaddr & subnet) != (ifaddr & subnet) )
|
||||
return errno = ENETUNREACH, (NetworkInterface*) NULL;
|
||||
return netif;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The destination must not be on the loopback network for
|
||||
// a non-loopback interface.
|
||||
if ( (dstaddr & loopmask) == (loopaddr & loopmask) )
|
||||
return errno = ENETUNREACH, (NetworkInterface*) NULL;
|
||||
// If the interface does not have a default route, the destination
|
||||
// must be broadcast or be on the interface's subnet.
|
||||
if ( !memcmp(&netif->cfg.inet.router, &any_ip, sizeof(in_addr_t)) &&
|
||||
memcmp(&dstaddr, &broadcast_ip, sizeof(in_addr_t)) != 0 &&
|
||||
(dstaddr & subnet) != (ifaddr & subnet) )
|
||||
return errno = ENETUNREACH, (NetworkInterface*) NULL;
|
||||
return netif;
|
||||
}
|
||||
}
|
||||
// If the destination is broadcast, send to the first fitting interface.
|
||||
else if ( !memcmp(&broadcast_ip, dst, sizeof(in_addr_t)) )
|
||||
{
|
||||
for ( unsigned int i = 1; i < netifs_count; i++ )
|
||||
{
|
||||
NetworkInterface* netif = netifs[i];
|
||||
if ( !netif )
|
||||
continue;
|
||||
ScopedLock cfg_lock(&netif->cfg_lock);
|
||||
// Can't route broadcast to loopback interfaces or down interfaces.
|
||||
if ( netif->ifinfo.type == IF_TYPE_LOOPBACK ||
|
||||
!(netif->ifstatus.flags & IF_STATUS_FLAGS_UP) )
|
||||
continue;
|
||||
return netif;
|
||||
}
|
||||
// No interface was suitable for broadcast.
|
||||
return errno = EADDRNOTAVAIL, (NetworkInterface*) NULL;
|
||||
}
|
||||
// Otherwise, pick the best interface for the destination address.
|
||||
else
|
||||
{
|
||||
NetworkInterface* default_netif = NULL;
|
||||
for ( unsigned int i = 1; i < netifs_count; i++ )
|
||||
{
|
||||
NetworkInterface* netif = netifs[i];
|
||||
if ( !netif )
|
||||
continue;
|
||||
ScopedLock cfg_lock(&netif->cfg_lock);
|
||||
in_addr_t dstaddr = be32toh(dst->s_addr);
|
||||
in_addr_t ifaddr = be32toh(netif->cfg.inet.address.s_addr);
|
||||
in_addr_t subnet = be32toh(netif->cfg.inet.subnet.s_addr);
|
||||
// Route to the interface if the destination is on its subnet.
|
||||
if ( (dstaddr & subnet) == (ifaddr & subnet) )
|
||||
{
|
||||
// Can't route to down interfaces.
|
||||
if ( !(netif->ifstatus.flags & IF_STATUS_FLAGS_UP) )
|
||||
return errno = ENETDOWN, (NetworkInterface*) NULL;
|
||||
return netif;
|
||||
}
|
||||
// If the interface is up, no default route has been found yet, and
|
||||
// the interface has a default route, default to that route if no
|
||||
// better interface is found.
|
||||
else if ( (netif->ifstatus.flags & IF_STATUS_FLAGS_UP) &&
|
||||
!default_netif &&
|
||||
memcmp(&any_ip, &netif->cfg.inet.router,
|
||||
sizeof(in_addr_t)) != 0 )
|
||||
default_netif = netif;
|
||||
}
|
||||
// If a fitting default route was found, use it.
|
||||
if ( default_netif )
|
||||
return default_netif;
|
||||
// No interface was up that could accept the destination address, hence
|
||||
// the network is down.
|
||||
return errno = ENETDOWN, (NetworkInterface*) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ShouldHandlePacket(Ref<Packet> pkt,
|
||||
const struct in_addr* src,
|
||||
const struct in_addr* dst,
|
||||
bool dst_broadcast,
|
||||
bool* out_broadcast)
|
||||
{
|
||||
NetworkInterface* netif = pkt->netif;
|
||||
ScopedLock cfg_lock(&netif->cfg_lock);
|
||||
// The source address must not be broadcast (RFC 1122 3.2.1.3).
|
||||
in_addr_t broadcast_ip = htobe32(INADDR_BROADCAST);
|
||||
if ( !memcmp(src, &broadcast_ip, sizeof(in_addr_t)) )
|
||||
return false;
|
||||
// The source address must not be the subnet's broadcast (RFC 1122 3.2.1.3).
|
||||
in_addr_t if_broadcast_ip =
|
||||
netif->cfg.inet.address.s_addr | ~netif->cfg.inet.subnet.s_addr;
|
||||
if ( !memcmp(&if_broadcast_ip, src, sizeof(in_addr_t)) )
|
||||
return false;
|
||||
if ( netif->ifinfo.type != IF_TYPE_LOOPBACK )
|
||||
{
|
||||
// 127.0.0.0/8 is only for loopback.
|
||||
if ( (be32toh(src->s_addr) & INADDR_LOOPMASK) ==
|
||||
(INADDR_LOOPBACK & INADDR_LOOPMASK) ||
|
||||
(be32toh(dst->s_addr) & INADDR_LOOPMASK) ==
|
||||
(INADDR_LOOPBACK & INADDR_LOOPMASK) )
|
||||
return false;
|
||||
}
|
||||
// Receive packets sent to the broadcast address.
|
||||
*out_broadcast = false;
|
||||
if ( !memcmp(dst, &broadcast_ip, sizeof(broadcast_ip)) )
|
||||
return *out_broadcast = true, true;
|
||||
in_addr_t any_ip = htobe32(INADDR_ANY);
|
||||
// Only receive non-broadcast packets if the interface is configured.
|
||||
if ( memcmp(&netif->cfg.inet.address, &any_ip, sizeof(in_addr_t)) != 0 )
|
||||
{
|
||||
// Receive packets sent to our address.
|
||||
if ( !dst_broadcast &&
|
||||
!memcmp(&netif->cfg.inet.address, dst, sizeof(in_addr_t)) )
|
||||
return true;
|
||||
// Receive packets sent to the subnet's broadcast address.
|
||||
if ( !memcmp(&if_broadcast_ip, dst, sizeof(in_addr_t)) )
|
||||
return *out_broadcast = true, true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Handle(Ref<Packet> pkt,
|
||||
const struct ether_addr* /*src*/,
|
||||
const struct ether_addr* /*dst*/,
|
||||
bool dst_broadcast)
|
||||
{
|
||||
struct ipv4 hdr;
|
||||
size_t pkt_remain = pkt->length - pkt->offset;
|
||||
// The packet has to be large enough to contain a header.
|
||||
if ( pkt_remain < sizeof(hdr) )
|
||||
return;
|
||||
memcpy(&hdr, pkt->from + pkt->offset, sizeof(hdr));
|
||||
// Verify the header's checksum is correct.
|
||||
if ( ipsum(&hdr, sizeof(hdr)) != 0 )
|
||||
return;
|
||||
hdr.length = be16toh(hdr.length);
|
||||
hdr.identification = be16toh(hdr.identification);
|
||||
hdr.fragment = be16toh(hdr.fragment);
|
||||
hdr.checksum = be16toh(hdr.checksum);
|
||||
// Verify the packet is Internet Protocol Version 4.
|
||||
if ( IPV4_VERSION(hdr.version_ihl) != 4 )
|
||||
return;
|
||||
// Verify the relation:
|
||||
// sizeof(hdr) <= ihl <= hdr.length <= pkt_remain
|
||||
size_t ihl = 4 * IPV4_IHL(hdr.version_ihl);
|
||||
// Verify the header length isn't smaller than the minimum header.
|
||||
if ( ihl < sizeof(hdr) )
|
||||
return;
|
||||
// Verify total length isn't smaller than the header length.
|
||||
if ( hdr.length < ihl )
|
||||
return;
|
||||
// Verify the packet length isn't smaller than the datagram.
|
||||
if ( pkt_remain < hdr.length )
|
||||
return;
|
||||
// Drop the packet if we shouldn't handle it.
|
||||
bool in_dst_broadcast;
|
||||
const struct in_addr* in_src = (const struct in_addr*) &hdr.source;
|
||||
const struct in_addr* in_dst = (const struct in_addr*) &hdr.destination;
|
||||
if ( !ShouldHandlePacket(pkt, in_src, in_dst, dst_broadcast,
|
||||
&in_dst_broadcast) )
|
||||
return;
|
||||
// TODO: IP options.
|
||||
// TODO: Reassemble fragmented packets.
|
||||
if ( IPV4_FRAGMENT(hdr.fragment) )
|
||||
return;
|
||||
if ( hdr.fragment & IPV4_FRAGMENT_MORE )
|
||||
return;
|
||||
// Trim the packet to the length according to the header, in case the packet
|
||||
// was smaller than the link layer protocol's minimum transmission unit and
|
||||
// the packet was padded by zeroes.
|
||||
size_t truncated_length = pkt->offset + hdr.length;
|
||||
if ( pkt->length < truncated_length )
|
||||
return;
|
||||
pkt->length = truncated_length;
|
||||
pkt->offset += ihl;
|
||||
if ( hdr.protocol == IPPROTO_ICMP )
|
||||
Ping::HandleIP(pkt, in_src, in_dst, in_dst_broadcast);
|
||||
else if ( hdr.protocol == IPPROTO_TCP )
|
||||
TCP::HandleIP(pkt, in_src, in_dst, in_dst_broadcast);
|
||||
else if ( hdr.protocol == IPPROTO_UDP )
|
||||
UDP::HandleIP(pkt, in_src, in_dst, in_dst_broadcast);
|
||||
}
|
||||
|
||||
bool Send(Ref<Packet> pktin,
|
||||
const struct in_addr* src,
|
||||
const struct in_addr* dst,
|
||||
uint8_t protocol,
|
||||
unsigned int ifindex,
|
||||
bool broadcast)
|
||||
{
|
||||
Ref<Packet> pkt = GetPacket();
|
||||
if ( !pkt )
|
||||
return false;
|
||||
size_t mtu = pkt->pmap.size;
|
||||
if ( mtu < sizeof(struct ipv4) ||
|
||||
mtu - sizeof(struct ipv4) < pktin->length )
|
||||
return errno = EMSGSIZE, -1;
|
||||
pkt->length = sizeof(struct ipv4) + pktin->length;
|
||||
unsigned char* in = pktin->from;
|
||||
unsigned char* out = pkt->from;
|
||||
struct ipv4 hdr;
|
||||
hdr.version_ihl = IPV4_VERSION_MAKE(4) | IPV4_IHL_MAKE(5);
|
||||
hdr.dscp_ecn = 0;
|
||||
hdr.length = htobe16(pkt->length);
|
||||
hdr.identification = htobe16(0); // TODO: Assign identification to packets.
|
||||
hdr.fragment = htobe16(0);
|
||||
hdr.ttl = 0x40; // TODO: This should be configurable.
|
||||
hdr.protocol = protocol;
|
||||
hdr.checksum = 0;
|
||||
memcpy(hdr.source, src, sizeof(struct in_addr));
|
||||
memcpy(hdr.destination, dst, sizeof(struct in_addr));
|
||||
hdr.checksum = htobe16(ipsum(&hdr, sizeof(hdr)));
|
||||
memcpy(out, &hdr, sizeof(hdr));
|
||||
memcpy(out + sizeof(struct ipv4), in, pktin->length);
|
||||
|
||||
NetworkInterface* netif = LocateInterface(src, dst, ifindex);
|
||||
if ( !netif )
|
||||
return false;
|
||||
|
||||
if ( netif->ifinfo.type == IF_TYPE_LOOPBACK )
|
||||
{
|
||||
struct ether_addr localaddr;
|
||||
memset(&localaddr, 0, sizeof(localaddr));
|
||||
return Ether::Send(pkt, &localaddr, &localaddr, ETHERTYPE_IP, netif);
|
||||
}
|
||||
|
||||
if ( netif->ifinfo.type != IF_TYPE_ETHERNET )
|
||||
return errno = EAFNOSUPPORT, false;
|
||||
|
||||
kthread_mutex_lock(&netif->cfg_lock);
|
||||
in_addr_t dst_ip = dst->s_addr;
|
||||
in_addr_t address_ip = netif->cfg.inet.address.s_addr;
|
||||
in_addr_t router_ip = netif->cfg.inet.router.s_addr;
|
||||
in_addr_t subnet_ip = netif->cfg.inet.subnet.s_addr;
|
||||
in_addr_t broadcast_ip =
|
||||
netif->cfg.inet.address.s_addr | ~netif->cfg.inet.subnet.s_addr;
|
||||
struct ether_addr ether_src = netif->cfg.ether.address;
|
||||
kthread_mutex_unlock(&netif->cfg_lock);
|
||||
|
||||
struct in_addr route;
|
||||
// Route directly to the destination if the destination is broadcast.
|
||||
if ( dst_ip == htobe32(INADDR_BROADCAST) || dst_ip == broadcast_ip )
|
||||
memcpy(&route, &dst_ip, sizeof(route));
|
||||
// Route directly to the destination if the destination is on the subnet.
|
||||
else if ( (dst_ip & subnet_ip) == (address_ip & subnet_ip) &&
|
||||
dst_ip != address_ip )
|
||||
memcpy(&route, dst, sizeof(route));
|
||||
// Route to the the default route if any.
|
||||
else if ( router_ip != htobe32(INADDR_ANY) )
|
||||
memcpy(&route, &router_ip, sizeof(route));
|
||||
// Otherwise the network is unreachable.
|
||||
else
|
||||
return errno = ENETUNREACH, false;
|
||||
|
||||
// If the destination is broadcast, send an ethernet broadcast.
|
||||
if ( dst_ip == htobe32(INADDR_BROADCAST) || dst_ip == broadcast_ip )
|
||||
{
|
||||
if ( !broadcast )
|
||||
return errno = EACCES, false;
|
||||
return Ether::Send(pkt, ðer_src, ðeraddr_broadcast, ETHERTYPE_IP,
|
||||
netif);
|
||||
}
|
||||
return ARP::RouteIPEthernet(netif, pkt, &route);
|
||||
}
|
||||
|
||||
bool GetSourceIP(const struct in_addr* src,
|
||||
const struct in_addr* dst,
|
||||
struct in_addr* sendfrom,
|
||||
unsigned int ifindex,
|
||||
size_t* mtu)
|
||||
{
|
||||
NetworkInterface* netif = LocateInterface(src, dst, ifindex);
|
||||
if ( !netif )
|
||||
return false;
|
||||
ScopedLock cfg_lock(&netif->cfg_lock);
|
||||
if ( sendfrom )
|
||||
memcpy(sendfrom, &netif->cfg.inet.address, sizeof(struct in_addr));
|
||||
if ( mtu )
|
||||
*mtu = Ether::GetMTU(netif) - sizeof(struct ipv4);
|
||||
return true;
|
||||
}
|
||||
|
||||
Ref<Inode> Socket(int type, int protocol)
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case SOCK_DGRAM:
|
||||
if ( protocol == 0 || protocol == IPPROTO_UDP )
|
||||
return UDP::Socket(AF_INET);
|
||||
if ( protocol == IPPROTO_PING )
|
||||
return Ping::Socket(AF_INET);
|
||||
return errno = EPROTONOSUPPORT, Ref<Inode>(NULL);
|
||||
case SOCK_STREAM:
|
||||
if ( protocol == 0 || protocol == IPPROTO_TCP )
|
||||
return TCP::Socket(AF_INET);
|
||||
return errno = EPROTONOSUPPORT, Ref<Inode>(NULL);
|
||||
default: return errno = EPROTOTYPE, Ref<Inode>(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace IP
|
||||
} // namespace Sortix
|
55
kernel/net/ip.h
Normal file
55
kernel/net/ip.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/ip.h
|
||||
* Internet Protocol Version 4.
|
||||
*/
|
||||
|
||||
#ifndef SORTIX_NET_IP_H
|
||||
#define SORTIX_NET_IP_H
|
||||
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <sortix/kernel/packet.h>
|
||||
|
||||
namespace Sortix {
|
||||
namespace IP {
|
||||
|
||||
uint16_t ipsum(const void* bufptr, size_t size);
|
||||
uint16_t ipsum_word(uint16_t sum, uint16_t word);
|
||||
uint16_t ipsum_buf(uint16_t sum, const void* bufptr, size_t size);
|
||||
uint16_t ipsum_finish(uint16_t sum);
|
||||
void Handle(Ref<Packet> pkt,
|
||||
const struct ether_addr* src,
|
||||
const struct ether_addr* dst,
|
||||
bool dst_broadcast);
|
||||
bool Send(Ref<Packet> pkt,
|
||||
const struct in_addr* src,
|
||||
const struct in_addr* dst,
|
||||
uint8_t protocol,
|
||||
unsigned int ifindex,
|
||||
bool broadcast);
|
||||
bool GetSourceIP(const struct in_addr* src,
|
||||
const struct in_addr* dst,
|
||||
struct in_addr* sendfrom,
|
||||
unsigned int ifindex,
|
||||
size_t* mtu = NULL);
|
||||
Ref<Inode> Socket(int type, int protocol);
|
||||
|
||||
} // namespace IP
|
||||
} // namespace Sortix
|
||||
|
||||
#endif
|
154
kernel/net/lo/lo.cpp
Normal file
154
kernel/net/lo/lo.cpp
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/lo/lo.cpp
|
||||
* Loopback device.
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sortix/kernel/ioctx.h>
|
||||
#include <sortix/kernel/kernel.h>
|
||||
#include <sortix/kernel/kthread.h>
|
||||
#include <sortix/kernel/if.h>
|
||||
#include <sortix/kernel/worker.h>
|
||||
|
||||
#include "../ether.h"
|
||||
|
||||
#include "lo.h"
|
||||
|
||||
// The loopback device currently communicates through the Ethernet layer and
|
||||
// pretends to do offload Ethernet checksumming as an optimization.
|
||||
|
||||
// The shared worker thread is used for processing. Whenever a packet needs to
|
||||
// be sent, if the worker thread isn't scheduled, it is scheduled. The worker
|
||||
// thread transmits all the packets that were in the queue when it begins, but
|
||||
// not any more than that. If any work remains at the end, it schedules itself
|
||||
// again to run later (to avoid starving other tasks using the shared worker
|
||||
// thread). The packet queue is a singly linked list of packets.
|
||||
|
||||
namespace Sortix {
|
||||
namespace Loopback {
|
||||
|
||||
class Loopback : public NetworkInterface
|
||||
{
|
||||
friend void Loopback__Recv(void* ctx);
|
||||
|
||||
public:
|
||||
Loopback();
|
||||
~Loopback();
|
||||
|
||||
public:
|
||||
bool Send(Ref<Packet> pkt);
|
||||
|
||||
private:
|
||||
void Recv();
|
||||
|
||||
private:
|
||||
kthread_mutex_t socket_lock;
|
||||
Ref<Packet> first_packet;
|
||||
Ref<Packet> last_packet;
|
||||
bool worker_scheduled;
|
||||
|
||||
};
|
||||
|
||||
Loopback::Loopback()
|
||||
{
|
||||
ifinfo.type = IF_TYPE_LOOPBACK;
|
||||
ifinfo.features = IF_FEATURE_ETHERNET_CRC_OFFLOAD;
|
||||
ifinfo.addrlen = 0;
|
||||
ifstatus.flags = IF_STATUS_FLAGS_UP;
|
||||
cfg.inet.address.s_addr = htobe32(INADDR_LOOPBACK);
|
||||
cfg.inet.router.s_addr = htobe32(INADDR_ANY);
|
||||
cfg.inet.subnet.s_addr = htobe32(INADDR_LOOPMASK);
|
||||
socket_lock = KTHREAD_MUTEX_INITIALIZER;
|
||||
// first_packet initialized by constructor
|
||||
// last_packet initialized by constructor
|
||||
worker_scheduled = false;
|
||||
}
|
||||
|
||||
Loopback::~Loopback()
|
||||
{
|
||||
// Avoid stack overflow in first_packet recursive destructor.
|
||||
while ( first_packet )
|
||||
{
|
||||
Ref<Packet> next = first_packet->next;
|
||||
first_packet->next.Reset();
|
||||
first_packet = next;
|
||||
}
|
||||
last_packet.Reset();
|
||||
}
|
||||
|
||||
void Loopback__Recv(void* ctx)
|
||||
{
|
||||
((Loopback*) ctx)->Recv();
|
||||
}
|
||||
|
||||
void Loopback::Recv()
|
||||
{
|
||||
kthread_mutex_lock(&socket_lock);
|
||||
Ref<Packet> next_packet = first_packet;
|
||||
first_packet.Reset();
|
||||
last_packet.Reset();
|
||||
kthread_mutex_unlock(&socket_lock);
|
||||
while ( next_packet )
|
||||
{
|
||||
Ref<Packet> packet = next_packet;
|
||||
next_packet = next_packet->next;
|
||||
packet->next.Reset();
|
||||
packet->netif = this;
|
||||
Ether::Handle(packet, true);
|
||||
}
|
||||
kthread_mutex_lock(&socket_lock);
|
||||
bool should_schedule = first_packet;
|
||||
if ( !should_schedule )
|
||||
worker_scheduled = false;
|
||||
kthread_mutex_unlock(&socket_lock);
|
||||
if ( should_schedule )
|
||||
Worker::Schedule(Loopback__Recv, this);
|
||||
}
|
||||
|
||||
bool Loopback::Send(Ref<Packet> pkt)
|
||||
{
|
||||
kthread_mutex_lock(&socket_lock);
|
||||
if ( last_packet )
|
||||
last_packet->next = pkt;
|
||||
else
|
||||
first_packet = pkt;
|
||||
last_packet = pkt;
|
||||
bool should_schedule = !worker_scheduled;
|
||||
worker_scheduled = true;
|
||||
kthread_mutex_unlock(&socket_lock);
|
||||
if ( should_schedule )
|
||||
Worker::Schedule(Loopback__Recv, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Init(const char* /*devpath*/, Ref<Descriptor> dev)
|
||||
{
|
||||
Loopback* lo = new Loopback();
|
||||
if ( !lo )
|
||||
PanicF("Failed to allocate loopback device");
|
||||
size_t index = 0;
|
||||
snprintf(lo->ifinfo.name, sizeof(lo->ifinfo.name), "lo%zu", index);
|
||||
if ( !RegisterNetworkInterface(lo, dev) )
|
||||
PanicF("Failed to register %s as network interface", lo->ifinfo.name);
|
||||
}
|
||||
|
||||
} // namespace Loopback
|
||||
} // namespace Sortix
|
33
kernel/net/lo/lo.h
Normal file
33
kernel/net/lo/lo.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/lo/lo.h
|
||||
* Loopback device.
|
||||
*/
|
||||
|
||||
#ifndef SORTIX_NET_LO_LO_H
|
||||
#define SORTIX_NET_LO_LO_H
|
||||
|
||||
#include <sortix/kernel/descriptor.h>
|
||||
|
||||
namespace Sortix {
|
||||
namespace Loopback {
|
||||
|
||||
void Init(const char* devpath, Ref<Descriptor> dev);
|
||||
|
||||
} // namespace Loopback
|
||||
} // namespace Sortix
|
||||
|
||||
#endif
|
104
kernel/net/packet.cpp
Normal file
104
kernel/net/packet.cpp
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Meisaka Yukara.
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/packet.cpp
|
||||
* Reference counted network packets.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sortix/kernel/kernel.h>
|
||||
#include <sortix/kernel/kthread.h>
|
||||
#include <sortix/kernel/memorymanagement.h>
|
||||
#include <sortix/kernel/packet.h>
|
||||
#include <sortix/kernel/pci-mmio.h>
|
||||
|
||||
namespace Sortix {
|
||||
|
||||
// Limit the memory usage of network packets to this fraction of total memory.
|
||||
// This constant is documented in if(4) under NOTES.
|
||||
static const size_t MAX_PACKET_FRACTION = 16;
|
||||
|
||||
// Keep this amount of virtually mapped buffers around at all times.
|
||||
// This constant is documented in if(4) under NOTES.
|
||||
static const size_t PACKET_CACHE_TARGET_SIZE = 384;
|
||||
|
||||
// A cache of physical memory allocations for quick allocation to new packets.
|
||||
static kthread_mutex_t packet_cache_lock = KTHREAD_MUTEX_INITIALIZER;
|
||||
static paddrmapped_t* packet_cache = NULL;
|
||||
static size_t packet_cache_used = 0;
|
||||
static size_t packet_cache_allocated = 0;
|
||||
static size_t packet_count = 0;
|
||||
|
||||
Packet::Packet(paddrmapped_t _pmap) : pmap(_pmap)
|
||||
{
|
||||
from = (unsigned char*) pmap.from;
|
||||
length = 0;
|
||||
offset = 0;
|
||||
netif = NULL;
|
||||
packet_count++;
|
||||
}
|
||||
|
||||
Packet::~Packet()
|
||||
{
|
||||
// Refuse to do recursive destructor calls that could stack overflow.
|
||||
assert(!next);
|
||||
ScopedLock lock(&packet_cache_lock);
|
||||
if ( packet_cache_used < packet_cache_allocated )
|
||||
packet_cache[packet_cache_used++] = pmap;
|
||||
else
|
||||
FreeAllocatedAndMappedPage(&pmap);
|
||||
packet_count--;
|
||||
}
|
||||
|
||||
Ref<Packet> GetPacket()
|
||||
{
|
||||
ScopedLock lock(&packet_cache_lock);
|
||||
if ( packet_cache == NULL )
|
||||
{
|
||||
size_t new_allocated = PACKET_CACHE_TARGET_SIZE;
|
||||
packet_cache = new paddrmapped_t[new_allocated];
|
||||
if ( !packet_cache )
|
||||
return errno = ENOBUFS, Ref<Packet>(NULL);
|
||||
packet_cache_allocated = new_allocated;
|
||||
}
|
||||
paddrmapped_t pmap;
|
||||
// Fast reuse of an existing physical allocation if available.
|
||||
if ( 0 < packet_cache_used )
|
||||
pmap = packet_cache[--packet_cache_used];
|
||||
// Otherwise make a new physical allocation for the packet.
|
||||
else
|
||||
{
|
||||
size_t total_memory;
|
||||
Memory::Statistics(NULL, &total_memory);
|
||||
size_t total_pages = total_memory / Page::Size();
|
||||
size_t max_packets = total_pages / MAX_PACKET_FRACTION;
|
||||
if ( max_packets <= packet_count )
|
||||
return errno = ENOBUFS, Ref<Packet>(NULL);
|
||||
if ( !AllocateAndMapPage(&pmap, PAGE_USAGE_NETWORK_PACKET) )
|
||||
return errno = ENOBUFS, Ref<Packet>(NULL);
|
||||
}
|
||||
Ref<Packet> pkt = Ref<Packet>(new Packet(pmap));
|
||||
if ( !pkt )
|
||||
{
|
||||
FreeAllocatedAndMappedPage(&pmap);
|
||||
return errno = ENOBUFS, Ref<Packet>(NULL);
|
||||
}
|
||||
return pkt;
|
||||
}
|
||||
|
||||
} // namespace Sortix
|
1271
kernel/net/ping.cpp
Normal file
1271
kernel/net/ping.cpp
Normal file
File diff suppressed because it is too large
Load diff
41
kernel/net/ping.h
Normal file
41
kernel/net/ping.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/ping.h
|
||||
* Internet Control Message Protocol Echo.
|
||||
*/
|
||||
|
||||
#ifndef SORTIX_NET_PING_H
|
||||
#define SORTIX_NET_PING_H
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <sortix/kernel/inode.h>
|
||||
#include <sortix/kernel/packet.h>
|
||||
|
||||
namespace Sortix {
|
||||
namespace Ping {
|
||||
|
||||
void Init();
|
||||
void HandleIP(Ref<Packet> pkt,
|
||||
const struct in_addr* src,
|
||||
const struct in_addr* dst,
|
||||
bool dst_broadcast);
|
||||
Ref<Inode> Socket(int af);
|
||||
|
||||
} // namespace Ping
|
||||
} // namespace Sortix
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -30,6 +30,7 @@
|
|||
#include <sortix/kernel/vnode.h>
|
||||
|
||||
#include "fs.h"
|
||||
#include "ip.h"
|
||||
|
||||
namespace Sortix {
|
||||
|
||||
|
@ -37,6 +38,7 @@ static Ref<Inode> CreateSocket(int domain, int type, int protocol)
|
|||
{
|
||||
switch ( domain )
|
||||
{
|
||||
case AF_INET: return IP::Socket(type, protocol);
|
||||
case AF_UNIX: return NetFS::Socket(type, protocol);
|
||||
default: return errno = EAFNOSUPPORT, Ref<Inode>(NULL);
|
||||
}
|
||||
|
|
2570
kernel/net/tcp.cpp
Normal file
2570
kernel/net/tcp.cpp
Normal file
File diff suppressed because it is too large
Load diff
41
kernel/net/tcp.h
Normal file
41
kernel/net/tcp.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/tcp.h
|
||||
* Transmission Control Protocol.
|
||||
*/
|
||||
|
||||
#ifndef SORTIX_NET_TCP_H
|
||||
#define SORTIX_NET_TCP_H
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <sortix/kernel/inode.h>
|
||||
#include <sortix/kernel/packet.h>
|
||||
|
||||
namespace Sortix {
|
||||
namespace TCP {
|
||||
|
||||
void Init();
|
||||
void HandleIP(Ref<Packet> pkt,
|
||||
const struct in_addr* src,
|
||||
const struct in_addr* dst,
|
||||
bool dst_broadcast);
|
||||
Ref<Inode> Socket(int af);
|
||||
|
||||
} // namespace TCP
|
||||
} // namespace Sortix
|
||||
|
||||
#endif
|
1263
kernel/net/udp.cpp
Normal file
1263
kernel/net/udp.cpp
Normal file
File diff suppressed because it is too large
Load diff
41
kernel/net/udp.h
Normal file
41
kernel/net/udp.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/udp.h
|
||||
* User Datagram Protocol.
|
||||
*/
|
||||
|
||||
#ifndef SORTIX_NET_UDP_H
|
||||
#define SORTIX_NET_UDP_H
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <sortix/kernel/inode.h>
|
||||
#include <sortix/kernel/packet.h>
|
||||
|
||||
namespace Sortix {
|
||||
namespace UDP {
|
||||
|
||||
void Init();
|
||||
void HandleIP(Ref<Packet> pkt,
|
||||
const struct in_addr* src,
|
||||
const struct in_addr* dst,
|
||||
bool dst_broadcast);
|
||||
Ref<Inode> Socket(int af);
|
||||
|
||||
} // namespace UDP
|
||||
} // namespace Sortix
|
||||
|
||||
#endif
|
|
@ -57,6 +57,7 @@ malloc/heap_init.o \
|
|||
malloc/__heap_lock.o \
|
||||
malloc/__heap_unlock.o \
|
||||
malloc/__heap_verify.o \
|
||||
netinet/if_ether/etheraddr_broadcast.o \
|
||||
netinet/in/in6addr_any.o \
|
||||
netinet/in/in6addr_loopback.o \
|
||||
regex/regcomp.o \
|
||||
|
|
77
libc/include/net/if.h
Normal file
77
libc/include/net/if.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* net/if.h
|
||||
* Network interface.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_NET_IF_H
|
||||
#define _INCLUDE_NET_IF_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#define IF_NAMESIZE 32
|
||||
|
||||
#if __USE_SORTIX
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define IF_HWADDR_MAXSIZE 6
|
||||
|
||||
#define IF_TYPE_LOOPBACK 1
|
||||
#define IF_TYPE_ETHERNET 2
|
||||
|
||||
#define IF_FEATURE_ETHERNET_CRC_OFFLOAD (1 << 0)
|
||||
|
||||
struct if_info
|
||||
{
|
||||
unsigned int linkid;
|
||||
int type;
|
||||
int features;
|
||||
size_t addrlen;
|
||||
char name[IF_NAMESIZE];
|
||||
unsigned char addr[IF_HWADDR_MAXSIZE];
|
||||
};
|
||||
|
||||
#define IF_STATUS_FLAGS_UP (1 << 0)
|
||||
|
||||
struct if_status
|
||||
{
|
||||
int flags;
|
||||
size_t mtu;
|
||||
};
|
||||
|
||||
struct if_config_ether
|
||||
{
|
||||
struct ether_addr address;
|
||||
};
|
||||
|
||||
struct if_config_inet
|
||||
{
|
||||
struct in_addr address;
|
||||
struct in_addr router;
|
||||
struct in_addr subnet;
|
||||
};
|
||||
|
||||
struct if_config
|
||||
{
|
||||
struct if_config_ether ether;
|
||||
struct if_config_inet inet;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
71
libc/include/netinet/if_ether.h
Normal file
71
libc/include/netinet/if_ether.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* netinet/if_ether.h
|
||||
* Ethernet interfaces.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_NETINET_IF_ETHER_H
|
||||
#define _INCLUDE_NETINET_IF_ETHER_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ETHER_ADDR_LEN 6
|
||||
#define ETHER_TYPE_LEN 2
|
||||
#define ETHER_HDR_LEN (ETHER_ADDR_LEN + ETHER_ADDR_LEN + ETHER_TYPE_LEN) /* 14 */
|
||||
#define ETHER_CRC_LEN 4
|
||||
#define ETHER_LEN (ETHER_HDR_LEN + ETHER_CRC_LEN) /* 18 */
|
||||
#define ETHER_MIN_LEN 64
|
||||
#define ETHER_MAX_LEN 1518
|
||||
|
||||
#define ETHERMTU (ETHER_MAX_LEN - ETHER_LEN) /* 1500 */
|
||||
#define ETHERMIN (ETHER_MIN_LEN - ETHER_LEN) /* 46 */
|
||||
|
||||
#define ETHERADDR_BROADCAST_INIT { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }
|
||||
|
||||
#define ETHERTYPE_IP 0x0800
|
||||
#define ETHERTYPE_ARP 0x0806
|
||||
#define ETHERTYPE_IPV6 0x86dd
|
||||
|
||||
struct ether_addr
|
||||
{
|
||||
uint8_t ether_addr_octet[ETHER_ADDR_LEN];
|
||||
};
|
||||
|
||||
struct ether_header
|
||||
{
|
||||
uint8_t ether_dhost[ETHER_ADDR_LEN];
|
||||
uint8_t ether_shost[ETHER_ADDR_LEN];
|
||||
uint16_t ether_type;
|
||||
};
|
||||
|
||||
struct ether_footer
|
||||
{
|
||||
uint32_t ether_crc;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const struct ether_addr etheraddr_broadcast; /* ff:ff:ff:ff:ff:ff */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2014, 2015 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2013, 2014, 2015, 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -23,14 +23,11 @@
|
|||
#include <sys/cdefs.h>
|
||||
|
||||
#include <sys/__/types.h>
|
||||
|
||||
#include <__/endian.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __in_port_t_defined
|
||||
#define __in_port_t_defined
|
||||
typedef uint16_t in_port_t;
|
||||
|
@ -43,7 +40,7 @@ typedef uint32_t in_addr_t;
|
|||
|
||||
#ifndef __sa_family_t_defined
|
||||
#define __sa_family_t_defined
|
||||
typedef unsigned short int sa_family_t;
|
||||
typedef uint16_t sa_family_t;
|
||||
#endif
|
||||
|
||||
#ifndef __socklen_t_defined
|
||||
|
@ -77,8 +74,6 @@ struct sockaddr_in6
|
|||
uint32_t sin6_scope_id;
|
||||
};
|
||||
|
||||
extern const struct in6_addr in6addr_any; /* :: */
|
||||
extern const struct in6_addr in6addr_loopback; /* ::1 */
|
||||
#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }
|
||||
#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } }
|
||||
|
||||
|
@ -90,16 +85,20 @@ struct ipv6_mreq
|
|||
|
||||
/* #define SOL_SOCKET 0 - in <sys/socket.h> */
|
||||
#define IPPROTO_ICMP 1
|
||||
#define IPPROTO_IP 2
|
||||
#define IPPROTO_IPV6 3
|
||||
#define IPPROTO_RAW 4
|
||||
#define IPPROTO_TCP 5
|
||||
#define IPPROTO_UDP 6
|
||||
#define IPPROTO_TCP 6
|
||||
#define IPPROTO_UDP 17
|
||||
#define IPPROTO_RAW 255
|
||||
#define IPPROTO_IP 256
|
||||
#define IPPROTO_IPV6 257
|
||||
#define IPPROTO_PING 258
|
||||
|
||||
#define INADDR_ANY ((in_addr_t) 0x00000000)
|
||||
#define INADDR_BROADCAST ((in_addr_t) 0xffffffff)
|
||||
#define INADDR_NONE ((in_addr_t) 0xffffffff)
|
||||
#define INADDR_LOOPBACK ((in_addr_t) 0x7f000001)
|
||||
#define INADDR_ANY ((in_addr_t) 0x00000000) /* 0.0.0.0 */
|
||||
#define INADDR_BROADCAST ((in_addr_t) 0xffffffff) /* 255.255.255.255 */
|
||||
#define INADDR_LOOPBACK ((in_addr_t) 0x7f000001) /* 127.0.0.1 */
|
||||
#define INADDR_NONE ((in_addr_t) 0xffffffff) /* 255.255.255.255 */
|
||||
#if __USE_SORTIX
|
||||
#define INADDR_LOOPMASK ((in_addr_t) 0xff000000) /* 255.0.0.0 */
|
||||
#endif
|
||||
|
||||
#define INADDR_UNSPEC_GROUP ((in_addr_t) 0xe0000000)
|
||||
#define INADDR_ALLHOSTS_GROUP ((in_addr_t) 0xe0000001)
|
||||
|
@ -178,6 +177,15 @@ struct ipv6_mreq
|
|||
|
||||
#define IN_LOOPBACKNET 127
|
||||
|
||||
#define IP_EVIL_INTENT 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const struct in6_addr in6addr_any; /* :: */
|
||||
extern const struct in6_addr in6addr_loopback; /* ::1 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
|
27
libc/include/netinet/ping.h
Normal file
27
libc/include/netinet/ping.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* netinet/ping.h
|
||||
* Internet Control Message Protocol Echo.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_NETINET_PING_H
|
||||
#define _INCLUDE_NETINET_PING_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#endif
|
|
@ -14,7 +14,7 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* netinet/tcp.h
|
||||
* Definitions for the Internet Transmission Control Protocol.
|
||||
* Transmission Control Protocol.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_NETINET_TCP_H
|
||||
|
@ -22,6 +22,69 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#if __USE_SORTIX
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#if __USE_SORTIX
|
||||
typedef uint32_t tcp_seq; /* TCP sequence number. */
|
||||
|
||||
/* Control Bits in struct tcphdr th_flags. */
|
||||
#define TH_FIN (1 << 0) /* No more data from sender. */
|
||||
#define TH_SYN (1 << 1) /* Synchronize sequence numbers. */
|
||||
#define TH_RST (1 << 2) /* Reset the connection. */
|
||||
#define TH_PUSH (1 << 3) /* Push Function. */
|
||||
#define TH_ACK (1 << 4) /* Acknowledgment field significant. */
|
||||
#define TH_URG (1 << 5) /* Urgent Pointer field significant. */
|
||||
|
||||
struct tcphdr
|
||||
{
|
||||
in_port_t th_sport; /* Source Port. */
|
||||
in_port_t th_dport; /* Destination Port. */
|
||||
tcp_seq th_seq; /* Sequence Number. */
|
||||
tcp_seq th_ack; /* Acknowledgment Number. */
|
||||
__extension__ union
|
||||
{
|
||||
__extension__ struct
|
||||
{
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
uint8_t th_x2:4; /* Reserved. */
|
||||
uint8_t th_off:4; /* Data offset. */
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
uint8_t th_off:4; /* Data offset. */
|
||||
uint8_t th_x2:4; /* Reserved. */
|
||||
#else
|
||||
#warning "You need to add support for your endian"
|
||||
#endif
|
||||
};
|
||||
uint8_t th_offset;
|
||||
};
|
||||
uint8_t th_flags; /* Control Bits. */
|
||||
uint16_t th_win; /* Window. */
|
||||
uint16_t th_sum; /* Checksum. */
|
||||
uint16_t th_urp; /* Urgent Pointer. */
|
||||
};
|
||||
|
||||
#define TCP_OFFSET_ENCODE(x) (((x) & 0xF) << 4) /* Encode th_offset. */
|
||||
#define TCP_OFFSET_DECODE(x) (((x) >> 4) & 0xF) /* Decode th_offset. */
|
||||
|
||||
#define TCP_MSS 536 /* Default Maximum Segment Size. */
|
||||
|
||||
#define TCPOPT_EOL 0 /* End of Option List. */
|
||||
#define TCPOPT_NOP 1 /* No-Operation. */
|
||||
|
||||
#define TCPOPT_MAXSEG 2 /* Maximum Segment Size. */
|
||||
#define TCPOLEN_MAXSEG 4 /* Length of Maximum Segment Size. */
|
||||
|
||||
/* Maximum header size: 16 * 4 bytes */
|
||||
#define TCP_MAXHLEN 64
|
||||
|
||||
/* Maximum total length of options. */
|
||||
#define TCP_MAXOLEN (TCP_MAXHLEN - sizeof(struct tcphdr))
|
||||
|
||||
#define TCP_MAXWIN 65535 /* Maximum window size. */
|
||||
#endif
|
||||
|
||||
/* Options at the IPPROTO_TCP socket level. */
|
||||
#define TCP_NODELAY 1
|
||||
#if __USE_SORTIX
|
||||
|
|
35
libc/include/netinet/udp.h
Normal file
35
libc/include/netinet/udp.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* netinet/udp.h
|
||||
* User Datagram Protocol.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_NETINET_UDP_H
|
||||
#define _INCLUDE_NETINET_UDP_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
struct udphdr
|
||||
{
|
||||
in_port_t uh_sport; /* Source Port */
|
||||
in_port_t uh_dport; /* Destination Port */
|
||||
uint16_t uh_ulen; /* Length */
|
||||
uint16_t uh_sum; /* Checksum */
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2014 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2013, 2014, 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -24,11 +24,9 @@
|
|||
|
||||
#include <sys/__/types.h>
|
||||
|
||||
#include <sortix/socket.h>
|
||||
#include <__/stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <sortix/socket.h>
|
||||
|
||||
#ifndef __socklen_t_defined
|
||||
#define __socklen_t_defined
|
||||
|
@ -48,19 +46,11 @@ typedef __ssize_t ssize_t;
|
|||
|
||||
#ifndef __sa_family_t_defined
|
||||
#define __sa_family_t_defined
|
||||
typedef unsigned short int sa_family_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
typedef __uint16_t sa_family_t;
|
||||
#endif
|
||||
|
||||
#include <sortix/uio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct sockaddr
|
||||
{
|
||||
sa_family_t sa_family;
|
||||
|
@ -139,8 +129,14 @@ struct linger
|
|||
#define SO_SNDLOWAT 14
|
||||
#define SO_SNDTIMEO 15
|
||||
#define SO_TYPE 16
|
||||
#if __USE_SORTIX
|
||||
#define SO_BINDTOINDEX 17
|
||||
#define SO_BINDTODEVICE 18
|
||||
#define SO_DOMAIN 19
|
||||
#define SO_PROTOCOL 20
|
||||
#endif
|
||||
|
||||
#define SOMAXCONN 5
|
||||
#define SOMAXCONN 128
|
||||
|
||||
#define MSG_CTRUNC (1<<0)
|
||||
#define MSG_DONTROUTE (1<<1)
|
||||
|
@ -174,6 +170,10 @@ struct linger
|
|||
#define SHUT_WR (1 << 1)
|
||||
#define SHUT_RDWR (SHUT_RD | SHUT_WR)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int accept4(int, struct sockaddr* __restrict, socklen_t* __restrict, int);
|
||||
int accept(int, struct sockaddr* __restrict, socklen_t* __restrict);
|
||||
int bind(int, const struct sockaddr*, socklen_t);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2013, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -24,13 +24,15 @@
|
|||
|
||||
#include <sys/__/types.h>
|
||||
|
||||
#include <__/stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __sa_family_t_defined
|
||||
#define __sa_family_t_defined
|
||||
typedef unsigned short int sa_family_t;
|
||||
typedef __uint16_t sa_family_t;
|
||||
#endif
|
||||
|
||||
struct sockaddr_un
|
||||
|
|
22
libc/netinet/if_ether/etheraddr_broadcast.c
Normal file
22
libc/netinet/if_ether/etheraddr_broadcast.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*
|
||||
* netinet/if_ether/etheraddr_broadcast.c
|
||||
* Ethernet broadcast address.
|
||||
*/
|
||||
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
const struct ether_addr etheraddr_broadcast = ETHERADDR_BROADCAST_INIT;
|
|
@ -118,6 +118,8 @@ does not match the size of the address corresponding to
|
|||
.Fa family .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr inet 4 ,
|
||||
.Xr inet6 4 ,
|
||||
.Xr dnsconfig 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
|
|
103
share/man/man4/arp.4
Normal file
103
share/man/man4/arp.4
Normal file
|
@ -0,0 +1,103 @@
|
|||
.Dd June 5, 2017
|
||||
.Dt ARP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm arp
|
||||
.Nd address resolution protocol
|
||||
.Sh SYNOPSIS
|
||||
.In netinet/if_ether.h
|
||||
.In netinet/in.h
|
||||
.Sh DESCRIPTION
|
||||
The Address Resolution Protocol (ARP) provides resolution of network layer
|
||||
addresses to link layer addresses on the local network.
|
||||
ARP requests asks for the link layer address of a network layer address and ARP
|
||||
replies contains the link layer address of the requested network layer
|
||||
address.
|
||||
Requests are broadcast on the local network, while replies are unicast back to
|
||||
the sending machine.
|
||||
.Pp
|
||||
The
|
||||
.Xr kernel 7
|
||||
uses the ARP to resolve Internet Protocol version 4 addresses
|
||||
.Xr ( inet 4 )
|
||||
to Ethernet addresses
|
||||
.Xr ( ether 4 )
|
||||
in order to transmit Internet Protocol version 4
|
||||
.Xr ( ip 4 )
|
||||
datagrams on Ethernet network interfaces
|
||||
.Xr ( if 4 ) .
|
||||
.Pp
|
||||
The
|
||||
.Xr kernel 7
|
||||
maintains a cache of ARP replies for every network interface, which is actively
|
||||
populated whenever there is a need to transmit to a network layer address, and
|
||||
passively populated with the source addresses of ARP requests from other hosts.
|
||||
Network layer datagrams are queued whenever a network layer address needs to
|
||||
be resolved.
|
||||
Queued datagrams are transmitted when the destination link layer address has
|
||||
been resolved, or are discarded if the resolution times out.
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
The transmission queue is limited to 16 packets for each network layer address.
|
||||
.Pp
|
||||
ARP requests are attempted three times, each attempt timing out after a second.
|
||||
If each request fails, the cache entry is evicted.
|
||||
.Pp
|
||||
When an network address is resolved, its cache entry remains valid for 60
|
||||
seconds.
|
||||
Upon expiry, if the cache entry was unused, it is evicted.
|
||||
Otherwise, its network address is renewed by resolving it again with three
|
||||
attempts.
|
||||
In the meanwhile, the entry cache continues to be used for routing.
|
||||
If the renewal fails, the cache entry is evicted.
|
||||
.Pp
|
||||
The ARP cache can contain up to 256 entries.
|
||||
If the cache is full,
|
||||
the least recently used cache entry is evicted when a network address is resolved
|
||||
that is not currently in the cache, and the source addresses from received ARP
|
||||
messages are not passively added to the cache.
|
||||
.Pp
|
||||
The ARP cache uses a hash table with 256 entries, using a linked list in case
|
||||
of hash collisions.
|
||||
The hash is the the bytewise xor (exclusive or) of every byte in the network
|
||||
address.
|
||||
This hash is perfect if the subnet contains no more than 256 addresses, and
|
||||
degrades in quality for larger subnets, at worst needing to linearly scan the
|
||||
whole ARP cache.
|
||||
.Pp
|
||||
The ARP cache is purged when the network interface's
|
||||
.Xr ether 4
|
||||
or
|
||||
.Xr inet 4
|
||||
configuration changes.
|
||||
Packets in the ARP transmission queue are dropped.
|
||||
.Sh SEE ALSO
|
||||
.Xr ether 4 ,
|
||||
.Xr if 4 ,
|
||||
.Xr inet 4 ,
|
||||
.Xr kernel 7
|
||||
.Sh STANDARDS
|
||||
.Rs
|
||||
.%A D. Plummer
|
||||
.%D November 1982
|
||||
.%R STD 37
|
||||
.%R RFC 826
|
||||
.%T \&An Ethernet Address Resolution Protocol
|
||||
.Re
|
||||
.Sh BUGS
|
||||
The ARP timeout is not configurable.
|
||||
.Sh SECURITY CONSIDERATIONS
|
||||
The source network layer and source link layer addresses of received ARP request
|
||||
and replies are trusted.
|
||||
If the router does not validate ARP messages on the network are consistent with
|
||||
the DHCP leases, an attacker will be able to engage in an ARP spoofing attack
|
||||
that would allow denial of service, man in the middle, and session hijacking
|
||||
attacks.
|
||||
.Pp
|
||||
The cache is limited to 256 entries per interface and if the local subnet is
|
||||
larger than 256 addresses, then if an attacker is capable of making the local
|
||||
system concurrently transmit to 256 addresses on the local network not currently
|
||||
in the ARP cache, then doing so would purge the whole transmission queue.
|
||||
If the attacker can do this faster than the machines on the local network can
|
||||
answer ARP requests, transmission service may be denied entirely, or at the
|
||||
least be significantly degraded as the higher layers wait a little while before
|
||||
they retransmit.
|
173
share/man/man4/ether.4
Normal file
173
share/man/man4/ether.4
Normal file
|
@ -0,0 +1,173 @@
|
|||
.Dd June 6, 2017
|
||||
.Dt ETHER 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ether
|
||||
.Nd ethernet
|
||||
.Sh SYNOPSIS
|
||||
.In netinet/if_ether.h
|
||||
.Bd -literal
|
||||
struct ether_addr {
|
||||
uint8_t ether_addr_octet[ETHER_ADDR_LEN /* 6 */];
|
||||
};
|
||||
|
||||
struct ether_header {
|
||||
uint8_t ether_dhost[ETHER_ADDR_LEN /* 6 */];
|
||||
uint8_t ether_shost[ETHER_ADDR_LEN /* 6 */];
|
||||
uint16_t ether_type;
|
||||
};
|
||||
|
||||
struct ether_footer {
|
||||
uint32_t ether_crc;
|
||||
};
|
||||
.Ed
|
||||
.Sh DESCRIPTION
|
||||
The Ethernet is a physical and link layer protocol for datagram exchange on a
|
||||
local area network.
|
||||
An Ethernet packet contains an Ethernet frame that contains a datagram of a
|
||||
higher level protocol.
|
||||
Ethernet 2.0 framing is implemented.
|
||||
IEEE Std 802.3 Ethernet framing is intentionally not implemented.
|
||||
.Pp
|
||||
Ethernet hosts are addressed with a globally unique six byte address assigned to
|
||||
the network interface controller.
|
||||
An Ethernet address can be stored in the
|
||||
.Vt struct ether_addr
|
||||
type.
|
||||
Ethernet addresses are notated in hexadecimal form interspaced with colons,
|
||||
e.g. 00:00:5e:00:53:ff.
|
||||
The Ethernet addresses in the range from 00:00:5e:00:53:00 (inclusive) to
|
||||
00:00:5e:00:53:ff (inclusive) are reserved for documentation.
|
||||
The address with all bits set
|
||||
.Pq ff:ff:ff:ff:ff:ff
|
||||
is the broadcast address and can be conveniently accessed using the
|
||||
.Xr etheraddr_broadcast 3
|
||||
which is initialized to
|
||||
.Dv ETHERADDR_BROADCAST_INIT .
|
||||
.Pp
|
||||
Ethernet packets are transmitted starting with an eight-byte start-of-frame
|
||||
preamble, followed by the Ethernet frame itself, ending with a twelve-byte
|
||||
interpacket gap.
|
||||
Ethernet 2.0 frames consist of a header, a datagram payload, and a frame check
|
||||
sequence.
|
||||
Frames are at least 64 bytes and are at most 1518 bytes.
|
||||
With 18 bytes of Ethernet frame overhead, the minimum transmission unit of the
|
||||
payload datagram is 46 bytes and the maximum transmission unit is 1500 bytes.
|
||||
The size of the frame is implicitly determined by the interpacket gap.
|
||||
The header has the format of
|
||||
.Vt struct ether_header ,
|
||||
starting with the destination host address
|
||||
.Pq Va ether_dhost ,
|
||||
followed by the source host address
|
||||
.Pq Va ether_shost ,
|
||||
ending with a big-endian 16-bit EtherType value denoting the protocol associated
|
||||
with the payload datagram
|
||||
.Pq Va ether_type .
|
||||
The frame check sequence has the format of
|
||||
.Vt struct ether_footer ,
|
||||
being a 32-bit cyclic redundancy checksum of the frame except the checksum
|
||||
itself
|
||||
.Pq Va ether_crc .
|
||||
.Pp
|
||||
Frames are discarded on receipt if the destination address is neither the local
|
||||
address nor the broadcast address, if the source address is the broadcast
|
||||
address, or if the checksum is invalid.
|
||||
.Pp
|
||||
Network layer addresses can be resolved to Ethernet addresses using the
|
||||
Address Resolution Protocol
|
||||
.Xr arp 4 .
|
||||
.Pp
|
||||
The
|
||||
.Va ether_type
|
||||
field denotes the payload datagram protocol and the following values are
|
||||
supported:
|
||||
.Bl -tag -width "12345678"
|
||||
.It Dv ETHERTYPE_IP Pq Li 0x0800
|
||||
The Internet Protocol version 4
|
||||
.Xr ip 4 .
|
||||
.It Dv ETHERTYPE_ARP Pq Li 0x0806
|
||||
The Address Resolution Protocol
|
||||
.Xr arp 4 .
|
||||
.El
|
||||
.Pp
|
||||
The following constants are defined in
|
||||
.In netinet/if_ether.h :
|
||||
.Bl -tag -width "12345678"
|
||||
.It Dv ETHER_ADDR_LEN Li 6
|
||||
The size of an Ethernet address in bytes.
|
||||
.It Dv ETHER_TYPE_LEN Li 2
|
||||
The size of the type field in the Ethernet header in bytes.
|
||||
.It Dv ETHER_HDR_LEN Li 14
|
||||
The size of the Ethernet header in bytes.
|
||||
.It Dv ETHER_CRC_LEN Li 4
|
||||
The size of the Ethernet frame check sequence in bytes.
|
||||
.It Dv ETHER_LEN Li 18
|
||||
The total size of the Ethernet header and the frame check sequence in bytes.
|
||||
.It Dv ETHER_MIN_LEN Li 64
|
||||
The minimum size of Ethernet frames.
|
||||
.It Dv ETHER_MAX_LEN Li 1518
|
||||
The maximum size of Ethernet frames.
|
||||
.It Dv ETHERMTU Li 1500
|
||||
The maximum transmission unit for Ethernet payloads.
|
||||
.It Dv ETHERMIN Li 46
|
||||
The minimum transmission unit for Ethernet payloads.
|
||||
.It Dv ETHERADDR_BROADCAST_INIT Li {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}
|
||||
An initializer list for
|
||||
.Vt struct ether_addr
|
||||
that initializes it to the broadcast address ff:ff:ff:ff:ff:ff.
|
||||
.El
|
||||
.Sh ERRORS
|
||||
Socket operations can fail due to these error conditions, in addition to the
|
||||
error conditions of the invoked function.
|
||||
.Bl -tag -width [EADDRNOTAVAIL]
|
||||
.It Bq Er EMSGSIZE
|
||||
The datagram was too large to be sent because it exceeded the maximum
|
||||
transmission unit (MTU) (1500 bytes) of the Ethernet protocol.
|
||||
.It Bq Er ENOBUFS
|
||||
There was not enough memory available for network packets.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr etheraddr_broadcast 3 ,
|
||||
.Xr arp 4 ,
|
||||
.Xr if 4 ,
|
||||
.Xr inet 4 ,
|
||||
.Xr ip 4 ,
|
||||
.Xr kernel 7
|
||||
.Sh STANDARDS
|
||||
.Rs
|
||||
.%A Digital Equipment Corporation
|
||||
.%A Intel Corporation
|
||||
.%A Xerox Corporation
|
||||
.%D November 1982
|
||||
.%R Version 2.0
|
||||
.%T The Ethernet - A Local Area Network
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A C. Hornig
|
||||
.%D April 1984
|
||||
.%R STD 41
|
||||
.%R RFC 894
|
||||
.%T A Standard for the Transmission of IP Datagrams over Ethernet Networks
|
||||
.%Q Symbolics Cambridge Research Center
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A Internet Engineering Task Force
|
||||
.%A R. Braden (ed.)
|
||||
.%D October 1989
|
||||
.%R STD 3
|
||||
.%R RFC 1122
|
||||
.%T Requirements for Internet Hosts -- Communication Layers
|
||||
.%Q USC/Information Sciences Institute
|
||||
.Re
|
||||
.Rs
|
||||
.%A Internet Engineering Task Force
|
||||
.%A D. Eastlake 3rd
|
||||
.%A J. Abley
|
||||
.%D October 2013
|
||||
.%R RFC 7042
|
||||
.%T IANA Considerations and IETF Protocol and Documentation Usage for IEEE 802 Parameters
|
||||
.%Q Huawei
|
||||
.%Q Dyn, Inc.
|
||||
.Re
|
35
share/man/man4/icmp.4
Normal file
35
share/man/man4/icmp.4
Normal file
|
@ -0,0 +1,35 @@
|
|||
.Dd June 4, 2017
|
||||
.Dt ICMP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm icmp
|
||||
.Nd internet control message protocol
|
||||
.Sh SYNOPSIS
|
||||
.In sys/socket.h
|
||||
.In netinet/in.h
|
||||
.Sh DESCRIPTION
|
||||
The Internet Control Message Protocol (ICMP) is a control and error reporting
|
||||
layer for the Internet Protocol version 4
|
||||
.Xr ip 4 .
|
||||
ICMP is commonly used to diagnose network problems, such as the destination
|
||||
being unreachable, network congestion, packets exceeding their time to live, and
|
||||
so on.
|
||||
.Sh SEE ALSO
|
||||
.Xr inet 4 ,
|
||||
.Xr ip 4 ,
|
||||
.Xr ping 4 ,
|
||||
.Xr kernel 7
|
||||
.Sh STANDARDS
|
||||
.Rs
|
||||
.%A J. Postel (ed.)
|
||||
.%D September 1981
|
||||
.%R STD 5
|
||||
.%R RFC 792
|
||||
.%T Internet Control Message Protocol - DARPA Internet Program Protocol Specification
|
||||
.%Q USC/Information Sciences Institute
|
||||
.Re
|
||||
.Sh BUGS
|
||||
ICMP is not implemented yet, except automatically replying to the Echo Request
|
||||
message (ping) and the existence of
|
||||
.Xr ping 4
|
||||
sockets for sending Echo Request messages and receiving Echo Reply messages.
|
377
share/man/man4/if.4
Normal file
377
share/man/man4/if.4
Normal file
|
@ -0,0 +1,377 @@
|
|||
.Dd June 11, 2017
|
||||
.Dt IF 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm if
|
||||
.Nd network interface
|
||||
.Sh SYNOPSIS
|
||||
.In sys/ioctl.h
|
||||
.In net/if.h
|
||||
.Sh DESCRIPTION
|
||||
Network interfaces are devices that provide transmission and receipt of network
|
||||
packets.
|
||||
The name of a network interface is the name of the device driver followed by the
|
||||
driver instance number, and each network interface have an unique index number
|
||||
distinct from the driver instance number.
|
||||
The name length is restricted to
|
||||
.Dv IF_NAMESIZE
|
||||
bytes including the trailing nul byte.
|
||||
Network interfaces are exposed in the filesystem as
|
||||
.Pa /dev/ Ns Ar name Ns Ar X
|
||||
devices, where
|
||||
.Ar name
|
||||
is the driver name, and the
|
||||
.Ar X
|
||||
number denotes which device using that driver.
|
||||
Each driver is documented with a manual page with the driver's name in section
|
||||
4 of the manual.
|
||||
.Pp
|
||||
The state of the network interface can be awaited with
|
||||
.Xr poll 2
|
||||
where the
|
||||
.Dv POLLIN
|
||||
and
|
||||
.Dv POLLOUT
|
||||
events are signaled when the network is up
|
||||
.Dv ( IF_STATUS_FLAGS_UP ) .
|
||||
.Sh LINK LAYER
|
||||
Network interfaces abstracts a hardware device or a software device as a link
|
||||
layer protocol:
|
||||
.Bl -tag -width "12345678"
|
||||
.It Ethernet Controller Pq Dv IF_TYPE_ETHERNET
|
||||
Packets are received and transmitted with the Ethernet
|
||||
.Xr ether 4
|
||||
link layer protocol.
|
||||
The
|
||||
.Va type
|
||||
field of
|
||||
.Vt struct if_info
|
||||
is set to
|
||||
.Dv IF_TYPE_ETHERNET
|
||||
and the
|
||||
.Va addr
|
||||
field contains the 6-byte Ethernet address assigned to the Ethernet controller.
|
||||
.It Loopback Device Pq Dv IF_TYPE_LOOPBACK
|
||||
The software loopback device
|
||||
.Xr lo 4
|
||||
on the local host receives any packets transmitted on it.
|
||||
The
|
||||
.Va type
|
||||
field of
|
||||
.Vt struct if_info
|
||||
is set to
|
||||
.Dv IF_TYPE_LOOPBACK
|
||||
and the
|
||||
.Va addr
|
||||
field is unused.
|
||||
.El
|
||||
.Sh NETWORK LAYER
|
||||
Network layer protocols are layered on top of the link layer:
|
||||
.Bl -tag -width "12345678"
|
||||
.It Internet Protocol version 4 Pq Dv AF_INET
|
||||
The Internet Protocol version 4
|
||||
.Xr ip 4
|
||||
provides the network layer of the Internet Protocol version 4 protocol family
|
||||
.Xr inet 4 ,
|
||||
containing transport protocols such as the Transmission Control Protocol
|
||||
.Xr tcp 4 ,
|
||||
and the User Datagram Protocol
|
||||
.Xr udp 4 .
|
||||
When combined with the Ethernet link layer, the Address Resolution Protocol
|
||||
.Xr arp 4
|
||||
is used to resolve network layer addresses into link layer addresses.
|
||||
.El
|
||||
.Sh CONFIGURATION
|
||||
The static information about a network interface is stored in
|
||||
.Vt struct if_info :
|
||||
.Bd -literal
|
||||
struct if_info {
|
||||
unsigned int linkid;
|
||||
int type;
|
||||
int features;
|
||||
size_t addrlen;
|
||||
char name[IF_NAMESIZE];
|
||||
unsigned char addr[IF_HWADDR_MAXSIZE];
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
.Va linkid
|
||||
is the network interface's index number.
|
||||
.Va type
|
||||
is the link layer protocol.
|
||||
.Va features
|
||||
is a bit mask of the features provided by the network interface:
|
||||
.Bl -tag -width "12345678"
|
||||
.It IF_FEATURE_ETHERNET_CRC_OFFLOAD
|
||||
The Ethernet CRC32 checksum is computed in hardware.
|
||||
.El
|
||||
.Pp
|
||||
.Va addrlen
|
||||
is the size of the interface's assigned hardware address stored in the
|
||||
.Va addr
|
||||
field.
|
||||
.Va name
|
||||
is the nul-terminated string name of the network interface.
|
||||
.Pp
|
||||
The status information about a network interface is stored in
|
||||
.Vt struct if_status :
|
||||
.Bd -literal
|
||||
struct if_status {
|
||||
int flags;
|
||||
size_t mtu;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
.Va flags
|
||||
is a bit mask of network interface status conditions:
|
||||
.Bl -tag -width "12345678"
|
||||
.It IF_STATUS_FLAGS_UP
|
||||
The network interface link is up and packets can be received and transmitted.
|
||||
.El
|
||||
.Pp
|
||||
.Va mtu
|
||||
is the maximum transmission unit of the network layer datagram that can be
|
||||
sent or transmitted on the link layer.
|
||||
.Pp
|
||||
The configuration of the network interface is stored in
|
||||
.Vt if_config :
|
||||
.Bd -literal
|
||||
struct if_config_ether {
|
||||
struct ether_addr address;
|
||||
};
|
||||
|
||||
struct if_config_inet {
|
||||
struct in_addr address;
|
||||
struct in_addr router;
|
||||
struct in_addr subnet;
|
||||
};
|
||||
|
||||
struct if_config {
|
||||
struct if_config_ether ether;
|
||||
struct if_config_inet inet;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
.Va ether
|
||||
is the configuration of the
|
||||
.Xr ether 4
|
||||
link layer protocol where
|
||||
.Va address
|
||||
is the Ethernet address that received packets must have as the destination
|
||||
address and the address used as the source address in transmitted packets.
|
||||
.Va address
|
||||
defaults on network interface creation to the value of the
|
||||
.Va addr
|
||||
field of the the network interface's
|
||||
.Va struct if_info .
|
||||
.Pp
|
||||
.Va inet
|
||||
is the configuration of the
|
||||
.Xr ip 4
|
||||
network layer protocol where
|
||||
.Va address
|
||||
is the local address,
|
||||
.Va router
|
||||
is the default route, and
|
||||
.Va subnet
|
||||
is the subnet mask.
|
||||
The protocol is disabled if
|
||||
.Va address
|
||||
is set to the any address
|
||||
.Pq 0.0.0.0 .
|
||||
.Pp
|
||||
Configuration changes to the local addresses or routing information will cause
|
||||
the remote side of existing sockets to become unreachable where paths are no
|
||||
longer configured.
|
||||
Currently outgoing packets are unaffected by configuration changes when they
|
||||
have left the appropriate network layers.
|
||||
Outgoing packets may be queued for a short period in queues such as
|
||||
the data link layer address resolution queue or in the transmission queue.
|
||||
.Sh IOCTLS
|
||||
Network interfaces provide the following
|
||||
.Xr ioctl 2
|
||||
requests defined in
|
||||
.In sys/ioctl.h :
|
||||
.Bl -tag -width "12345678"
|
||||
.It Dv IOCGETTYPE Fa "void"
|
||||
Return the device
|
||||
.Fa type
|
||||
that as a parameter to the
|
||||
.Dv IOC_TYPE(int type)
|
||||
macro returns
|
||||
.Dv IOC_TYPE_NETWORK_INTERFACE
|
||||
if the device is a network interface.
|
||||
.It Dv NIOC_GETCONFIG Fa "struct if_config *"
|
||||
Retrieve the network interface configuration for all protocols atomically.
|
||||
.It Dv NIOC_GETCONFIG_ETHER Fa "struct if_config_ether *"
|
||||
Retrieve the Ethernet configuration.
|
||||
.It Dv NIOC_GETCONFIG_INET Fa "struct if_config_inet *"
|
||||
Retrieve Internet Protocol version 4 configuration.
|
||||
.It Dv NIOC_GETINFO Fa "struct if_info *"
|
||||
Retrieve the network interface static information.
|
||||
.It Dv NIOC_GETSTATUS Fa "struct if_status *"
|
||||
Retrieve the network interface status.
|
||||
.It Dv NIOC_SETCONFIG Fa "const struct if_config *"
|
||||
Set the network interface configuration for all protocols atomically.
|
||||
.It Dv NIOC_SETCONFIG_ETHER Fa "const struct if_config_ether *"
|
||||
Set the Ethernet configuration.
|
||||
.It Dv NIOC_SETCONFIG_INET Fa "const struct if_config_inet *"
|
||||
Set the Internet Protocol version 4 configuration.
|
||||
.El
|
||||
.Sh SOCKET OPTIONS
|
||||
Sockets are made with
|
||||
.Xr socket 2
|
||||
by requesting the desired network layer protocol and the desired transport layer
|
||||
protocol.
|
||||
These
|
||||
.Xr setsockopt 2 /
|
||||
.Xr getsockopt 2
|
||||
options of level
|
||||
.Dv SOL_SOCKET
|
||||
control aspects related to the network interface and are defined in
|
||||
.In sys/socket.h :
|
||||
.Bl -tag -width "12345678"
|
||||
.It Dv SO_BINDTODEVICE Fa "char[]"
|
||||
Set the network interface the socket is bound to by looking up the string value
|
||||
(which need not be nul-terminated) as an network interface name, and then
|
||||
binding the socket to that network interface index number; or failing with
|
||||
.Er ENODEV
|
||||
if no such device exists.
|
||||
Gets the name of the network interface the socket is bound to, by looking up the
|
||||
network interface index number the socket is bound to, and copying out the name
|
||||
of that network interface; or copying out the empty string if so no such device
|
||||
exists.
|
||||
If bound to a network interface, a socket will only receive from and transmit on
|
||||
that network interface.
|
||||
(Initially the empty string)
|
||||
.It Dv SO_BINDTOINDEX Fa "unsigned int"
|
||||
Sets the network interface the socket is bound to by the network interface index
|
||||
number, not verifying such an network interface exists, returning with the error
|
||||
.Er EINVAL
|
||||
if the requested index number exceeds
|
||||
.Dv UINT_MAX .
|
||||
Gets the index number of the network interface the socket is bound to.
|
||||
Index 0 means no network interface.
|
||||
If bound to a network interface, a socket will only receive from and transmit on
|
||||
that network interface.
|
||||
(Initially 0)
|
||||
.It Dv SO_BROADCAST Fa "int"
|
||||
Sending to a broadcast address is allowed when set to 1, sending to a broadcast
|
||||
address will fail with
|
||||
.Er EACCESS
|
||||
when set to 0.
|
||||
This option is boolean, setting it to non-zero is the same as setting it to 1.
|
||||
This option only pertains to datagram sockets.
|
||||
(Initially 0)
|
||||
.It Dv SO_DEBUG Fa "int"
|
||||
Whether the socket is in debug mode.
|
||||
This option is not implemented.
|
||||
This option is boolean, setting it to non-zero is the same as setting it to 1.
|
||||
Attempting to set it to non-zero will fail with
|
||||
.Er EPERM .
|
||||
(Initially 0)
|
||||
.It Dv SO_DOMAIN Fa "sa_family_t"
|
||||
The socket domain (the address family).
|
||||
This option can only be read.
|
||||
The initial value is set when making the socket.
|
||||
.It Dv SO_DONTROUTE Fa "int"
|
||||
Whether to bypass the routing table and only send on the local network.
|
||||
This option is not implemented.
|
||||
This option is boolean, setting it to non-zero is the same as setting it to 1.
|
||||
Attempting to set it to non-zero will fail with
|
||||
.Er EPERM .
|
||||
(Initially 0)
|
||||
.It Dv SO_ERROR Fa "int"
|
||||
The asynchronous pending error
|
||||
(an
|
||||
.Xr errno 3
|
||||
value).
|
||||
Cleared to 0 when read unless the error is permanent.
|
||||
This option can only be read.
|
||||
(Initially 0)
|
||||
.It Dv SO_PROTOCOL Fa "int"
|
||||
The socket protocol.
|
||||
This option can only be read.
|
||||
The initial value is set when making the socket.
|
||||
.It Dv SO_RCVBUF Fa "int"
|
||||
How many bytes the receive queue can use.
|
||||
Setting this option to a value beyond the socket's hard limit will instead set
|
||||
this option to the hard limit.
|
||||
The initial value depends on the socket protocol.
|
||||
.It Dv SO_REUSEADDR Fa "int"
|
||||
Don't fail to
|
||||
.Xr bind 2
|
||||
the second socket with
|
||||
.Er EADDRINUSE
|
||||
when one socket is bound to the any address and a port and the other socket is
|
||||
bound to another address and that port, whenever this option is set to 1.
|
||||
This option is boolean, setting it to non-zero is the same as setting it to 1.
|
||||
(Initially 0)
|
||||
.It Dv SO_SNDBUF Fa "int"
|
||||
How many bytes the send queue can use.
|
||||
Setting this option to a value beyond the socket's hard limit will instead set
|
||||
this option to the hard limit.
|
||||
The initial value depends on the socket protocol.
|
||||
.It Dv SO_TYPE Fa "int"
|
||||
The socket type.
|
||||
This option can only be read.
|
||||
The initial value is set when making the socket.
|
||||
.El
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
Network packets waiting to be transmitted or received have 384 dedicated pages
|
||||
of backing memory (allocated on first use).
|
||||
If more packets are needed, available system memory is used up to a limit of
|
||||
1/16 of the total system memory.
|
||||
If no memory is available for another network packet or the limit is hit,
|
||||
received packets may be dropped and transmitted packets may be dropped or
|
||||
temporarily fail with
|
||||
.Er ENOBUFS .
|
||||
.Sh SEE ALSO
|
||||
.Xr getsockopt 2 ,
|
||||
.Xr ioctl 2 ,
|
||||
.Xr setsockopt 2 ,
|
||||
.Xr arp 4 ,
|
||||
.Xr ether 4 ,
|
||||
.Xr inet 4 ,
|
||||
.Xr ip 4 ,
|
||||
.Xr lo 4 ,
|
||||
.Xr kernel 7
|
||||
.Sh STANDARDS
|
||||
.St -p1003.1-2008
|
||||
only specifies a minimal
|
||||
.In net/if.h
|
||||
with
|
||||
.Dv IF_NAMESIZE ,
|
||||
.Vt struct if_nameindex
|
||||
and the
|
||||
.Xr if_nameindex 3
|
||||
family of functions.
|
||||
.Pp
|
||||
.St -p1003.1-2008
|
||||
specifies the socket options
|
||||
.Dv SO_ACCEPTCONN ,
|
||||
.Dv SO_BROADCAST ,
|
||||
.Dv SO_DEBUG ,
|
||||
.Dv SO_DONTROUTE ,
|
||||
.Dv SO_ERROR ,
|
||||
.Dv SO_KEEPALIVE ,
|
||||
.Dv SO_LINGER ,
|
||||
.Dv SO_OOBINLINE ,
|
||||
.Dv SO_RCVBUF ,
|
||||
.Dv SO_RCVLOWAT ,
|
||||
.Dv SO_RCVTIMEO ,
|
||||
.Dv SO_REUSEADDR ,
|
||||
.Dv SO_SNDBUF ,
|
||||
.Dv SO_SNDLOWAT ,
|
||||
.Dv SO_SNDTIMEO ,
|
||||
and
|
||||
.Dv SO_TYPE
|
||||
in
|
||||
.In sys/socket.h
|
||||
.Sh HISTORY
|
||||
Network interfaces as described here originally appeared in Sortix 1.1, except
|
||||
when noted otherwise.
|
||||
.Pp
|
||||
The
|
||||
.Dv SO_BINDTODEVICE
|
||||
socket option is also found on Linux.
|
214
share/man/man4/inet.4
Normal file
214
share/man/man4/inet.4
Normal file
|
@ -0,0 +1,214 @@
|
|||
.Dd June 1, 2017
|
||||
.Dt INET 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm inet
|
||||
.Nd internet protocol family
|
||||
.Sh SYNOPSIS
|
||||
.In sys/socket.h
|
||||
.In netinet/in.h
|
||||
.Pp
|
||||
.Fd #define AF_INET 1
|
||||
.Bd -literal
|
||||
typedef uint16_t sa_family_t;
|
||||
typedef uint16_t in_port_t;
|
||||
typedef uint32_t in_addr_t;
|
||||
|
||||
struct in_addr {
|
||||
in_addr_t s_addr;
|
||||
};
|
||||
|
||||
struct sockaddr_in {
|
||||
sa_family_t sin_family;
|
||||
in_port_t sin_port;
|
||||
struct in_addr sin_addr;
|
||||
};
|
||||
.Ed
|
||||
.Sh DESCRIPTION
|
||||
The Internet Protocol version 4 protocol family is a set of protocols using the
|
||||
Internet Protocol version 4
|
||||
.Xr ip 4
|
||||
as the network layer.
|
||||
.Dv SOCK_STREAM
|
||||
sockets are provided by the Transmission Control Protocol
|
||||
.Xr tcp 4 .
|
||||
.Dv SOCK_DGRAM
|
||||
sockets are provided by the User Datagram Protocol
|
||||
.Xr udp 4 .
|
||||
.Pp
|
||||
Hosts are addressed with a four byte Internet Protocol (IP) address stored in a
|
||||
.Vt struct in_addr
|
||||
in network byte order.
|
||||
IP addresses are notated by
|
||||
the decimal byte values interspaced with periods, e.g. 192.0.2.255.
|
||||
Subnetworks are ranges of IP addresses given by a starting IP address along with
|
||||
how many leading bits (most significant bit first) of the IP address are common
|
||||
to the network (the prefix), the first address of the the subnetwork is the
|
||||
prefix with the remaining bits set to zero, and the last address is the prefix
|
||||
with the
|
||||
remaining bits set to one.
|
||||
A subnetwork can be denoted by the starting IP address and the leading bits,
|
||||
e.g. 198.51.100.0/24 spans from 198.51.100.0 to 198.51.100.255.
|
||||
The subnet mask of a subnetwork is an IP address with the bits set that belong
|
||||
to the network prefix, e.g. the subnet mask of 203.0.113.0/24 is 255.255.255.0.
|
||||
The subnetworks 192.0.2.0/24 (TEST-NET-1), 198.51.100.0/24 (TEST-NET-2), and
|
||||
203.0.113.0/24 (TEST-NET-2) are reserved for documentation.
|
||||
The last address in a network is normally the broadcast address for the network.
|
||||
.Pp
|
||||
Services are addressed
|
||||
with a 16-bit byte port number in a
|
||||
.Vt in_port_t
|
||||
in network byte order.
|
||||
.Pp
|
||||
Sockets are addressed with the combination of a host address and port number
|
||||
stored in a
|
||||
.Vt struct sockaddr_in
|
||||
where
|
||||
.Va sin_family
|
||||
is set to
|
||||
.Dv AF_INET ,
|
||||
.Va sin_port
|
||||
is set to the 16-bit port number in network byte order, and
|
||||
.Va sin_addr
|
||||
is set to the host address in network byte order.
|
||||
.Pp
|
||||
.Va sin_port
|
||||
can be set to
|
||||
.Li 0
|
||||
(converted to network byte order)
|
||||
to request
|
||||
.Xr bind 2
|
||||
allocate a port.
|
||||
Port
|
||||
.Li 0
|
||||
is not valid as a destination port.
|
||||
.Pp
|
||||
.Va sin_addr.s_addr
|
||||
can be set to
|
||||
.Dv INADDR_ANY
|
||||
.Pq 0.0.0.0
|
||||
(converted to network byte order) to mean an unspecified address.
|
||||
When a socket is bound to the address
|
||||
.Dv INADDR_ANY ,
|
||||
messages are accepted from any address.
|
||||
In
|
||||
.Xr connect 2
|
||||
and
|
||||
.Xr sendto 2 ,
|
||||
the destination address
|
||||
.Dv INADDR_ANY
|
||||
means the current host.
|
||||
.Pp
|
||||
.Va sin_addr.s_addr
|
||||
can be set to
|
||||
.Dv INADDR_BROADCAST
|
||||
.Pq 255.255.255.255
|
||||
(converted to network byte order),
|
||||
the broadcast address of the local network.
|
||||
.Pp
|
||||
.Va sin_addr.s_addr
|
||||
can be set to
|
||||
.Dv INADDR_LOOPBACK
|
||||
.Pq 127.0.0.1
|
||||
(converted to network byte order), the address of the loopback interface
|
||||
.Xr lo 4 .
|
||||
.Dv INADDR_LOOPMASK
|
||||
.Pq 255.0.0.0
|
||||
contains the subnet mask of the loopback interface.
|
||||
.Pp
|
||||
Sockets of this protocol family can be created by passing
|
||||
.Dv AF_INET
|
||||
as the
|
||||
.Fa domain
|
||||
parameter of
|
||||
.Xr socket 2 .
|
||||
.Pp
|
||||
The network byte order is big-endian.
|
||||
.Pp
|
||||
IP addresses in 32-bit integer format in the host endian can be converted
|
||||
to network byte order using
|
||||
.Xr htobe32 3
|
||||
or
|
||||
.Xr htonl 3
|
||||
and back using
|
||||
.Xr be32toh 3
|
||||
or
|
||||
.Xr ntohl 3 .
|
||||
.Pp
|
||||
Port numbers in 16-bit integer format in the host endian can be converted
|
||||
to network byte order using
|
||||
.Xr htobe16 3
|
||||
or
|
||||
.Xr htons 3
|
||||
and back using
|
||||
.Xr be16toh 3
|
||||
or
|
||||
.Xr ntohs 3 .
|
||||
.Pp
|
||||
.Xr inet_pton 3
|
||||
can be used to convert an IP address from textual representation to binary
|
||||
representation.
|
||||
.Xr inet_ntop 3
|
||||
can be used to convert an IP address from binary representation to textual
|
||||
representation.
|
||||
.Sh EXAMPLES
|
||||
This example manually constructs and deconstructs a
|
||||
.Vt struct inaddr_in .
|
||||
.Bd -literal
|
||||
struct sockaddr_in saddr;
|
||||
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_addr.s_addr = htobe32(0xC0000201); /* 192.0.2.1 */
|
||||
saddr.sin_port = htobe16(1234);
|
||||
|
||||
sa_family_t family = saddr.sin_family;
|
||||
in_addr_t addr = be32toh(saddr.sin_addr.s_addr);
|
||||
in_port_t port = be16toh(saddr.sin_port);
|
||||
.Ed
|
||||
.Sh COMPATIBILITY
|
||||
On some operating systems,
|
||||
.Vt struct sockaddr_in
|
||||
may contain padding and additional members and the structure should be
|
||||
initialized to zero prior to initializing its members.
|
||||
.Sh SEE ALSO
|
||||
.Xr socket 2 ,
|
||||
.Xr arp 4 ,
|
||||
.Xr icmp 4 ,
|
||||
.Xr ip 4 ,
|
||||
.Xr ping 4 ,
|
||||
.Xr tcp 4 ,
|
||||
.Xr udp 4 ,
|
||||
.Xr kernel 7
|
||||
.Sh STANDARDS
|
||||
.Rs
|
||||
.%A J. Postel (ed.)
|
||||
.%D September 1981
|
||||
.%R STD 5
|
||||
.%R RFC 791
|
||||
.%T Internet Protocol - DARPA Internet Program Protocol Specification
|
||||
.%Q USC/Information Sciences Institute
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A Internet Engineering Task Force
|
||||
.%A J. Arkko
|
||||
.%A M. Cotton
|
||||
.%A L. Vegoda
|
||||
.%D January 2010
|
||||
.%R RFC 5737
|
||||
.%T IPv4 Address Blocks Reserved for Documentation
|
||||
.%Q Ericsson
|
||||
.%Q ICANN
|
||||
.Re
|
||||
.Pp
|
||||
The protocol family programming interface conforms to
|
||||
.St -p1003.1-2008 .
|
||||
.Sh BUGS
|
||||
The network stack implementation is incomplete and has known bugs.
|
||||
See the protocol manual pages for more information.
|
||||
.Pp
|
||||
The 4-byte address space allows only a maximum of 4294967296 addresses and is
|
||||
being exhausted.
|
||||
The Internet Protocol version 6 replaces version 4 and provides a 16-byte
|
||||
address space instead.
|
135
share/man/man4/ip.4
Normal file
135
share/man/man4/ip.4
Normal file
|
@ -0,0 +1,135 @@
|
|||
.Dd June 3, 2017
|
||||
.Dt IP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ip
|
||||
.Nd internet protocol
|
||||
.Sh SYNOPSIS
|
||||
.In sys/socket.h
|
||||
.In netinet/in.h
|
||||
.Ft int
|
||||
.Fn socket AF_INET type protocol
|
||||
.Sh DESCRIPTION
|
||||
The Internet Protocol version 4 is the original network layer protocol of the
|
||||
Internet and provides best-effort delivery of datagrams between hosts.
|
||||
It provides for addressing of hosts, routing over packet-switched networks,
|
||||
fragmentation and reassembly of datagrams across networks with small maximum
|
||||
transmission unit sizes; but it does not provide guarantee of delivery,
|
||||
avoidance of delivering multiple times, ordering, flow control, nor data
|
||||
integrity.
|
||||
Its protocol family
|
||||
.Xr inet 4
|
||||
can be layered on top of the Internet Protocol to provide the enhanced service
|
||||
of the transport layer.
|
||||
For instance, the Transmission Control Protocol
|
||||
.Xr tcp 4
|
||||
can be used to provide multiplexed reliable communication across the Internet,
|
||||
while the User Datagram Protocol
|
||||
.Xr udp 4
|
||||
can be used to provide low-overhead multiplexed unreliable communication across
|
||||
the Internet.
|
||||
.Pp
|
||||
Datagrams contain a header followed by a datagram of the above protocol layer.
|
||||
The header contains the Internet Protocol version (4), the header size, the
|
||||
desired type of service, the datagram size, information for the reassembly of
|
||||
fragmented datagrams, the remaining time this datagram has left to live, the
|
||||
protocol number of the above protocol layer, a checksum of the header, the
|
||||
address of the source host and the address of the destination host, and an
|
||||
optional set of options.
|
||||
.Pp
|
||||
An incoming datagram on a network interface will be received and passed to the
|
||||
higher level protocol if the following conditions hold:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
The checksum is valid.
|
||||
.It
|
||||
The protocol is Internet Protocol version 4 and the packet is well-formed.
|
||||
.It
|
||||
The source address is neither the broadcast address
|
||||
.Pq 255.255.255.255
|
||||
or the subnet's broadcast address.
|
||||
.It
|
||||
If the network interface is not the loopback network interface
|
||||
.Xr lo 4 ,
|
||||
neither the source nor the destination belong to the loopback subnet
|
||||
.Pq 127.0.0.0/24
|
||||
.It
|
||||
The destination address is either the local address (and the link layer
|
||||
destination address was not a broadcast address) of the network interface, the
|
||||
broadcast address of the network interface, or the broadcast address
|
||||
.Pq 255.255.255.255 .
|
||||
.El
|
||||
.Sh ERRORS
|
||||
Socket operations can fail due to these error conditions, in addition to the
|
||||
error conditions of link layer and the error conditions of the invoked function.
|
||||
.Bl -tag -width [EADDRNOTAVAIL]
|
||||
.It Bq Er EACCES
|
||||
A datagram was sent to a broadcast address, but
|
||||
.Dv SO_BROADCAST
|
||||
is turned off.
|
||||
.It Bq Er EADDRNOTAVAIL
|
||||
The socket cannot be bound to the requested address because no network interface
|
||||
had that address or broadcast address.
|
||||
.It Bq Er ECONNREFUSED
|
||||
The destination host of a datagram was not listening on the port.
|
||||
.It Bq Er EHOSTDOWN
|
||||
The destination host of a datagram is not up.
|
||||
.It Bq Er EHOSTUNREACH
|
||||
The destination host of a datagram was unreachable.
|
||||
.It Bq Er EMSGSIZE
|
||||
The datagram was too large to be sent because it exceeded the maximum
|
||||
transmission unit (MTU) on the path between the local and remote address.
|
||||
.It Bq Er ENETDOWN
|
||||
The network interface used to deliver a datagram isn't up.
|
||||
.It Bq Er ENETUNREACH
|
||||
The destination network of a datagram was unreachable.
|
||||
.It Bq Er ENOBUFS
|
||||
There was not enough memory available for network packets.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr arp 4 ,
|
||||
.Xr icmp 4 ,
|
||||
.Xr inet 4 ,
|
||||
.Xr ping 4 ,
|
||||
.Xr tcp 4 ,
|
||||
.Xr udp 4 ,
|
||||
.Xr kernel 7
|
||||
.Sh STANDARDS
|
||||
.Rs
|
||||
.%A J. Postel (ed.)
|
||||
.%D September 1981
|
||||
.%R STD 5
|
||||
.%R RFC 791
|
||||
.%T Internet Protocol - DARPA Internet Program Protocol Specification
|
||||
.%Q USC/Information Sciences Institute
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A Internet Engineering Task Force
|
||||
.%A R. Braden (ed.)
|
||||
.%D October 1989
|
||||
.%R STD 3
|
||||
.%R RFC 1122
|
||||
.%T Requirements for Internet Hosts -- Communication Layers
|
||||
.%Q USC/Information Sciences Institute
|
||||
.Re
|
||||
.Sh BUGS
|
||||
The implementation is incomplete and has known bugs.
|
||||
.Pp
|
||||
Fragmented datagrams are not yet supported and are discarded on receipt.
|
||||
The fragment identification field is always set to 0, preventing the proper
|
||||
reassembly of multiple datagrams that became fragmented around the same time.
|
||||
.Pp
|
||||
Options are not yet supported and are ignored.
|
||||
.Pp
|
||||
The 4-byte address space allows only a maximum of 4294967296 addresses and is
|
||||
being exhausted.
|
||||
The Internet Protocol version 6 replaces version 4 and provides a 16-byte
|
||||
address space instead.
|
||||
.Pp
|
||||
There is no routing table that can be configured.
|
||||
Routing happens by searching for the first appropriate network interface that
|
||||
can transmit the datagram.
|
||||
If multiple network interfaces have a default route, the packet is sent using
|
||||
the default route of the network interface with the lowest index number.
|
36
share/man/man4/lo.4
Normal file
36
share/man/man4/lo.4
Normal file
|
@ -0,0 +1,36 @@
|
|||
.Dd May 27, 2017
|
||||
.Dt LO 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm lo
|
||||
.Nd loopback network interface
|
||||
.Sh SYNOPSIS
|
||||
.Nm /dev/lo Ns Ar X
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a loopback network interface that receives what is sent on it, used for
|
||||
communication within the local host.
|
||||
.Nm
|
||||
is implemented in software and the packets sent on it are not transmitted on the
|
||||
network.
|
||||
.Pp
|
||||
The
|
||||
.Xr kernel 7
|
||||
creates the
|
||||
.Sy lo0
|
||||
network interface on boot and configures it with the
|
||||
.Xr inet 4
|
||||
address
|
||||
.Dv 127.0.0.1
|
||||
in the subnet
|
||||
.Dv 127.0.0.0/8 .
|
||||
Packets with source or destination outside this subnet are dropped.
|
||||
.Sh SEE ALSO
|
||||
.Xr kernel 7
|
||||
.Sh CAVEATS
|
||||
The default
|
||||
.Xr inet 4
|
||||
configuration
|
||||
of the
|
||||
.Sy lo0
|
||||
network interface must not be changed or local loopback communication may fail.
|
537
share/man/man4/ping.4
Normal file
537
share/man/man4/ping.4
Normal file
|
@ -0,0 +1,537 @@
|
|||
.Dd June 4, 2017
|
||||
.Dt PING 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ping
|
||||
.Nd ping protocol
|
||||
.Sh SYNOPSIS
|
||||
.In sys/socket.h
|
||||
.In netinet/in.h
|
||||
.In netinet/ping.h
|
||||
.Ft int
|
||||
.Fn socket AF_INET SOCK_DGRAM IPPROTO_PING
|
||||
.Sh DESCRIPTION
|
||||
The Ping Protocol uses the Echo Request and Echo Reply messages of the Internet
|
||||
Control Message Protocol (ICMP) to provide a connectionless best-effort echo of
|
||||
datagrams.
|
||||
A cooperating host will send back a Echo Reply message containing the same data
|
||||
as any Echo Request messages it receives.
|
||||
It is designed for packet-switched networks and provides multiplexing with a
|
||||
16-bit port number (using the identifier field of the Echo Request and Echo
|
||||
Reply messages), and basic data integrity checks (16-bit ones' complement sum),
|
||||
and broadcasting.
|
||||
It does not provide a guarantee of delivery, avoidance of delivering multiple
|
||||
times, ordering, out of band data, nor flow control.
|
||||
.Pp
|
||||
Ping sockets allow only sending Echo Request messages and receiving Echo Reply
|
||||
messages.
|
||||
The kernel will automatically send Echo Reply messages in response to any
|
||||
received Echo Request Messages.
|
||||
.Pp
|
||||
The structure of ping datagrams is a 4 bytes sequence number (in big endian)
|
||||
followed by 0 or more bytes of an optional payload.
|
||||
Ping datagrams are sent inside a Echo Request message (with that sequence
|
||||
number) and received inside a Echo Reply message (also containing a sequence
|
||||
number).
|
||||
.Pp
|
||||
Ping sockets are made with
|
||||
.Xr socket 2
|
||||
by passing an appropriate
|
||||
.Fa domain
|
||||
.Dv ( AF_INET ) ,
|
||||
.Dv SOCK_DGRAM
|
||||
as the
|
||||
.Fa type ,
|
||||
and
|
||||
.Dv IPPROTO_PING
|
||||
as the
|
||||
.Fa protocol .
|
||||
Initially a socket is not bound, it won't receive datagrams, and it does not
|
||||
have a remote address and port set.
|
||||
.Pp
|
||||
A Ping socket has the following state:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
The address family it belongs to.
|
||||
.It
|
||||
The network interface it is bound to (if any)
|
||||
.Dv ( SO_BINDTODEVICE
|
||||
and
|
||||
.Dv SO_BINDTOINDEX )
|
||||
(initially none).
|
||||
.It
|
||||
The local address and port (when bound) (initially none).
|
||||
.It
|
||||
The remote address and port (when connected) (initially none).
|
||||
.It
|
||||
A receive queue (initially empty).
|
||||
.It
|
||||
Whether the socket has been
|
||||
.Xr shutdown 2
|
||||
for read and/or write (initially neither).
|
||||
.It
|
||||
A single pending asynchronous error (if any)
|
||||
.Dv ( SO_ERROR )
|
||||
(initially none).
|
||||
.It
|
||||
Whether broadcast datagrams can be sent
|
||||
.Dv ( SO_BROADCAST )
|
||||
(initially no).
|
||||
.It
|
||||
Whether binding to the any address and a port doesn't conflict with binding to
|
||||
another address on the same port
|
||||
.Dv ( SO_REUSEADDR )
|
||||
(initially no).
|
||||
.It
|
||||
Limits on the size of the receive and send queues
|
||||
.Dv ( SO_RCVBUF
|
||||
and
|
||||
.Dv SO_SNDBUF ) .
|
||||
.El
|
||||
.Pp
|
||||
Datagrams are sent as a packet with a header and the datagram itself.
|
||||
The header contains the port and the checksum.
|
||||
The header is 8 bytes.
|
||||
.Pp
|
||||
Port numbers are 16-bit and range from 1 to 65535.
|
||||
Port 0 is not valid.
|
||||
Binding to port 0 will assign an available port on the requested address.
|
||||
Sending or connecting to port 0 will fail with
|
||||
.Er EADDRNOTAVAIL .
|
||||
Received Echo Reply packets whose port number is port 0 will be silently
|
||||
dropped.
|
||||
Ping ports are distinct from ports in other transport layer protocols.
|
||||
.Pp
|
||||
Packets contain a 16-bit ones' complement checksum.
|
||||
A received packet will be silently discarded if its checksum does not match its
|
||||
contents.
|
||||
.Pp
|
||||
Sockets can be bound to a local address and port with
|
||||
.Xr bind 2
|
||||
(if not already bound),
|
||||
or an local address and port will be automatically assigned on the first send
|
||||
or connect operation.
|
||||
The local address and port can be read with
|
||||
.Xr getsockname 2 .
|
||||
If the socket hasn't been bound, the local address and port is reported as the
|
||||
any address on port 0.
|
||||
There are no ports that require superuser privileges.
|
||||
.Pp
|
||||
Sockets can be bound to the any address, the broadcast address, the address of
|
||||
a network interface, or the broadcast address of a network interface.
|
||||
Binding to port 0 will automatically assign an available port on the requested
|
||||
local address or fail with
|
||||
.Er EAGAIN
|
||||
if no port is available.
|
||||
No two sockets can bind to the same local address and port.
|
||||
No two sockets can be bound such that one is bound to the any address and a
|
||||
port, and the other socket is bound to another address and the same port; unless
|
||||
both sockets had the
|
||||
.Dv SO_REUSEADDR
|
||||
socket option set when the second socket was bound, and the current user is the
|
||||
same that bound the first socket or the current user has superuser privileges.
|
||||
.Pp
|
||||
A socket bound to a local address and port will receive an incoming datagram of
|
||||
the following conditions hold:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
The datagram belongs to the socket's address family and the protocol is Ping.
|
||||
.It
|
||||
The datagram's checksum matches the datagram.
|
||||
.It
|
||||
The datagram is an Echo Reply message.
|
||||
.It
|
||||
The datagram's port number is not port 0.
|
||||
.It
|
||||
The datagram is sent to the address or broadcast address of the network
|
||||
interface it is received on, or the datagram was sent to the broadcast address;
|
||||
.It
|
||||
The socket is either bound to the receiving network interface, or the socket is
|
||||
not bound to a network interface;
|
||||
.It
|
||||
The datagram is sent to the socket's local port;
|
||||
.It
|
||||
The datagram is sent to the socket's local address, or the socket's local
|
||||
address is the any address (and no other socket is bound to the datagram's
|
||||
address and that port);
|
||||
.It
|
||||
The socket is connected and the datagram was sent from the remote address and
|
||||
the remote port, or the socket is not connected; and
|
||||
.It
|
||||
The socket is not shut down for reading.
|
||||
.El
|
||||
.Pp
|
||||
If so, the datagram is added to the socket's receive queue, otherwise it is
|
||||
discarded.
|
||||
The receive queue contains incoming packets waiting to be received.
|
||||
Incoming packets are dropped if the receive queue is full.
|
||||
Shrinking the receive queue limit drops packets as needed to stay below the
|
||||
limit.
|
||||
.Pp
|
||||
The remote address and port can be set multiple times with
|
||||
.Xr connect 2 ,
|
||||
after which the socket is said to be connected, but Ping is connectionless and
|
||||
no handshake is sent.
|
||||
The remote port must not be port 0 or the connection will fail with
|
||||
.Er EADDRNOTAVAIL .
|
||||
If the socket is not bound,
|
||||
.Xr connect 2
|
||||
will determine which network interface will be used to send to the remote
|
||||
address, and then bind to the address of that network interface together with an
|
||||
available port.
|
||||
.Xr connect 2
|
||||
will fail if there is no route from the local address to the requested remote
|
||||
address.
|
||||
A connected socket only receive datagrams from the remote address and port.
|
||||
.Xr connect 2
|
||||
will drop datagrams in the receive queue that don't originate from the
|
||||
requested remote address.
|
||||
The
|
||||
.Xr send 2 ,
|
||||
.Xr write 2 ,
|
||||
and
|
||||
.Xr writev 2
|
||||
functions can be used on a connected socket and they send to the remote address
|
||||
and port by default.
|
||||
If the socket is connected, the destination given to
|
||||
.Xr sendto 2
|
||||
and
|
||||
.Xr sendmsg 2
|
||||
must be
|
||||
.Dv NULL .
|
||||
The remote address and port can be read with
|
||||
.Xr getpeername 2 .
|
||||
.Pp
|
||||
The socket can be disconnected by connecting to a socket address with the family
|
||||
value set to
|
||||
.Dv AF_UNSPEC ,
|
||||
which resets the remote address and port (if set), and otherwise has no effect.
|
||||
.Pp
|
||||
Datagrams can be sent with
|
||||
.Xr sendmsg 2
|
||||
and
|
||||
.Xr sendto 2 .
|
||||
Sending on a socket not bound to a local address and port will bind to the
|
||||
any address and an available port, or fail with
|
||||
.Er EAGAIN
|
||||
if no port is available.
|
||||
Datagrams can be received with
|
||||
.Xr recvmsg 2 ,
|
||||
.Xr recvfrom 2 ,
|
||||
.Xr recv 2 ,
|
||||
.Xr read 2 ,
|
||||
and
|
||||
.Xr readv 2 .
|
||||
If an asynchronous error is pending, the next send and receive operation will
|
||||
fail with that error and clear the asynchronous eror, so the next operation can
|
||||
succeed.
|
||||
Asynchronous errors can arise from network problems.
|
||||
There is no send queue at the Ping level and datagrams are directly forwarded to
|
||||
the network layer.
|
||||
It is an error to use any of the flags
|
||||
.Dv MSG_CMSG_CLOEXEC ,
|
||||
.Dv MSG_CMSG_CLOFORK ,
|
||||
.Dv MSG_EOR ,
|
||||
.Dv MSG_OOB ,
|
||||
and
|
||||
.Dv MSG_WAITALL .
|
||||
.Pp
|
||||
The condition of the socket can be tested with
|
||||
.Xr poll 2
|
||||
where
|
||||
.Dv POLLIN
|
||||
signifies a packet has been received (or the socket is shut down for reading),
|
||||
.Dv POLLOUT
|
||||
signifies a packet can be sent now (and the socket is not shut down for
|
||||
writing),
|
||||
.Dv POLLHUP
|
||||
signifies the socket is shut down for writing, and
|
||||
.Dv POLLERR
|
||||
signifies an asynchronous error is pending.
|
||||
.Pp
|
||||
The socket can be shut down for receiving and/or sending with
|
||||
.Xr shutdown 2 .
|
||||
The receive queue is emptied when shut down for receive (asynchronous errors are
|
||||
preserved) and receive operations will succeed with an end of file
|
||||
condition, but any pending asynchronous errors will take precedence and be
|
||||
delivered instead.
|
||||
Sending when shut down for writing will raise
|
||||
.Dv SIGPIPE
|
||||
and fail with
|
||||
.Er EPIPE
|
||||
(regardless of a pending asynchronous error).
|
||||
.Pp
|
||||
Socket options can be set with
|
||||
.Xr setsockopt 2
|
||||
and read with
|
||||
.Xr getsockopt 2
|
||||
and exist on the
|
||||
.Dv IPPROTO_PING
|
||||
level as well as applicable underlying protocol levels.
|
||||
.Pp
|
||||
Broadcast Echo Requests can be sent by setting the
|
||||
.Dv SO_BROADCAST
|
||||
socket option with
|
||||
.Xr setsockopt 2
|
||||
and sending to a broadcast address of the network layer.
|
||||
RFC 1122 3.2.2.6 allows hosts to ignore broadcast Echo Requests.
|
||||
.Sh SOCKET OPTIONS
|
||||
Ping sockets support these
|
||||
.Xr setsockopt 2 /
|
||||
.Xr getsockopt 2
|
||||
options at level
|
||||
.Dv SOL_SOCKET :
|
||||
.Bl -tag -width "12345678"
|
||||
.It Dv SO_BINDTODEVICE Fa "char[]"
|
||||
Bind to a network interface by its name.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_BINDTOINDEX Fa "unsigned int"
|
||||
Bind to a network interface by its index number.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_BROADCAST Fa "int"
|
||||
Whether sending to a broadcast address is allowed.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_DEBUG Fa "int"
|
||||
Whether the socket is in debug mode.
|
||||
This option is not implemented and is initially 0.
|
||||
Attempting to set it to non-zero will fail with
|
||||
.Er EPERM .
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_DOMAIN Fa "sa_family_t"
|
||||
The socket
|
||||
.Fa domain
|
||||
(the address family).
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_DONTROUTE Fa "int"
|
||||
Whether to bypass the routing table and only send on the local network.
|
||||
This option is not implemented and is initially 0.
|
||||
Attempting to set it to non-zero will fail with
|
||||
.Er EPERM .
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_ERROR Fa "int"
|
||||
The asynchronous pending error
|
||||
(an
|
||||
.Xr errno 3
|
||||
value).
|
||||
Cleared to 0 when read.
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_PROTOCOL Fa "int"
|
||||
The socket protocol
|
||||
.Dv ( IPPROTO_PING ) .
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_RCVBUF Fa "int"
|
||||
How many bytes the receive queue can use (default is 64 pages, max 4096 pages).
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_REUSEADDR Fa "int"
|
||||
Whether binding to the any address on a port doesn't conflict with binding to
|
||||
another address and the same port, if both sockets have this option set and the
|
||||
user binding the second socket is the same that bound the first socket or the
|
||||
user binding the second socket has superuser privileges.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_SNDBUF Fa "int"
|
||||
How many bytes the send queue can use (default is 64 pages, max 4096 pages).
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_TYPE Fa "int"
|
||||
The socket type
|
||||
.Dv ( SOCK_DGRAM ) .
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.El
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
Received broadcast echo requests are ignored as permitted by RFC 1122 3.2.2.6.
|
||||
.Pp
|
||||
Each packet currently use a page of memory, which counts towards the receive
|
||||
queue limit.
|
||||
.Pp
|
||||
If no specific port is requested, one is randomly selected in the dynamic port
|
||||
range 32768 (inclusive) through 61000 (exclusive).
|
||||
.Sh EXAMPLES
|
||||
This example sends a Echo Request and blocks indefinitely until it receives a
|
||||
Echo Reply.
|
||||
.Va remote
|
||||
is the remote socket address and
|
||||
.Va remote_len
|
||||
is the size of
|
||||
.Va remote.
|
||||
The
|
||||
.Va remote
|
||||
and
|
||||
.Va remote_len
|
||||
values should all be chosen according to the address family and network layer.
|
||||
.Bd -literal
|
||||
sa_family_t af = /* ... */;
|
||||
const struct sockaddr *remote = /* ... */;
|
||||
socklen_t remote_len = /* ... */;
|
||||
|
||||
int fd = socket(af, SOCK_DGRAM, IPPROTO_PING);
|
||||
if (fd < 0)
|
||||
err(1, "socket");
|
||||
if (connect(fd, remote, remote_len) < 0)
|
||||
err(1, "connect");
|
||||
unsigned char request[56];
|
||||
arc4random_buf(request, sizeof(request));
|
||||
if (send(fd, request, sizeof(request), 0) < 0)
|
||||
err(1, "send");
|
||||
unsigned char reply[56 + 1 /* detect too large reply */];
|
||||
ssize_t amount = recv(fd, reply, sizeof(reply), 0);
|
||||
if (amount < 0 )
|
||||
err(1, "recv");
|
||||
if (amount == sizeof(request) && !memcmp(request, reply, sizeof(request)))
|
||||
printf("correct echo reply\\n");
|
||||
else
|
||||
printf("incorrect echo reply\\n");
|
||||
.Ed
|
||||
.Sh ERRORS
|
||||
Socket operations can fail due to these error conditions, in addition to the
|
||||
error conditions of the network and link layer, and the error conditions of the
|
||||
invoked function.
|
||||
.Bl -tag -width [EADDRNOTAVAIL]
|
||||
.It Bq Er EACCES
|
||||
A datagram was sent to a broadcast address, but
|
||||
.Dv SO_BROADCAST
|
||||
is turned off.
|
||||
.It Bq Er EADDRINUSE
|
||||
The socket cannot be bound to the requested address and port because another
|
||||
socket was already bound to 1) the same address and port 2) the any address
|
||||
and the same port (and
|
||||
.Dv SO_REUSEADDR
|
||||
was not set on both sockets), or 3) some address and the same port but the
|
||||
requested address was the any address (and
|
||||
.Dv SO_REUSEADDR
|
||||
was not set on both sockets).
|
||||
.It Bq Er EADDRNOTAVAIL
|
||||
The socket cannot be bound to the requested address because no network interface
|
||||
had that address or broadcast address.
|
||||
.It Bq Er EAGAIN
|
||||
A port could not be assigned because each port in the dynamic port range had
|
||||
already been bound to a socket in a conflicting manner.
|
||||
.It Bq Er ECONNREFUSED
|
||||
The destination host of a datagram was not listening on the port.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er EHOSTDOWN
|
||||
The destination host of a datagram is not up.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er EHOSTUNREACH
|
||||
The destination host of a datagram was unreachable.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er EISCONN
|
||||
A destination address and port was specified when sending a datagram, but the
|
||||
socket has already been connected to a remote address and port.
|
||||
.It Bq Er EMSGSIZE
|
||||
The datagram was too large to be sent because it exceeded the maximum
|
||||
transmission unit (MTU) on the path between the local and remote address.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er ENETDOWN
|
||||
The network interface used to deliver a datagram isn't up.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er ENETUNREACH
|
||||
The destination network of a datagram was unreachable.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er ENETUNREACH
|
||||
The remote address could not be connected because there was no route from the
|
||||
local address to the remote address.
|
||||
.It Bq Er ENOBUFS
|
||||
There was not enough memory available for network packets.
|
||||
.It Bq Er EPERM
|
||||
One of the unimplemented
|
||||
.Dv SO_DEBUG
|
||||
and
|
||||
.Dv SO_DONTROUTE
|
||||
socket options was attempted to be set to a non-zero value.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr bind 2 ,
|
||||
.Xr connect 2 ,
|
||||
.Xr getpeername 2 ,
|
||||
.Xr getsockname 2 ,
|
||||
.Xr getsockopt 2 ,
|
||||
.Xr poll 2 ,
|
||||
.Xr recvfrom 2 ,
|
||||
.Xr recvmsg 2 ,
|
||||
.Xr sendmsg 2 ,
|
||||
.Xr sendto 2 ,
|
||||
.Xr setsockopt 2 ,
|
||||
.Xr shutdown 2 ,
|
||||
.Xr socket 2 ,
|
||||
.Xr icmp 4 ,
|
||||
.Xr if 4 ,
|
||||
.Xr inet 4 ,
|
||||
.Xr ip 4 ,
|
||||
.Xr kernel 7
|
||||
.Sh STANDARDS
|
||||
.Rs
|
||||
.%A J. Postel (ed.)
|
||||
.%D September 1981
|
||||
.%R STD 5
|
||||
.%R RFC 792
|
||||
.%T Internet Control Message Protocol - DARPA Internet Program Protocol Specification
|
||||
.%Q USC/Information Sciences Institute
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A Internet Engineering Task Force
|
||||
.%A R. Braden (ed.)
|
||||
.%D October 1989
|
||||
.%R STD 3
|
||||
.%R RFC 1122
|
||||
.%T Requirements for Internet Hosts -- Communication Layers
|
||||
.%Q USC/Information Sciences Institute
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
Ping sockets originally appeared in Sortix 1.1.
|
||||
.Sh BUGS
|
||||
The handling of
|
||||
.Dv SO_REUSEADDR in
|
||||
.Xr bind 2
|
||||
does not yet enforce the two sockets to be bound by the same user or the second
|
||||
socket to be bound by a user with superuser privileges.
|
||||
The requirement that both sockets have
|
||||
.Dv SO_REUSEADDR
|
||||
set might be relaxed to only the second socket having it set when this
|
||||
permission check is implemented.
|
||||
.Pp
|
||||
The integration with the network layer is inadequate and the asynchronous errors
|
||||
.Er ECONNREFUSED ,
|
||||
.Er EHOSTDOWN ,
|
||||
.Er EHOSTUNREACH ,
|
||||
and
|
||||
.Er ENETUNREACH
|
||||
are never delivered asynchronously from the network.
|
||||
.Pp
|
||||
Ping sockets does not yet provide access to IP header values such as the Time
|
||||
To Live and does not yet report ICMP error messages.
|
||||
.Pp
|
||||
The
|
||||
.Xr send 2
|
||||
flag
|
||||
.Dv MSG_DONTROUTE
|
||||
and the
|
||||
.Dv SO_DONTROUTE
|
||||
socket option are not implemented yet.
|
||||
.Pp
|
||||
The
|
||||
.Dv SO_SNDBUF
|
||||
socket option is currently not used and the send queue is not limited at the
|
||||
socket level.
|
||||
.Pp
|
||||
The automatic assignment of ports is random, but is statistically biased.
|
||||
A random port is picked, and if it is taken, the search sequentially iterates
|
||||
ports in ascending order until an available port is found or the search
|
||||
terminates.
|
382
share/man/man4/tcp.4
Normal file
382
share/man/man4/tcp.4
Normal file
|
@ -0,0 +1,382 @@
|
|||
.Dd June 3, 2017
|
||||
.Dt TCP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm tcp
|
||||
.Nd transmission control protocol
|
||||
.Sh SYNOPSIS
|
||||
.In sys/socket.h
|
||||
.In netinet/in.h
|
||||
.In netinet/tcp.h
|
||||
.Ft int
|
||||
.Fn socket AF_INET SOCK_STREAM IPPROTO_TCP
|
||||
.Sh DESCRIPTION
|
||||
The Transmission Control Protocol (TCP) is a connection-oriented transport layer
|
||||
for the Internet Protocol
|
||||
.Xr ip 4
|
||||
that provides a reliable byte stream connection between two hosts.
|
||||
It is designed for packet-switched networks and provides sequenced data,
|
||||
retransmissions on packet loss, handling of duplicated packets, flow control,
|
||||
basic data integrity checks, multiplexing with a 16-bit port number, support for
|
||||
out-of-band urgent data, and detection of lost connection.
|
||||
TCP provides the
|
||||
.Dv SOCK_STREAM
|
||||
abstraction for the
|
||||
.Xr inet 4
|
||||
protocol family.
|
||||
.Pp
|
||||
TCP sockets are made with
|
||||
.Xr socket 2
|
||||
by passing an appropriate
|
||||
.Fa domain
|
||||
.Dv ( AF_INET ) ,
|
||||
.Dv SOCK_STREAM
|
||||
as the
|
||||
.Fa type ,
|
||||
and 0 or
|
||||
.Dv IPPROTO_TCP
|
||||
as the
|
||||
.Fa protocol .
|
||||
Newly created TCP sockets are not bound to a local address nor connected to a
|
||||
remote socket.
|
||||
.Pp
|
||||
Port numbers are 16-bit and range from 1 to 65535.
|
||||
Port 0 is not valid.
|
||||
Binding to port 0 will assign an available port on the requested address.
|
||||
Connecting to port 0 will fail with
|
||||
.Er EADDRNOTAVAIL .
|
||||
Received packets whose source or destination address is port 0 will be silently
|
||||
dropped.
|
||||
TCP ports are distinct from ports in other transport layer protocols.
|
||||
.Pp
|
||||
Packets contain a 16-bit ones' complement checksum.
|
||||
Received packets will be silently discarded if their checksum does not match
|
||||
the contents.
|
||||
.Pp
|
||||
Sockets can be bound to a local address and port with
|
||||
.Xr bind 2
|
||||
(if not already bound),
|
||||
or an local address and port will be automatically assigned when connected.
|
||||
The local address and port can be read with
|
||||
.Xr getsockname 2 .
|
||||
If the socket hasn't been bound, the local address and port is reported as the
|
||||
any address on port 0.
|
||||
Binding to a well-known port (port 1 through port 1023) requires superuser
|
||||
privileges.
|
||||
.Pp
|
||||
Sockets can be bound to the any address, the broadcast address, the address of
|
||||
a network interface, or the broadcast address of a network interface.
|
||||
Binding to port 0 will automatically assign an available port on the requested
|
||||
local address or fail with
|
||||
.Er EAGAIN
|
||||
if no port is available.
|
||||
No two sockets can bind to the same local address and port.
|
||||
No two sockets can be bound such that one is bound to the any address and a
|
||||
port, and the other socket is bound to another address and the same port; unless
|
||||
both sockets had the
|
||||
.Dv SO_REUSEADDR
|
||||
socket option set when the second socket was bound, and the current user is the
|
||||
same that bound the first socket or the current user has superuser privileges.
|
||||
.Pp
|
||||
A connection to a remote TCP socket can be established with
|
||||
.Xr connect 2 .
|
||||
Connections can be established when both sides calls
|
||||
.Xr connect 2
|
||||
on each other.
|
||||
If the socket is not bound,
|
||||
.Xr connect 2
|
||||
will determine which network interface will be used to send to the remote
|
||||
address, and then bind to the address of that network interface together with an
|
||||
available port.
|
||||
.Xr connect 2
|
||||
will fail if there is no route from the local address to the requested remote
|
||||
address.
|
||||
.Pp
|
||||
Incoming connections can be received by binding to a local address with
|
||||
.Xr bind 2
|
||||
and listening for connections with
|
||||
.Xr listen 2 ,
|
||||
after which incoming connections can be retrieved with
|
||||
.Xr accept 2 .
|
||||
.Pp
|
||||
Bytes can be received from the remote TCP socket with
|
||||
.Xr recv 2 ,
|
||||
.Xr recvmsg 2 ,
|
||||
.Xr recvfrom 2 ,
|
||||
.Xr read 2 ,
|
||||
or
|
||||
.Xr readv 2 .
|
||||
Bytes can be transmitted to the remote TCP socket with
|
||||
.Xr send 2 ,
|
||||
.Xr sendmsg 2 ,
|
||||
.Xr sendto 2 ,
|
||||
.Xr write 2 ,
|
||||
or
|
||||
.Xr writev 2 .
|
||||
Transmitting when the connection has broken will result in the process being
|
||||
sent the
|
||||
.Dv SIGPIPE
|
||||
signal and fail with
|
||||
.Er EPIPE .
|
||||
.Pp
|
||||
The receiving socket will acknowledge any received data.
|
||||
If no acknowledgement is received in a timely manner, the transmitting socket
|
||||
will transmit the data again.
|
||||
If a acknowledgement still isn't received after a while, the connection is
|
||||
considered broken and no further receipt or transmission is possible.
|
||||
.Pp
|
||||
The condition of the socket can be tested with
|
||||
.Xr poll 2
|
||||
where
|
||||
.Dv POLLIN
|
||||
signifies new data been received or the remote socket has shut down for writing
|
||||
or an incoming connection can be retrieved with
|
||||
.Xr accept 2 ,
|
||||
.Dv POLLOUT
|
||||
signifies new data can be sent now (and the socket is not shut down for
|
||||
writing),
|
||||
.Dv POLLHUP
|
||||
signifies the socket is shut down for writing, and
|
||||
.Dv POLLERR
|
||||
signifies an asynchronous error is pending.
|
||||
.Pp
|
||||
The connection can be shut down with
|
||||
.Xr shutdown 2
|
||||
in either the reading direction (discarding further received data) or the
|
||||
writing direction (which sends the finish control flag).
|
||||
The connection is closed when both sockets have sent and acknowledged the finish
|
||||
control flag.
|
||||
Upon the
|
||||
.Xr close 2
|
||||
of the last file descriptor for a connected socket, the socket is shut down in
|
||||
both directions.
|
||||
.Pp
|
||||
Socket options can be set with
|
||||
.Xr setsockopt 2
|
||||
and read with
|
||||
.Xr getsockopt 2
|
||||
and exist on the
|
||||
.Dv IPPROTO_TCP
|
||||
level as well as applicable underlying protocol levels.
|
||||
.Sh SOCKET OPTIONS
|
||||
TCP sockets support these
|
||||
.Xr setsockopt 2 /
|
||||
.Xr getsockopt 2
|
||||
options at level
|
||||
.Dv SOL_SOCKET :
|
||||
.Bl -tag -width "12345678"
|
||||
.It Dv SO_BINDTODEVICE Fa "char[]"
|
||||
Bind to a network interface by its name.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_BINDTOINDEX Fa "unsigned int"
|
||||
Bind to a network interface by its index number.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_DEBUG Fa "int"
|
||||
Whether the socket is in debug mode.
|
||||
This option is not implemented and is initially 0.
|
||||
Attempting to set it to non-zero will fail with
|
||||
.Er EPERM .
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_DOMAIN Fa "sa_family_t"
|
||||
The socket
|
||||
.Fa domain
|
||||
(the address family).
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_ERROR Fa "int"
|
||||
The asynchronous pending error
|
||||
(an
|
||||
.Xr errno 3
|
||||
value).
|
||||
Errors are permanent.
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_PROTOCOL Fa "int"
|
||||
The socket protocol
|
||||
.Dv ( IPPROTO_TCP ) .
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_RCVBUF Fa "int"
|
||||
How many bytes the receive queue can use (default is 64 KiB).
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_REUSEADDR Fa "int"
|
||||
Whether binding to the any address on a port doesn't conflict with binding to
|
||||
another address and the same port, if both sockets have this option set and the
|
||||
user binding the second socket is the same that bound the first socket or the
|
||||
user binding the second socket has superuser privileges.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_SNDBUF Fa "int"
|
||||
How many bytes the send queue can use (default is 64 KiB).
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_TYPE Fa "int"
|
||||
The socket type
|
||||
.Dv ( SOCK_STREAM ) .
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.El
|
||||
.Pp
|
||||
TCP sockets currently implement no
|
||||
.Xr setsockopt 2 /
|
||||
.Xr getsockopt 2
|
||||
options at level
|
||||
.Dv IPPROTO_TCP .
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
Connections time out when a segment has not been acknowledged by the remote
|
||||
socket after 6 attempts to deliver the segment.
|
||||
Each retransmission happens after 1 second plus 1 second per failed
|
||||
transmissions so far.
|
||||
Successful delivery of any segment resets the retransmission count to 0.
|
||||
.Pp
|
||||
The receive and transmission buffers are both 64 KiB by default.
|
||||
.Pp
|
||||
If no specific port is requested, one is randomly selected in the dynamic port
|
||||
range 32768 (inclusive) through 61000 (exclusive).
|
||||
.Pp
|
||||
The Maximum Segment Lifetime (MSL) is set to 30 seconds and the quiet time of
|
||||
two MSLs before reusing sockets is 60 seconds.
|
||||
.Sh ERRORS
|
||||
Socket operations can fail due to these error conditions, in addition to the
|
||||
error conditions of the network and link layer, and the error conditions of the
|
||||
invoked function.
|
||||
.Bl -tag -width [EADDRNOTAVAIL]
|
||||
.It Bq Er EADDRINUSE
|
||||
The socket cannot be bound to the requested address and port because another
|
||||
socket was already bound to 1) the same address and port 2) the any address
|
||||
and the same port (and
|
||||
.Dv SO_REUSEADDR
|
||||
was not set on both sockets), or 3) some address and the same port but the
|
||||
requested address was the any address (and
|
||||
.Dv SO_REUSEADDR
|
||||
was not set on both sockets).
|
||||
.It Bq Er EADDRNOTAVAIL
|
||||
The socket cannot be bound to the requested address because no network interface
|
||||
had that address or broadcast address.
|
||||
.It Bq Er EADDRNOTAVAIL
|
||||
The socket was connected to port 0.
|
||||
.It Bq Er EAGAIN
|
||||
A port could not be assigned because each port in the dynamic port range had
|
||||
already been bound to a socket in a conflicting manner.
|
||||
.It Bq Er ECONNREFUSED
|
||||
The destination host refused the connection.
|
||||
.It Bq Er ECONNRESET
|
||||
The connection was reset by the remote socket.
|
||||
.It Bq Er EHOSTDOWN
|
||||
The destination host is not up.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er EHOSTUNREACH
|
||||
The destination host was unreachable.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er ENETDOWN
|
||||
The network interface isn't up.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er ENETUNREACH
|
||||
The destination network was unreachable.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er ENETUNREACH
|
||||
The remote address could not be connected because there was no route from the
|
||||
local address to the remote address.
|
||||
.It Bq Er ENOBUFS
|
||||
There was not enough memory available for network packets.
|
||||
.It Bq Er EPERM
|
||||
The unimplemented
|
||||
.Dv SO_DEBUG
|
||||
socket options was attempted to be set to a non-zero value.
|
||||
.It Bq Er EPIPE
|
||||
The transmission failed because the connetion is broken.
|
||||
The
|
||||
.Dv SIGPIPE
|
||||
signal is sent as well unless disabled.
|
||||
.It Bq Er ETIMEDOUT
|
||||
The connection timed out delivering a segment.
|
||||
This error can happen asynchronously.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr accept 2 ,
|
||||
.Xr bind 2 ,
|
||||
.Xr connect 2 ,
|
||||
.Xr getpeername 2 ,
|
||||
.Xr getsockname 2 ,
|
||||
.Xr getsockopt 2 ,
|
||||
.Xr poll 2 ,
|
||||
.Xr recv 2 ,
|
||||
.Xr recvfrom 2 ,
|
||||
.Xr recvmsg 2 ,
|
||||
.Xr send 2 ,
|
||||
.Xr sendmsg 2 ,
|
||||
.Xr sendto 2 ,
|
||||
.Xr setsockopt 2 ,
|
||||
.Xr shutdown 2 ,
|
||||
.Xr socket 2 ,
|
||||
.Xr if 4 ,
|
||||
.Xr inet 4 ,
|
||||
.Xr ip 4 ,
|
||||
.Xr kernel 7
|
||||
.Sh STANDARDS
|
||||
.Rs
|
||||
.%A J. Postel (ed.)
|
||||
.%D September 1981
|
||||
.%R STD 7
|
||||
.%R RFC 793
|
||||
.%T Transmission Control Protocol
|
||||
.%Q USC/Information Sciences Institute
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A Internet Engineering Task Force
|
||||
.%A R. Braden (ed.)
|
||||
.%D October 1989
|
||||
.%R STD 3
|
||||
.%R RFC 1122
|
||||
.%T Requirements for Internet Hosts -- Communication Layers
|
||||
.%Q USC/Information Sciences Institute
|
||||
.Re
|
||||
.Pp
|
||||
.St -p1003.1-2008 specifies the TCP socket programming interface.
|
||||
.Sh BUGS
|
||||
The implementation is incomplete and has known bugs.
|
||||
.Pp
|
||||
Out-of-band data is not yet supported and is ignored on receipt.
|
||||
.Pp
|
||||
The round trip time is not estimated which prevents efficient retransmission
|
||||
when data is lost
|
||||
Retransmissions happen after a second, which means unnecessary retransmissions
|
||||
happen if the round trip time is more than a second.
|
||||
.Pp
|
||||
Options are not supported and are ignored on receipt.
|
||||
.Pp
|
||||
No extensions are implemented yet that improve efficiency for long fast networks
|
||||
with large bandwidth * delay products.
|
||||
.Pp
|
||||
There is not yet any support for sending keep-alive packets.
|
||||
.Pp
|
||||
There is not yet any support for respecting
|
||||
.Xr icmp 4
|
||||
condition such as destination unreachable or source quench.
|
||||
.Pp
|
||||
Half-open connections use memory, but until the handshake is complete, it is not
|
||||
confirmed whether the remote is actually able to transmit from the source
|
||||
qaddress.
|
||||
An attacker may be able to transmit many packets from forged addresses,
|
||||
reaching the limit on pending TCP sockets in the listen queue and thus deny
|
||||
service to further legitimate connections.
|
||||
A SYN queue or SYN cookies would mitigate this problem, but neither is yet
|
||||
implemented.
|
||||
.Pp
|
||||
.Xr bind 2
|
||||
does not yet enforce that binding to a well-known port (port 1 through port
|
||||
1023) requires superuser privileges.
|
||||
.Pp
|
||||
The automatic assignment of ports is random, but is statistically biased.
|
||||
A random port is picked, and if it is taken, the search sequentially iterates
|
||||
ports in ascending order until an available port is found or the search
|
||||
terminates.
|
699
share/man/man4/udp.4
Normal file
699
share/man/man4/udp.4
Normal file
|
@ -0,0 +1,699 @@
|
|||
.Dd June 4, 2017
|
||||
.Dt UDP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm udp
|
||||
.Nd user datagram protocol
|
||||
.Sh SYNOPSIS
|
||||
.In sys/socket.h
|
||||
.In netinet/in.h
|
||||
.In netinet/udp.h
|
||||
.Ft int
|
||||
.Fn socket AF_INET SOCK_DGRAM IPPROTO_UDP
|
||||
.Sh DESCRIPTION
|
||||
The User Datagram Protocol (UDP) is a connectionless transport layer for the
|
||||
Internet Protocol
|
||||
.Xr ip 4
|
||||
that provides best-effort delivery of datagrams.
|
||||
It is designed for packet-switched networks and provides multiplexing with a
|
||||
16-bit port number, basic data integrity checks (16-bit ones' complement sum),
|
||||
and broadcasting.
|
||||
It does not provide a guarantee of delivery, avoidance of delivering multiple
|
||||
times, ordering, out of band data, nor flow control.
|
||||
UDP provides the
|
||||
.Dv SOCK_DGRAM
|
||||
abstraction for the
|
||||
.Xr inet 4
|
||||
protocol family.
|
||||
.Pp
|
||||
UDP sockets are made with
|
||||
.Xr socket 2
|
||||
by passing an appropriate
|
||||
.Fa domain
|
||||
.Dv ( AF_INET ) ,
|
||||
.Dv SOCK_DGRAM
|
||||
as the
|
||||
.Fa type ,
|
||||
and 0 or
|
||||
.Dv IPPROTO_UDP
|
||||
as the
|
||||
.Fa protocol .
|
||||
Initially a socket is not bound, it won't receive datagrams, and it does not
|
||||
have a remote address and port set.
|
||||
.Pp
|
||||
A UDP socket has the following state:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
The address family it belongs to.
|
||||
.It
|
||||
The network interface it is bound to (if any)
|
||||
.Dv ( SO_BINDTODEVICE
|
||||
and
|
||||
.Dv SO_BINDTOINDEX )
|
||||
(initially none).
|
||||
.It
|
||||
The local address and port (when bound) (initially none).
|
||||
.It
|
||||
The remote address and port (when connected) (initially none).
|
||||
.It
|
||||
A receive queue (initially empty).
|
||||
.It
|
||||
Whether the socket has been
|
||||
.Xr shutdown 2
|
||||
for read and/or write (initially neither).
|
||||
.It
|
||||
A single pending asynchronous error (if any)
|
||||
.Dv ( SO_ERROR )
|
||||
(initially none).
|
||||
.It
|
||||
Whether broadcast datagrams can be sent
|
||||
.Dv ( SO_BROADCAST )
|
||||
(initially no).
|
||||
.It
|
||||
Whether binding to the any address and a port doesn't conflict with binding to
|
||||
another address on the same port
|
||||
.Dv ( SO_REUSEADDR )
|
||||
(initially no).
|
||||
.It
|
||||
Limits on the size of the receive and send queues
|
||||
.Dv ( SO_RCVBUF
|
||||
and
|
||||
.Dv SO_SNDBUF ) .
|
||||
.El
|
||||
.Pp
|
||||
Datagrams are sent as a packet with a header and the datagram itself.
|
||||
The header contains the source port, the destination port, the checksum, and the
|
||||
packet's length.
|
||||
The length is a 16-bit value, allowing the packet to be up to 65535 bytes.
|
||||
The header is 8 bytes, allowing the maximum datagram size of 65527 bytes.
|
||||
However, the actual maximum datagram size may be smaller, as the network layer
|
||||
and link layer, as well as the path to the destination host, will add their own
|
||||
headers and maximum transmission unit (MTU) restrictions.
|
||||
.Pp
|
||||
Port numbers are 16-bit and range from 1 to 65535.
|
||||
Port 0 is not valid.
|
||||
Binding to port 0 will assign an available port on the requested address.
|
||||
Sending or connecting to port 0 will fail with
|
||||
.Er EADDRNOTAVAIL .
|
||||
Received packets whose source or destination address is port 0 will be silently
|
||||
dropped.
|
||||
UDP ports are distinct from ports in other transport layer protocols.
|
||||
.Pp
|
||||
Packets contain a 16-bit ones' complement checksum by default.
|
||||
Unless the packet has no checksum, a received packet will be silently discarded
|
||||
if its checksum does not match its contents.
|
||||
.Pp
|
||||
Sockets can be bound to a local address and port with
|
||||
.Xr bind 2
|
||||
(if not already bound),
|
||||
or an local address and port will be automatically assigned on the first send
|
||||
or connect operation.
|
||||
The local address and port can be read with
|
||||
.Xr getsockname 2 .
|
||||
If the socket hasn't been bound, the local address and port is reported as the
|
||||
any address on port 0.
|
||||
Binding to a well-known port (port 1 through port 1023) requires superuser
|
||||
privileges.
|
||||
.Pp
|
||||
Sockets can be bound to the any address, the broadcast address, the address of
|
||||
a network interface, or the broadcast address of a network interface.
|
||||
Binding to port 0 will automatically assign an available port on the requested
|
||||
local address or fail with
|
||||
.Er EAGAIN
|
||||
if no port is available.
|
||||
No two sockets can bind to the same local address and port.
|
||||
No two sockets can be bound such that one is bound to the any address and a
|
||||
port, and the other socket is bound to another address and the same port; unless
|
||||
both sockets had the
|
||||
.Dv SO_REUSEADDR
|
||||
socket option set when the second socket was bound, and the current user is the
|
||||
same that bound the first socket or the current user has superuser privileges.
|
||||
.Pp
|
||||
A socket bound to a local address and port will receive an incoming datagram if
|
||||
the following conditions hold:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
The datagram belongs to the socket's address family and the protocol is UDP.
|
||||
.It
|
||||
The datagram's checksum matches the datagram or it has no checksum.
|
||||
.It
|
||||
The datagram is not sent from port 0 and is not sent to port 0.
|
||||
.It
|
||||
The datagram is sent to the address or broadcast address of the network
|
||||
interface it is received on, or the datagram was sent to the broadcast address;
|
||||
.It
|
||||
The socket is either bound to the receiving network interface, or the socket is
|
||||
not bound to a network interface;
|
||||
.It
|
||||
The datagram is sent to the socket's local port;
|
||||
.It
|
||||
The datagram is sent to the socket's local address, or the socket's local
|
||||
address is the any address (and no other socket is bound to the datagram's
|
||||
address and that port);
|
||||
.It
|
||||
The socket is connected and the datagram was sent from the remote address and
|
||||
the remote port, or the socket is not connected; and
|
||||
.It
|
||||
The socket is not shut down for reading.
|
||||
.El
|
||||
.Pp
|
||||
If so, the datagram is added to the socket's receive queue, otherwise it is
|
||||
discarded.
|
||||
The receive queue contains incoming packets waiting to be received.
|
||||
Incoming packets are dropped if the receive queue is full.
|
||||
Shrinking the receive queue limit drops packets as needed to stay below the
|
||||
limit.
|
||||
.Pp
|
||||
The remote address and port can be set multiple times with
|
||||
.Xr connect 2 ,
|
||||
after which the socket is said to be connected, but UDP is connectionless and
|
||||
no handshake is sent.
|
||||
The remote port must not be port 0 or the connection will fail with
|
||||
.Er EADDRNOTAVAIL .
|
||||
If the socket is not bound,
|
||||
.Xr connect 2
|
||||
will determine which network interface will be used to send to the remote
|
||||
address, and then bind to the address of that network interface together with an
|
||||
available port.
|
||||
.Xr connect 2
|
||||
will fail if there is no route from the local address to the requested remote
|
||||
address.
|
||||
A connected socket only receive datagrams from the remote address and port.
|
||||
.Xr connect 2
|
||||
will drop datagrams in the receive queue that don't originate from the
|
||||
requested remote address.
|
||||
The
|
||||
.Xr send 2 ,
|
||||
.Xr write 2 ,
|
||||
and
|
||||
.Xr writev 2
|
||||
functions can be used on a connected socket and they send to the remote address
|
||||
and port by default.
|
||||
If the socket is connected, the destination given to
|
||||
.Xr sendto 2
|
||||
and
|
||||
.Xr sendmsg 2
|
||||
must be
|
||||
.Dv NULL .
|
||||
The remote address and port can be read with
|
||||
.Xr getpeername 2 .
|
||||
.Pp
|
||||
The socket can be disconnected by connecting to a socket address with the family
|
||||
value set to
|
||||
.Dv AF_UNSPEC ,
|
||||
which resets the remote address and port (if set), and otherwise has no effect.
|
||||
The socket can be disconnected even if not connected, but it has no effect.
|
||||
.Pp
|
||||
Datagrams can be sent with
|
||||
.Xr sendmsg 2
|
||||
and
|
||||
.Xr sendto 2 .
|
||||
Sending on a unbound socket will bind to the any address and an available port,
|
||||
or fail with
|
||||
.Er EAGAIN
|
||||
if no port is available.
|
||||
Datagrams can be received with
|
||||
.Xr recvmsg 2 ,
|
||||
.Xr recvfrom 2 ,
|
||||
.Xr recv 2 ,
|
||||
.Xr read 2 ,
|
||||
and
|
||||
.Xr readv 2 .
|
||||
If an asynchronous error is pending, the next send and receive operation will
|
||||
fail with that error and clear the asynchronous eror, so the next operation can
|
||||
succeed.
|
||||
Asynchronous errors can arise from network problems.
|
||||
There is no send queue at the UDP level and datagrams are directly forwarded to
|
||||
the network layer.
|
||||
It is an error to use any of the flags
|
||||
.Dv MSG_CMSG_CLOEXEC ,
|
||||
.Dv MSG_CMSG_CLOFORK ,
|
||||
.Dv MSG_EOR ,
|
||||
.Dv MSG_OOB ,
|
||||
and
|
||||
.Dv MSG_WAITALL .
|
||||
.Pp
|
||||
The condition of the socket can be tested with
|
||||
.Xr poll 2
|
||||
where
|
||||
.Dv POLLIN
|
||||
signifies a packet has been received (or the socket is shut down for reading),
|
||||
.Dv POLLOUT
|
||||
signifies a packet can be sent now (and the socket is not shut down for
|
||||
writing),
|
||||
.Dv POLLHUP
|
||||
signifies the socket is shut down for writing, and
|
||||
.Dv POLLERR
|
||||
signifies an asynchronous error is pending.
|
||||
.Pp
|
||||
The socket can be shut down for receiving and/or sending with
|
||||
.Xr shutdown 2 .
|
||||
The receive queue is emptied when shut down for receive (asynchronous errors are
|
||||
preserved) and receive operations will succeed with an end of file
|
||||
condition, but any pending asynchronous errors will take precedence and be
|
||||
delivered instead.
|
||||
Sending when shut down for writing will raise
|
||||
.Dv SIGPIPE
|
||||
and fail with
|
||||
.Er EPIPE
|
||||
(regardless of a pending asynchronous error).
|
||||
.Pp
|
||||
Socket options can be set with
|
||||
.Xr setsockopt 2
|
||||
and read with
|
||||
.Xr getsockopt 2
|
||||
and exist on the
|
||||
.Dv IPPROTO_UDP
|
||||
level as well as applicable underlying protocol levels.
|
||||
.Pp
|
||||
Broadcast datagrams can be sent by setting the
|
||||
.Dv SO_BROADCAST
|
||||
socket option with
|
||||
.Xr setsockopt 2
|
||||
and sending to a broadcast address of the network layer.
|
||||
.Sh SOCKET OPTIONS
|
||||
UDP sockets support these
|
||||
.Xr setsockopt 2 /
|
||||
.Xr getsockopt 2
|
||||
options at level
|
||||
.Dv SOL_SOCKET :
|
||||
.Bl -tag -width "12345678"
|
||||
.It Dv SO_BINDTODEVICE Fa "char[]"
|
||||
Bind to a network interface by its name.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_BINDTOINDEX Fa "unsigned int"
|
||||
Bind to a network interface by its index number.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_BROADCAST Fa "int"
|
||||
Whether sending to a broadcast address is allowed.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_DEBUG Fa "int"
|
||||
Whether the socket is in debug mode.
|
||||
This option is not implemented and is initially 0.
|
||||
Attempting to set it to non-zero will fail with
|
||||
.Er EPERM .
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_DOMAIN Fa "sa_family_t"
|
||||
The socket
|
||||
.Fa domain
|
||||
(the address family).
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_DONTROUTE Fa "int"
|
||||
Whether to bypass the routing table and only send on the local network.
|
||||
This option is not implemented and is initially 0.
|
||||
Attempting to set it to non-zero will fail with
|
||||
.Er EPERM .
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_ERROR Fa "int"
|
||||
The asynchronous pending error
|
||||
(an
|
||||
.Xr errno 3
|
||||
value).
|
||||
Cleared to 0 when read.
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_PROTOCOL Fa "int"
|
||||
The socket protocol
|
||||
.Dv ( IPPROTO_UDP ) .
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_RCVBUF Fa "int"
|
||||
How many bytes the receive queue can use (default is 64 pages, max 4096 pages).
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_REUSEADDR Fa "int"
|
||||
Whether binding to the any address on a port doesn't conflict with binding to
|
||||
another address and the same port, if both sockets have this option set and the
|
||||
user binding the second socket is the same that bound the first socket or the
|
||||
user binding the second socket has superuser privileges.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_SNDBUF Fa "int"
|
||||
How many bytes the send queue can use (default is 64 pages, max 4096 pages).
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.It Dv SO_TYPE Fa "int"
|
||||
The socket type
|
||||
.Dv ( SOCK_DGRAM ) .
|
||||
This option can only be read.
|
||||
(Described in
|
||||
.Xr if 4 )
|
||||
.El
|
||||
.Pp
|
||||
UDP sockets currently implement no
|
||||
.Xr setsockopt 2 /
|
||||
.Xr getsockopt 2
|
||||
options at level
|
||||
.Dv IPPROTO_UDP .
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
There is no way to disable the checksum on sent packets, however received
|
||||
packets without a checksum will not be checksummed.
|
||||
.Pp
|
||||
Each packet currently use a page of memory, which counts towards the receive
|
||||
queue limit.
|
||||
.Pp
|
||||
If no specific port is requested, one is randomly selected in the dynamic port
|
||||
range 32768 (inclusive) through 61000 (exclusive).
|
||||
.Sh EXAMPLES
|
||||
This example creates and binds a UDP socket to a local address and port and
|
||||
sends a broadcast datagram to a remote address and port and receives a response
|
||||
and remembers who sent the response.
|
||||
.Va local
|
||||
is the local socket address that is bound to and
|
||||
.Va local_len
|
||||
is the size of the local socket address and likewise with
|
||||
.Va remote
|
||||
and
|
||||
.Va remote_len .
|
||||
.Va responder
|
||||
is an uninitialized socket address of the appropriate size
|
||||
.Va responder_len
|
||||
for the protocol family
|
||||
.Va af
|
||||
where the source address of the response is stored.
|
||||
The response is stored in the
|
||||
.Va incoming
|
||||
array of size
|
||||
.Va amount .
|
||||
The
|
||||
.Va af , local , local_len , remote , remote_len , responder ,
|
||||
and
|
||||
.Va responder_len
|
||||
values should all be chosen according to the address family and network layer.
|
||||
.Bd -literal
|
||||
sa_family_t af = /* ... */;
|
||||
const struct sockaddr *local = /* ... */;
|
||||
socklen_t local_len = /* ... */;
|
||||
const struct sockaddr *remote = /* ... */;
|
||||
socklen_t remote_len = /* ... */;
|
||||
const struct sockaddr *responder = /* ... */;
|
||||
socklen_t responder_len = /* ... */;
|
||||
|
||||
int fd = socket(af, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (fd < 0)
|
||||
err(1, "socket");
|
||||
if (bind(fd, local, local_len) < 0)
|
||||
err(1, "bind");
|
||||
int value = 1;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value)) < 0)
|
||||
err(1, "setsockopt");
|
||||
char outgoing[] = "Hello";
|
||||
if (sendto(fd, outgoing, strlen(outgoing), 0, remote, remote_len) < 0)
|
||||
err(1, "sendto");
|
||||
char incoming[1024];
|
||||
ssize_t amount = recvfrom(fd, incoming, sizeof(incoming), 0,
|
||||
responder, &responder_len);
|
||||
if (amount < 0 )
|
||||
err(1, "recvfrom");
|
||||
.Ed
|
||||
.Sh COMPATIBILITY
|
||||
Sortix is the only known system where
|
||||
.Xr connect 2
|
||||
will remove datagrams from the wrong source from the receive queue.
|
||||
All other systems will deliver datagrams already present in the receive queue,
|
||||
even if from the wrong source, despite the POSIX requirement that
|
||||
.Xr connect 2
|
||||
"limits the remote sender for subsequent recv() functions".
|
||||
Software for affected systems must either first empty the receive queue after
|
||||
.Xr connect 2 ,
|
||||
or use
|
||||
.Xr recvmsg 2
|
||||
and validate the source address rather than rely on the kernel validation.
|
||||
.Pp
|
||||
.Xr sendto 2
|
||||
or
|
||||
.Xr sendmsg 2
|
||||
on a connected socket must have the destination be
|
||||
.Dv NULL
|
||||
(the default destination)
|
||||
on Sortix, FreeBSD, Haiku, macOS, NetBSD, OpenBSD, and SunOS; but the
|
||||
destination can be
|
||||
.Dv NULL
|
||||
or any address on DragonFly, GNU/Hurd, Linux, and Minix.
|
||||
.Pp
|
||||
Socket disconnect is implemented on Sortix, DragonFly, Haiku, GNU/Hurd, Linux,
|
||||
Minix, and SunOS; but socket disconnect is not implemented on on FreeBSD, macOS,
|
||||
NetBSD and OpenBSD.
|
||||
Storing the
|
||||
.Dv AF_FAMILY
|
||||
value in the address family's socket address structure or struct sockaddr is
|
||||
portable to the systems implementing socket disconnect.
|
||||
A socket can be disconnected even if not connected on Sortix, DragonFly, Haiku,
|
||||
GNU/Hurd, Linux, and Minix; but SunOS requires the socket to be connected
|
||||
before it can be disconnected.
|
||||
.Pp
|
||||
The broadcast address can be bound on Sortix, GNU/Hurd, Linux, OpenBSD, and
|
||||
SunOS; but can't be bound on DragonFly, FreeBSD, macOS, Minix and NetBSD.
|
||||
.Pp
|
||||
.Dv SO_BROADCAST
|
||||
doesn't need to be enabled to
|
||||
.Xr connect 2
|
||||
to the broadcast address on Sortix, DragonFly, FreeBSD, Haiku, macOS, Minix,
|
||||
NetBSD, OpenBSD, and SunOS; but is required on GNU/Hurd and Linux.
|
||||
.Pp
|
||||
Reconnecting a socket to an address that is not reachable from the local address
|
||||
will fail on Sortix, GNU/Hurd, and Linux; but the socket will be bound to
|
||||
another address that can reach the remote address (even though it is not
|
||||
possible to bind a socket twice) (on the same port if possible) on DragonFly,
|
||||
FreeBSD, Haiku, macOS, NetBSD, OpenBSD, and SunOS.
|
||||
.Pp
|
||||
.Xr connect 2
|
||||
will not deliver asynchronous errors on Sortix, DragonFly, FreeBSD, Haiku,
|
||||
GNU/Hurd, Linux, and Minix; however it will deliver asynchronous errors on
|
||||
macOS, NetBSD, OpenBSD, and SunOS.
|
||||
.Pp
|
||||
Shutting a socket down for reading will cause receives to return 0 on Sortix,
|
||||
DragonFly, FreeBSD, macOS, Minix, NetBSD, OpenBSD, and SunOS; but receives will
|
||||
fail with fail with
|
||||
.Er EWOULDBLOCK
|
||||
on Linux.
|
||||
.Pp
|
||||
Shutting a socket down for writing will cause sends to raise SIGPIPE and fail
|
||||
with EPIPE on Sortix, DragonFly, FreeBSD, GNU/Hurd, macOS, NetBSD, OpenBSD, and
|
||||
SunOS; but will not raise SIGPIPE and only fail with EPIPE on Linux and Minix.
|
||||
.Pp
|
||||
Sortix, GNU/Hurd, Linux, and Minix will signal POLLIN if a datagram has been
|
||||
received or if shut down for read.
|
||||
DragonFly, FreeBSD, macOS, NetBSD, OpenBSD, and SunOS will signal POLLIN if a
|
||||
datagram has been received, if shut down for read, or if an error is pending.
|
||||
.Pp
|
||||
Sortix and DragonFly will signal POLLOUT if a datagram can be sent, unless the
|
||||
socket has been shut down for write.
|
||||
FreeBSD will signal POLLOUT if a datagram can be sent, unless the socket has
|
||||
been shut down for both read and write.
|
||||
GNU/Hurd will signal POLLOUT if a datagram can be sent, unless the socket has
|
||||
been shut down for write or if an error is pending.
|
||||
Linux, Minix, OpenBSD, and SunOS will signal POLLOUT if a datagram can be sent,
|
||||
regardless of whether the socket has been shut down.
|
||||
macOS will signal POLLOUT if a datagram can be sent, unless the socket has been
|
||||
shut down for either read or write.
|
||||
.Pp
|
||||
Sortix and DragonFly will signal POLLHUP if shut down for write.
|
||||
FreeBSD and Linux will signal POLLHUP if shut down for both read and write.
|
||||
GNU/Hurd, macOS, Minix, NetBSD, OpenBSD, and SunOS will not signal POLLHUP.
|
||||
macOS will signal POLLHUP if shut down for either read or write.
|
||||
.Pp
|
||||
Sortix, Haiku, GNU/Hurd, and Linux will signal POLLERR if an error is pending.
|
||||
DragonFly, FreeBSD, macOS, Minix, NetBSD, OpenBSD, and SunOS will not signal
|
||||
POLLERR.
|
||||
.Pp
|
||||
Shutting a socket down for read doesn't work on GNU/Hurd and Linux, where the
|
||||
socket continues to receive datagrams.
|
||||
.Pp
|
||||
Linux delivers asynchronous errors on send, even if shut down for write.
|
||||
.Pp
|
||||
Sockets can be shut down even if not connected on Sortix, DragonFly, Minix,
|
||||
NetBSD, and OpenBSD; but sockets must be connected before they can be shut down
|
||||
on FreeBSD, GNU/Hurd, Linux, macOS, and SunOS.
|
||||
.Pp
|
||||
Connecting to the any address will fail with
|
||||
.Er ENETUNREACH
|
||||
on Sortix.
|
||||
On DragonFly, FreeBSD, Haiku, GNU/Hurd, Linux, macOS, OpenBSD, and SunOS it will
|
||||
succeed and
|
||||
.Xr getpeername 2
|
||||
will report the loopback address (OpenBSD will report the any address).
|
||||
.Pp
|
||||
Connecting to port 0 will fail on Sortix, FreeBSD, macOS, Minix, NetBSD, OpenBSD,
|
||||
and SunOS; but will succeed on DragonFly, Haiku, GNU/Hurd and Linux.
|
||||
.Pp
|
||||
Sortix's handling of
|
||||
.Dv SO_REUSEADDR
|
||||
requires the two sockets to bound by the same user or the second socket to be
|
||||
bound by a user with superuser privileges.
|
||||
It's unclear what other systems also perform this check and when the user
|
||||
identity is captured.
|
||||
.Pp
|
||||
Setting
|
||||
.Dv SO_REUSEADDR
|
||||
on both sockets is required on Sortix, Haiku, GNU/Hurd, and Linux; but
|
||||
DragonFly, FreeBSD, Minix, macOS, NetBSD, OpenBSD, and SunOS only require it to
|
||||
be set on the second socket.
|
||||
.Pp
|
||||
Two sockets can't be bound to the same address and port on Sortix, DragonFly,
|
||||
FreeBSD, Haiku, macOS, NetBSD, and OpenBSD; but GNU/Hurd, Linux, Minix, and
|
||||
SunOS allows it when
|
||||
.Dv SO_REUSEADDR
|
||||
is set.
|
||||
.Sh ERRORS
|
||||
Socket operations can fail due to these error conditions, in addition to the
|
||||
error conditions of the network and link layer, and the error conditions of the
|
||||
invoked function.
|
||||
.Bl -tag -width [EADDRNOTAVAIL]
|
||||
.It Bq Er EACCES
|
||||
A datagram was sent to a broadcast address, but
|
||||
.Dv SO_BROADCAST
|
||||
is turned off.
|
||||
.It Bq Er EADDRINUSE
|
||||
The socket cannot be bound to the requested address and port because another
|
||||
socket was already bound to 1) the same address and port 2) the any address
|
||||
and the same port (and
|
||||
.Dv SO_REUSEADDR
|
||||
was not set on both sockets), or 3) some address and the same port but the
|
||||
requested address was the any address (and
|
||||
.Dv SO_REUSEADDR
|
||||
was not set on both sockets).
|
||||
.It Bq Er EADDRNOTAVAIL
|
||||
The socket cannot be bound to the requested address because no network interface
|
||||
had that address or broadcast address.
|
||||
.It Bq Er EADDRNOTAVAIL
|
||||
The socket was connected to port 0, or a datagram was sent to port 0.
|
||||
.It Bq Er EAGAIN
|
||||
A port could not be assigned because each port in the dynamic port range had
|
||||
already been bound to a socket in a conflicting manner.
|
||||
.It Bq Er ECONNREFUSED
|
||||
The destination host of a datagram was not listening on the port.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er EHOSTDOWN
|
||||
The destination host of a datagram is not up.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er EHOSTUNREACH
|
||||
The destination host of a datagram was unreachable.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er EISCONN
|
||||
A destination address and port was specified when sending a datagram, but the
|
||||
socket has already been connected to a remote address and port.
|
||||
.It Bq Er EMSGSIZE
|
||||
The datagram was too large to be sent because it exceeded the maximum
|
||||
transmission unit (MTU) on the path between the local and remote address, or it
|
||||
exceeded the UDP datagram size limit of 65527 bytes.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er ENETDOWN
|
||||
The network interface used to deliver a datagram isn't up.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er ENETUNREACH
|
||||
The destination network of a datagram was unreachable.
|
||||
This error can happen asynchronously.
|
||||
.It Bq Er ENETUNREACH
|
||||
The remote address could not be connected because there was no route from the
|
||||
local address to the remote address.
|
||||
.It Bq Er ENOBUFS
|
||||
There was not enough memory available for network packets.
|
||||
.It Bq Er EPERM
|
||||
One of the unimplemented
|
||||
.Dv SO_DEBUG
|
||||
and
|
||||
.Dv SO_DONTROUTE
|
||||
socket options was attempted to be set to a non-zero value.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr bind 2 ,
|
||||
.Xr connect 2 ,
|
||||
.Xr getpeername 2 ,
|
||||
.Xr getsockname 2 ,
|
||||
.Xr getsockopt 2 ,
|
||||
.Xr poll 2 ,
|
||||
.Xr recvfrom 2 ,
|
||||
.Xr recvmsg 2 ,
|
||||
.Xr sendmsg 2 ,
|
||||
.Xr sendto 2 ,
|
||||
.Xr setsockopt 2 ,
|
||||
.Xr shutdown 2 ,
|
||||
.Xr socket 2 ,
|
||||
.Xr if 4 ,
|
||||
.Xr inet 4 ,
|
||||
.Xr ip 4 ,
|
||||
.Xr kernel 7
|
||||
.Sh STANDARDS
|
||||
.Rs
|
||||
.%A J. Postel
|
||||
.%D August 1980
|
||||
.%R STD 6
|
||||
.%R RFC 768
|
||||
.%T User Datagram Protocol
|
||||
.%Q USC/Information Sciences Institute
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A Internet Engineering Task Force
|
||||
.%A R. Braden (ed.)
|
||||
.%D October 1989
|
||||
.%R STD 3
|
||||
.%R RFC 1122
|
||||
.%T Requirements for Internet Hosts -- Communication Layers
|
||||
.%Q USC/Information Sciences Institute
|
||||
.Re
|
||||
.Pp
|
||||
.St -p1003.1-2008 specifies the UDP socket programming interface and defines the
|
||||
socket options
|
||||
.Dv SO_BROADCAST , SO_DEBUG , SO_DONTROUTE, SO_ERROR, SO_RCVBUF, SO_REUSEADDR ,
|
||||
.Dv SO_SNDBUF ,
|
||||
and
|
||||
.Dv SO_TYPE .
|
||||
.Sh BUGS
|
||||
.Xr bind 2
|
||||
does not yet enforce that binding to a well-known port (port 1 through port
|
||||
1023) requires superuser privileges.
|
||||
.Pp
|
||||
The handling of
|
||||
.Dv SO_REUSEADDR in
|
||||
.Xr bind 2
|
||||
does not yet enforce the two sockets to be bound by the same user or the second
|
||||
socket to be bound by a user with superuser privileges.
|
||||
The requirement that both sockets have
|
||||
.Dv SO_REUSEADDR
|
||||
set might be relaxed to only the second socket having it set when this
|
||||
permission check is implemented.
|
||||
.Pp
|
||||
The integration with the network layer is inadequate and the asynchronous errors
|
||||
.Er ECONNREFUSED ,
|
||||
.Er EHOSTDOWN ,
|
||||
.Er EHOSTUNREACH ,
|
||||
and
|
||||
.Er ENETUNREACH
|
||||
are never delivered asynchronously from the network.
|
||||
.Pp
|
||||
The
|
||||
.Xr send 2
|
||||
flag
|
||||
.Dv MSG_DONTROUTE
|
||||
and the
|
||||
.Dv SO_DONTROUTE
|
||||
socket option are not implemented yet.
|
||||
.Pp
|
||||
The
|
||||
.Dv SO_SNDBUF
|
||||
socket option is currently not used and the send queue is not limited at the
|
||||
socket level.
|
||||
.Pp
|
||||
The automatic assignment of ports is random, but is statistically biased.
|
||||
A random port is picked, and if it is taken, the search sequentially iterates
|
||||
ports in ascending order until an available port is found or the search
|
||||
terminates.
|
||||
.Pp
|
||||
FreeBSD's and OpenBSD's UDP documentation states in the BUGS section that
|
||||
receiving a datagram on a socket shutdown for read should reply with a ICMP
|
||||
Port Unreachable message, however they don't implement this behavior.
|
||||
No other system appears to implement this behavior, and it is unclear whether
|
||||
it should be implemented.
|
|
@ -398,19 +398,21 @@ The
|
|||
makefile target can be used to verify your work needs some of the development
|
||||
conventions.
|
||||
.Pp
|
||||
You can then easily prepare your a set of patches for upstream submission:
|
||||
Prepare a set of patches suitable for upstream submission and submit a merge
|
||||
request to the upstream project.
|
||||
.Pp
|
||||
If your installation does not have network connectivity, you will need to
|
||||
submit the changes from another system.
|
||||
If you are dual booting and have another operating system with network
|
||||
connectivity, you can boot into the other operating system and mount the
|
||||
appropriate filesystem from there.
|
||||
If you have a serial line, you can produce a set of .patch files containing
|
||||
your changes with
|
||||
.Bd -literal
|
||||
git format-patch master..local
|
||||
.Ed
|
||||
.Pp
|
||||
This will create a series of .patch files containing your changes.
|
||||
Review them and rewrite git history as needed until they are of submittable
|
||||
quality.
|
||||
You can then submit them for review at the official website.
|
||||
.Pp
|
||||
To transfer files out of the operating system, you can either mount the local
|
||||
root filesystem from another operating system with networking, or you transmit
|
||||
the patches over the serial connection as described in
|
||||
and then transfer them over the serial connection as described in
|
||||
.Xr serial-transfer 7 .
|
||||
.Ss Releases
|
||||
CD-ROM release of the operating system can be built with the
|
||||
|
|
|
@ -69,6 +69,18 @@ releasing Sortix x.y, foo." to allow the maintainer to easily
|
|||
.Xr grep 1
|
||||
for it after a release.
|
||||
.Sh CHANGES
|
||||
.Ss Add networking stack
|
||||
The network stack has been implemented in the kernel and exposed through
|
||||
additions to the system call interface.
|
||||
.Pp
|
||||
This is a compatible ABI change that adds features to
|
||||
.Xr socket 2
|
||||
.Sy ( AF_INET , IPPROTO_TCP , IPPROTO_UDP , IPPROTO_PING ) ,
|
||||
the ioctls for
|
||||
.Xr if 4 ,
|
||||
socket options, and the
|
||||
.Xr lo 4
|
||||
loopback interface.
|
||||
.Ss Add daemon support to init(8)
|
||||
.Xr init 8
|
||||
has gained
|
||||
|
|
|
@ -82,7 +82,7 @@ per the instructions in
|
|||
The release modification procedure lets you customize aspects such as the
|
||||
default bootloader menu option and timeout, the default hostname, the default
|
||||
keyboard layout, the default graphics resolution, adding files of your choice to
|
||||
the live environment, and so on.
|
||||
the live environment, control which drivers are loaded by default, and so on.
|
||||
.Pp
|
||||
Warning: The live environment does not come with any random entropy and entropy
|
||||
gathering is not yet implemented.
|
||||
|
@ -130,6 +130,11 @@ You need enough memory to store the whole system and the runtime usage.
|
|||
If the system memory is really insufficient, then the bootloader may have
|
||||
strange behavior, take a really long time to load, or not complete the boot at
|
||||
all.
|
||||
.Ss Bootloader Advanced Options
|
||||
The bootloader advanced options menu lets you customize the live environment by
|
||||
making one-time adjustments to the boot process.
|
||||
These decisions will not carry over to the final installed system, which you
|
||||
instead will need to configure to have the same effects.
|
||||
.Pp
|
||||
You can configure which ports gets loaded using the bootloader menu.
|
||||
The base system is rather lean and can be made quite small.
|
||||
|
@ -367,6 +372,17 @@ If you invoked
|
|||
yourself, then you will be returned to your live environment shell.
|
||||
Otherwise the computer will power off when the chroot environment terminates.
|
||||
.Pp
|
||||
This is a last chance to make modifications before the new system boots for the
|
||||
first time.
|
||||
If you want to make final modifications to the system (examples are below), you
|
||||
can answer
|
||||
.Sy '!'
|
||||
to escape to a shell in the live environment inside the subdirectory where the
|
||||
new system is mounted.
|
||||
You can then run
|
||||
.Sy "chroot -d ."
|
||||
to enter a shell within the new installation.
|
||||
.Pp
|
||||
Upon boot of the new system it will be configured in multi-user mode and you
|
||||
will be presented with a login screen.
|
||||
Authenticate as one of the local users and you will be given a shell.
|
||||
|
@ -387,6 +403,55 @@ The
|
|||
manual page is a basic overview of the system for new users.
|
||||
.Pp
|
||||
Congratulations on your new Sortix system.
|
||||
.Ss Disabling Networking by Default
|
||||
To disable networking drivers by default, edit the bootloader configuration to
|
||||
pass the
|
||||
.Fl \-disable-network-drivers
|
||||
option by default on the
|
||||
.Xr kernel 7
|
||||
command line.
|
||||
.Pp
|
||||
If you are at the final stage of installation, you can answer
|
||||
.Sy '!'
|
||||
to get a shell in the live environment and then run
|
||||
.Sy "chroot -d ."
|
||||
to enter a shell inside the new installation.
|
||||
.Pp
|
||||
For instance, if GRUB is used the bootloader, networking can be disabled by
|
||||
default by done by editing
|
||||
.Pa /etc/grub.d/10_sortix
|
||||
of the new installation.
|
||||
.Xr editor 1
|
||||
or any editor can be used to edit the file.
|
||||
Change the line from
|
||||
.Bd -literal
|
||||
multiboot $BOOT_REL/sortix.bin
|
||||
.Ed
|
||||
.Pp
|
||||
to instead be
|
||||
.Bd -literal
|
||||
multiboot $BOOT_REL/sortix.bin --disable-network-drivers
|
||||
.Ed
|
||||
.Pp
|
||||
If the included GRUB bootloader is used, after making the above edit, run
|
||||
.Xr update-grub 8
|
||||
within the new installation to regenerate the bootloader configuration.
|
||||
Note that
|
||||
.Pa /etc/grub.d/10_sortix
|
||||
is part of the GRUB package and local changes will be undone when the GRUB
|
||||
package is updated or reinstalled, in which case you must make this change again
|
||||
and run
|
||||
.Xr update-grub 8
|
||||
again.
|
||||
.Pp
|
||||
If the included GRUB bootloader is not used, but instead the
|
||||
.Pa /etc/grub.d/10_sortix.cache
|
||||
fragment is spliced into another GRUB installation, make the above change and
|
||||
then run the
|
||||
.Pa /etc/grub.d/10_sortix
|
||||
command and use the freshly regenerated
|
||||
.Pa /etc/grub.d/10_sortix.cache
|
||||
fragment instead.
|
||||
.Sh SEE ALSO
|
||||
.Xr chkblayout 1 ,
|
||||
.Xr chvideomode 1 ,
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
.Nd operating system kernel
|
||||
.Sh SYNOPSIS
|
||||
.Pa /boot/sortix.bin
|
||||
.Op Fl \-disable-network-drivers
|
||||
.Op Fl \-enable-network-drivers
|
||||
.Op Fl \-no-random-seed
|
||||
.Op Fl \-
|
||||
.Op Ar init ...
|
||||
|
@ -46,6 +48,12 @@ otherwise.
|
|||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width "12345678"
|
||||
.It Fl \-disable-network-drivers
|
||||
Don't initialize any network drivers.
|
||||
This option ensures the booted system is not networked.
|
||||
.It Fl \-enable-network-drivers
|
||||
Do initialize network drivers.
|
||||
This is the default behavior.
|
||||
.It Fl \-no-random-seed
|
||||
Don't warn if no random seed file was loaded by the bootloader (usually from
|
||||
.Pa /boot/random.seed ) .
|
||||
|
|
|
@ -128,6 +128,8 @@ The
|
|||
.Sy hook_advanced_menu_pre
|
||||
hook is run.
|
||||
.Pp
|
||||
A menu entry is emitted to control whether network drivers are enabled.
|
||||
.Pp
|
||||
A menu entry is emitted that goes to the binary packages menu (which runs
|
||||
.Li configfile /boot/grub/tix.cfg )
|
||||
.Pp
|
||||
|
@ -260,6 +262,13 @@ If the selected menu option itself is a submenu, it can be appended with a
|
|||
.Sy '>'
|
||||
and another selection to pick a default menu option in that submenu, and so on.
|
||||
(Default: 0)
|
||||
.It Sy enable_network_drivers
|
||||
An additional
|
||||
.Xr kernel 7
|
||||
command line parameter that controls whether network drivers are enabled.
|
||||
Either set to the empty string (network drivers are enabled) or
|
||||
.Sy --disable-network-drivers .
|
||||
(Default: The empty string).
|
||||
.It Sy enable_src
|
||||
Whether to load the source code initrd containing
|
||||
.Pa /src .
|
||||
|
@ -330,6 +339,7 @@ with a
|
|||
.Xr kernel 7
|
||||
command line consisting of
|
||||
.Sy $no_random_seed
|
||||
.Sy $enable_network_drivers
|
||||
followed by the arguments to this function (which should contain
|
||||
.Li "-- /sbin/init --target=desired-target" )
|
||||
followed by any additional options to
|
||||
|
|
|
@ -16,7 +16,7 @@ configuration as described in section 5 of the manual.
|
|||
The release modification procedure lets you customize aspects such as the
|
||||
default bootloader menu option and timeout, the default hostname, the default
|
||||
keyboard layout, the default graphics resolution, adding files of your choice to
|
||||
the live environment, and so on.
|
||||
the live environment, control which drivers are loaded by default, and so on.
|
||||
.Ss Prerequisites
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
|
@ -390,6 +390,13 @@ hook_ports_menu_sets
|
|||
EOF
|
||||
tix-iso-add sortix.iso bootconfig
|
||||
.Ed
|
||||
.Ss Disable Networking Drivers By Default
|
||||
To customize a release so it doesn't load network drivers by default, useful for
|
||||
security reasons or to work around driver issues:
|
||||
.Bd -literal
|
||||
tix-iso-bootconfig --disable-network-drivers bootconfig
|
||||
tix-iso-add sortix.iso bootconfig
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr xorriso 1 ,
|
||||
.Xr development 7 ,
|
||||
|
|
|
@ -29,7 +29,7 @@ per the instructions in
|
|||
The release modification procedure lets you customize aspects such as the
|
||||
default bootloader menu option and timeout, the default hostname, the default
|
||||
keyboard layout, the default graphics resolution, adding files of your choice to
|
||||
the live environment, and so on.
|
||||
the live environment, control which drivers are loaded by default, and so on.
|
||||
.Pp
|
||||
Warning: The live environment does not come with any random entropy and entropy
|
||||
gathering is not yet implemented.
|
||||
|
|
|
@ -120,9 +120,14 @@ You can make a compatible filesystem with:
|
|||
.Pp
|
||||
.Dl $ mkfs.ext2 -O none,large_file,filetype
|
||||
.Ss Networking
|
||||
Sortix does not have networking at this time.
|
||||
Unix sockets have a basic implementation incapable of advanced features.
|
||||
The standard library and kernel provides stubs for many network interfaces.
|
||||
Internet Protocol version 4
|
||||
.Pq Xr ip 4
|
||||
networking is available if you have a supported network interface
|
||||
.Pq Xr if 4 .
|
||||
.Pp
|
||||
The Internet Protocol version 6
|
||||
.Xr ( ip6 4 )
|
||||
is not yet supported.
|
||||
.Ss Serial Transfer
|
||||
It is possible to transfer files over serial devices as described in
|
||||
.Xr serial-transfer 7 .
|
||||
|
|
|
@ -1126,6 +1126,8 @@ int main(void)
|
|||
}
|
||||
text("\n");
|
||||
|
||||
// TODO: Ask if networking should be disabled / enabled.
|
||||
|
||||
text("It's time to boot into the newly installed system.\n\n");
|
||||
|
||||
if ( strcasecmp(accept_grub, "no") == 0 )
|
||||
|
|
|
@ -22,6 +22,7 @@ append_title="modified by $(id -un)@$(hostname)"
|
|||
default=
|
||||
directory=
|
||||
enable_append_title=true
|
||||
enable_network_drivers=
|
||||
enable_src=
|
||||
init_target=
|
||||
liveconfig=
|
||||
|
@ -51,8 +52,10 @@ for argument do
|
|||
--default=*) default=$parameter ;;
|
||||
--default) previous_option=default ;;
|
||||
--disable-append-title) enable_append_title=false ;;
|
||||
--disable-network-drivers) enable_network_drivers=false ;;
|
||||
--disable-src) enable_src=false ;;
|
||||
--enable-append-title) enable_append_title=true ;;
|
||||
--enable-network-drivers) enable_network_drivers=true ;;
|
||||
--enable-src) enable_src=true ;;
|
||||
--init-target=*) init_target=$parameter ;;
|
||||
--init-target) previous_option=init_target ;;
|
||||
|
@ -135,6 +138,7 @@ mkdir -p -- "$directory/boot/grub"
|
|||
if [ -n "$timeout" ]; then
|
||||
printf 'timeout="%s"\n' "$timeout"
|
||||
fi
|
||||
print_enable_default "$enable_network_drivers" network_drivers network-drivers
|
||||
print_enable_default_bool "$enable_src" src src
|
||||
if $enable_append_title; then
|
||||
printf "base_menu_title=\"\$base_menu_title - \"'%s'\n" \
|
||||
|
|
|
@ -9,8 +9,10 @@
|
|||
.Op Fl \-append-title Ns = Ns Ar text
|
||||
.Op Fl \-default Ns = Ns Ar default-boot-menu-option
|
||||
.Op Fl \-disable-append-title
|
||||
.Op Fl \-disable-network-drivers
|
||||
.Op Fl \-disable-src
|
||||
.Op Fl \-enable-append-title
|
||||
.Op Fl \-enable-network-drivers
|
||||
.Op Fl \-enable-src
|
||||
.Op Fl \-init-target Ns = Ns Ar target
|
||||
.Op Fl \-liveconfig Ns = Ns Ar liveconfig-directory
|
||||
|
@ -89,6 +91,14 @@ GRUB variable.
|
|||
Don't append anything to the bootloader menu title by appending to the
|
||||
.Sy base_menu_title
|
||||
GRUB variable.
|
||||
.It Fl \-disable-network-drivers
|
||||
Disable network drivers by setting the
|
||||
.Sy enable_network_drivers
|
||||
GRUB variable to the
|
||||
.Fl \-disable-network-drivers
|
||||
option which will be passed on the
|
||||
.Xr kernel 7
|
||||
command line.
|
||||
.It Fl \-disable-src
|
||||
Disable loading the source code in
|
||||
.Pa /src
|
||||
|
@ -104,6 +114,14 @@ to the bootloader menu title by appending to the
|
|||
GRUB variable.
|
||||
This option is on by default and can be disabled with
|
||||
.Fl \-disable-append-title .
|
||||
.It Fl \-enable-network-drivers
|
||||
Enable network drivers by setting the
|
||||
.Sy enable_network_drivers
|
||||
GRUB variable to the
|
||||
.Fl \-enable-network-drivers
|
||||
option which will be passed on the
|
||||
.Xr kernel 7
|
||||
command line.
|
||||
.It Fl \-enable-src
|
||||
Enable loading the source code in
|
||||
.Pa /src
|
||||
|
@ -246,6 +264,13 @@ of your choice:
|
|||
tix-iso-bootconfig --append-title="Initech Company Edition" bootconfig
|
||||
tix-iso-add sortix.iso bootconfig
|
||||
.Ed
|
||||
.Ss Disable Networking Drivers By Default
|
||||
To customize a release so it doesn't load network drivers by default, useful for
|
||||
security reasons or to work around driver issues:
|
||||
.Bd -literal
|
||||
tix-iso-bootconfig --disable-network-drivers bootconfig
|
||||
tix-iso-add sortix.iso bootconfig
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr xorriso 1 ,
|
||||
.Xr kernel 7 ,
|
||||
|
|
Loading…
Add table
Reference in a new issue