mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Add tcp syn packet fingerprinting to redbean
This change also fixes bugs in enoprotoopt reporting with setsockopt and getsockopt error returns.
This commit is contained in:
parent
866b21a151
commit
4d25f8c3c9
75 changed files with 1551 additions and 115 deletions
2
Makefile
2
Makefile
|
@ -145,6 +145,7 @@ include tool/args/args.mk
|
|||
include test/tool/args/test.mk
|
||||
include third_party/linenoise/linenoise.mk
|
||||
include third_party/maxmind/maxmind.mk
|
||||
include net/finger/finger.mk
|
||||
include third_party/double-conversion/double-conversion.mk
|
||||
include third_party/lua/lua.mk
|
||||
include third_party/make/make.mk
|
||||
|
@ -202,6 +203,7 @@ include test/libc/release/test.mk
|
|||
include test/libc/test.mk
|
||||
include test/net/http/test.mk
|
||||
include test/net/https/test.mk
|
||||
include test/net/finger/test.mk
|
||||
include test/net/test.mk
|
||||
include test/tool/build/lib/test.mk
|
||||
include test/tool/build/test.mk
|
||||
|
|
|
@ -44,6 +44,8 @@ kTcpOptnames:
|
|||
.e TCP_SYNCNT,"SYNCNT" # int
|
||||
.e TCP_NOTSENT_LOWAT,"NOTSENT_LOWAT" # int
|
||||
.e TCP_WINDOW_CLAMP,"WINDOW_CLAMP" # int
|
||||
.e TCP_SAVE_SYN,"SAVE_SYN" # int
|
||||
.e TCP_SAVED_SYN,"SAVED_SYN" # buffer
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kTcpOptnames,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
* @param optname can be SO_{REUSE{PORT,ADDR},KEEPALIVE,etc.} etc.
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @error ENOPROTOOPT for unknown (level,optname)
|
||||
* @error EINVAL if `out_optlen` is invalid somehow
|
||||
* @error ENOTSOCK if `fd` is valid but not a socket
|
||||
* @error EBADF if `fd` isn't valid
|
||||
* @error EFAULT if optval memory isn't valid
|
||||
* @see libc/sysv/consts.sh for tuning catalogue
|
||||
* @see setsockopt()
|
||||
*/
|
||||
|
@ -39,10 +43,8 @@ int getsockopt(int fd, int level, int optname, void *out_opt_optval,
|
|||
uint32_t *out_optlen) {
|
||||
int rc;
|
||||
|
||||
if (!level || !optname) {
|
||||
rc = enoprotoopt(); /* our sysvconsts definition */
|
||||
} else if (optname == -1) {
|
||||
rc = 0; /* our sysvconsts definition */
|
||||
if (level == -1 || !optname) {
|
||||
rc = enoprotoopt(); /* see libc/sysv/consts.sh */
|
||||
} else if (IsAsan() && (out_opt_optval && out_optlen &&
|
||||
(!__asan_is_valid(out_optlen, sizeof(uint32_t)) ||
|
||||
!__asan_is_valid(out_opt_optval, *out_optlen)))) {
|
||||
|
|
|
@ -49,6 +49,10 @@ static bool setsockopt_polyfill(int *optname) {
|
|||
* @param optname can be SO_{REUSE{PORT,ADDR},KEEPALIVE,etc.} etc.
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @error ENOPROTOOPT for unknown (level,optname)
|
||||
* @error EINVAL if `optlen` is invalid somehow
|
||||
* @error ENOTSOCK if `fd` is valid but not a socket
|
||||
* @error EBADF if `fd` isn't valid
|
||||
* @error EFAULT if optval memory isn't valid
|
||||
* @see libc/sysv/consts.sh for tuning catalogue
|
||||
* @see getsockopt()
|
||||
*/
|
||||
|
@ -56,8 +60,8 @@ int setsockopt(int fd, int level, int optname, const void *optval,
|
|||
uint32_t optlen) {
|
||||
int e, rc;
|
||||
|
||||
if (!optname) {
|
||||
rc = enosys(); /* see libc/sysv/consts.sh */
|
||||
if (level == -1 || !optname) {
|
||||
rc = enoprotoopt(); /* see libc/sysv/consts.sh */
|
||||
} else if ((!optval && optlen) ||
|
||||
(IsAsan() && !__asan_is_valid(optval, optlen))) {
|
||||
rc = efault();
|
||||
|
|
|
@ -649,9 +649,6 @@ syscon epoll EPOLLET 0x80000000 0x80000000 0x80000000 0x80000000 0x80000
|
|||
|
||||
# {set,get}sockopt(fd, level=SOL_SOCKET, X, ...)
|
||||
#
|
||||
# * 0 we define as EINVAL
|
||||
# * -1 we define as no-op
|
||||
#
|
||||
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon so SO_DEBUG 1 1 1 1 1 1 # debugging is enabled; consensus
|
||||
syscon so SO_TYPE 3 0x1008 0x1008 0x1008 0x1008 0x1008 # bsd consensus
|
||||
|
@ -719,30 +716,30 @@ syscon sol SOL_IP 0 0 0 0 0 0 # consensus
|
|||
syscon sol SOL_SOCKET 1 0xffff 0xffff 0xffff 0xffff 0xffff # yes it's actually 0xffff; bsd+nt consensus (todo: what's up with ipproto_icmp overlap)
|
||||
syscon sol SOL_TCP 6 6 6 6 6 6 # consensus
|
||||
syscon sol SOL_UDP 17 17 17 17 17 17 # consensus
|
||||
syscon sol SOL_RAW 255 0 0 0 0 0
|
||||
syscon sol SOL_RAW 255 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_IPV6 41 41 41 41 41 41
|
||||
syscon sol SOL_ICMPV6 58 58 58 58 58 0
|
||||
syscon sol SOL_AAL 265 0 0 0 0 0
|
||||
syscon sol SOL_ALG 279 0 0 0 0 0
|
||||
syscon sol SOL_ATM 264 0 0 0 0 0
|
||||
syscon sol SOL_BLUETOOTH 274 0 0 0 0 0
|
||||
syscon sol SOL_CAIF 278 0 0 0 0 0
|
||||
syscon sol SOL_DCCP 269 0 0 0 0 0
|
||||
syscon sol SOL_DECNET 261 0 0 0 0 0
|
||||
syscon sol SOL_IRDA 266 0 0 0 0 0
|
||||
syscon sol SOL_IUCV 277 0 0 0 0 0
|
||||
syscon sol SOL_KCM 281 0 0 0 0 0
|
||||
syscon sol SOL_LLC 268 0 0 0 0 0
|
||||
syscon sol SOL_NETBEUI 267 0 0 0 0 0
|
||||
syscon sol SOL_NETLINK 270 0 0 0 0 0
|
||||
syscon sol SOL_NFC 280 0 0 0 0 0
|
||||
syscon sol SOL_PACKET 263 0 0 0 0 0
|
||||
syscon sol SOL_PNPIPE 275 0 0 0 0 0
|
||||
syscon sol SOL_PPPOL2TP 273 0 0 0 0 0
|
||||
syscon sol SOL_RDS 276 0 0 0 0 0
|
||||
syscon sol SOL_RXRPC 272 0 0 0 0 0
|
||||
syscon sol SOL_TIPC 271 0 0 0 0 0
|
||||
syscon sol SOL_X25 262 0 0 0 0 0
|
||||
syscon sol SOL_ICMPV6 58 58 58 58 58 -1
|
||||
syscon sol SOL_AAL 265 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_ALG 279 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_ATM 264 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_BLUETOOTH 274 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_CAIF 278 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_DCCP 269 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_DECNET 261 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_IRDA 266 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_IUCV 277 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_KCM 281 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_LLC 268 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_NETBEUI 267 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_NETLINK 270 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_NFC 280 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_PACKET 263 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_PNPIPE 275 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_PPPOL2TP 273 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_RDS 276 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_RXRPC 272 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_TIPC 271 -1 -1 -1 -1 -1
|
||||
syscon sol SOL_X25 262 -1 -1 -1 -1 -1
|
||||
|
||||
syscon alg ALG_SET_KEY 1 0 0 0 0 0
|
||||
syscon alg ALG_SET_IV 2 0 0 0 0 0
|
||||
|
@ -751,12 +748,9 @@ syscon alg ALG_SET_AEAD_ASSOCLEN 4 0 0 0 0 0
|
|||
syscon alg ALG_SET_AEAD_AUTHSIZE 5 0 0 0 0 0
|
||||
syscon alg ALG_SET_DRBG_ENTROPY 6 0 0 0 0 0
|
||||
|
||||
# {set,get}sockopt(fd, level=IPPROTO_TCP, X, ...)
|
||||
# {set,get}sockopt(fd, level=SOL_TCP, X, ...)
|
||||
# » most elite of all tuning groups
|
||||
#
|
||||
# * 0 we define as EINVAL
|
||||
# * -1 we define as no-op
|
||||
#
|
||||
# @see https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
|
||||
# @see https://www.iana.org/assignments/tcp-parameters/tcp-parameters.txt
|
||||
#
|
||||
|
@ -923,33 +917,33 @@ syscon iproto IPPROTO_ICMP 1 1 1 1 1 1 # consensus
|
|||
syscon iproto IPPROTO_TCP 6 6 6 6 6 6 # consensus
|
||||
syscon iproto IPPROTO_UDP 17 17 17 17 17 17 # consensus
|
||||
syscon iproto IPPROTO_RAW 255 255 255 255 255 255 # consensus
|
||||
syscon iproto IPPROTO_HOPOPTS 0 0 0 0 0 0 # consensus
|
||||
syscon iproto IPPROTO_HOPOPTS -1 -1 -1 -1 -1 -1 # consensus
|
||||
syscon iproto IPPROTO_IDP 22 22 22 22 22 22 # consensus
|
||||
syscon iproto IPPROTO_IGMP 2 2 2 2 2 2 # consensus
|
||||
syscon iproto IPPROTO_PUP 12 12 12 12 12 12 # consensus
|
||||
syscon iproto IPPROTO_AH 51 51 51 51 51 0 # unix consensus
|
||||
syscon iproto IPPROTO_DSTOPTS 60 60 60 60 60 0 # unix consensus
|
||||
syscon iproto IPPROTO_EGP 8 8 8 8 8 0 # unix consensus
|
||||
syscon iproto IPPROTO_ENCAP 98 98 98 98 98 0 # unix consensus
|
||||
syscon iproto IPPROTO_ESP 50 50 50 50 50 0 # unix consensus
|
||||
syscon iproto IPPROTO_FRAGMENT 44 44 44 44 44 0 # unix consensus
|
||||
syscon iproto IPPROTO_GRE 47 47 47 47 47 0 # unix consensus
|
||||
syscon iproto IPPROTO_ICMPV6 58 58 58 58 58 0 # unix consensus
|
||||
syscon iproto IPPROTO_IPIP 4 4 4 4 4 0 # unix consensus
|
||||
syscon iproto IPPROTO_IPV6 41 41 41 41 41 0 # unix consensus
|
||||
syscon iproto IPPROTO_NONE 59 59 59 59 59 0 # unix consensus
|
||||
syscon iproto IPPROTO_PIM 103 103 103 103 103 0 # unix consensus
|
||||
syscon iproto IPPROTO_ROUTING 43 43 43 43 43 0 # unix consensus
|
||||
syscon iproto IPPROTO_RSVP 46 46 46 46 46 0 # unix consensus
|
||||
syscon iproto IPPROTO_TP 29 29 29 29 29 0 # unix consensus
|
||||
syscon iproto IPPROTO_MPLS 137 0 137 137 137 0
|
||||
syscon iproto IPPROTO_MTP 92 92 92 0 0 0
|
||||
syscon iproto IPPROTO_SCTP 132 132 132 0 0 0
|
||||
syscon iproto IPPROTO_MH 135 0 135 0 0 0
|
||||
syscon iproto IPPROTO_UDPLITE 136 0 136 0 0 0
|
||||
syscon iproto IPPROTO_BEETPH 94 0 0 0 0 0
|
||||
syscon iproto IPPROTO_COMP 108 0 0 0 0 0
|
||||
syscon iproto IPPROTO_DCCP 33 0 0 0 0 0
|
||||
syscon iproto IPPROTO_AH 51 51 51 51 51 -1 # unix consensus
|
||||
syscon iproto IPPROTO_DSTOPTS 60 60 60 60 60 -1 # unix consensus
|
||||
syscon iproto IPPROTO_EGP 8 8 8 8 8 -1 # unix consensus
|
||||
syscon iproto IPPROTO_ENCAP 98 98 98 98 98 -1 # unix consensus
|
||||
syscon iproto IPPROTO_ESP 50 50 50 50 50 -1 # unix consensus
|
||||
syscon iproto IPPROTO_FRAGMENT 44 44 44 44 44 -1 # unix consensus
|
||||
syscon iproto IPPROTO_GRE 47 47 47 47 47 -1 # unix consensus
|
||||
syscon iproto IPPROTO_ICMPV6 58 58 58 58 58 -1 # unix consensus
|
||||
syscon iproto IPPROTO_IPIP 4 4 4 4 4 -1 # unix consensus
|
||||
syscon iproto IPPROTO_IPV6 41 41 41 41 41 -1 # unix consensus
|
||||
syscon iproto IPPROTO_NONE 59 59 59 59 59 -1 # unix consensus
|
||||
syscon iproto IPPROTO_PIM 103 103 103 103 103 -1 # unix consensus
|
||||
syscon iproto IPPROTO_ROUTING 43 43 43 43 43 -1 # unix consensus
|
||||
syscon iproto IPPROTO_RSVP 46 46 46 46 46 -1 # unix consensus
|
||||
syscon iproto IPPROTO_TP 29 29 29 29 29 -1 # unix consensus
|
||||
syscon iproto IPPROTO_MPLS 137 -1 137 137 137 -1
|
||||
syscon iproto IPPROTO_MTP 92 92 92 -1 -1 -1
|
||||
syscon iproto IPPROTO_SCTP 132 132 132 -1 -1 -1
|
||||
syscon iproto IPPROTO_MH 135 -1 135 -1 -1 -1
|
||||
syscon iproto IPPROTO_UDPLITE 136 -1 136 -1 -1 -1
|
||||
syscon iproto IPPROTO_BEETPH 94 -1 -1 -1 -1 -1
|
||||
syscon iproto IPPROTO_COMP 108 -1 -1 -1 -1 -1
|
||||
syscon iproto IPPROTO_DCCP 33 -1 -1 -1 -1 -1
|
||||
|
||||
syscon sio SIOCADDMULTI 0x8931 0x80206931 0x80206931 0x80206931 0x80206931 0 # bsd consensus
|
||||
syscon sio SIOCATMARK 0x8905 0x40047307 0x40047307 0x40047307 0x40047307 0 # bsd consensus
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_AH,51,51,51,51,51,0
|
||||
.syscon iproto,IPPROTO_AH,51,51,51,51,51,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_BEETPH,94,0,0,0,0,0
|
||||
.syscon iproto,IPPROTO_BEETPH,94,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_COMP,108,0,0,0,0,0
|
||||
.syscon iproto,IPPROTO_COMP,108,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_DCCP,33,0,0,0,0,0
|
||||
.syscon iproto,IPPROTO_DCCP,33,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_DSTOPTS,60,60,60,60,60,0
|
||||
.syscon iproto,IPPROTO_DSTOPTS,60,60,60,60,60,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_EGP,8,8,8,8,8,0
|
||||
.syscon iproto,IPPROTO_EGP,8,8,8,8,8,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_ENCAP,98,98,98,98,98,0
|
||||
.syscon iproto,IPPROTO_ENCAP,98,98,98,98,98,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_ESP,50,50,50,50,50,0
|
||||
.syscon iproto,IPPROTO_ESP,50,50,50,50,50,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_FRAGMENT,44,44,44,44,44,0
|
||||
.syscon iproto,IPPROTO_FRAGMENT,44,44,44,44,44,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_GRE,47,47,47,47,47,0
|
||||
.syscon iproto,IPPROTO_GRE,47,47,47,47,47,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_HOPOPTS,0,0,0,0,0,0
|
||||
.syscon iproto,IPPROTO_HOPOPTS,-1,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_ICMPV6,58,58,58,58,58,0
|
||||
.syscon iproto,IPPROTO_ICMPV6,58,58,58,58,58,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_IPIP,4,4,4,4,4,0
|
||||
.syscon iproto,IPPROTO_IPIP,4,4,4,4,4,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_IPV6,41,41,41,41,41,0
|
||||
.syscon iproto,IPPROTO_IPV6,41,41,41,41,41,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_MH,135,0,135,0,0,0
|
||||
.syscon iproto,IPPROTO_MH,135,-1,135,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_MPLS,137,0,137,137,137,0
|
||||
.syscon iproto,IPPROTO_MPLS,137,-1,137,137,137,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_MTP,92,92,92,0,0,0
|
||||
.syscon iproto,IPPROTO_MTP,92,92,92,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_NONE,59,59,59,59,59,0
|
||||
.syscon iproto,IPPROTO_NONE,59,59,59,59,59,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_PIM,103,103,103,103,103,0
|
||||
.syscon iproto,IPPROTO_PIM,103,103,103,103,103,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_ROUTING,43,43,43,43,43,0
|
||||
.syscon iproto,IPPROTO_ROUTING,43,43,43,43,43,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_RSVP,46,46,46,46,46,0
|
||||
.syscon iproto,IPPROTO_RSVP,46,46,46,46,46,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_SCTP,132,132,132,0,0,0
|
||||
.syscon iproto,IPPROTO_SCTP,132,132,132,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_TP,29,29,29,29,29,0
|
||||
.syscon iproto,IPPROTO_TP,29,29,29,29,29,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon iproto,IPPROTO_UDPLITE,136,0,136,0,0,0
|
||||
.syscon iproto,IPPROTO_UDPLITE,136,-1,136,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_AAL,265,0,0,0,0,0
|
||||
.syscon sol,SOL_AAL,265,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_ALG,279,0,0,0,0,0
|
||||
.syscon sol,SOL_ALG,279,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_ATM,264,0,0,0,0,0
|
||||
.syscon sol,SOL_ATM,264,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_BLUETOOTH,274,0,0,0,0,0
|
||||
.syscon sol,SOL_BLUETOOTH,274,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_CAIF,278,0,0,0,0,0
|
||||
.syscon sol,SOL_CAIF,278,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_DCCP,269,0,0,0,0,0
|
||||
.syscon sol,SOL_DCCP,269,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_DECNET,261,0,0,0,0,0
|
||||
.syscon sol,SOL_DECNET,261,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_ICMPV6,58,58,58,58,58,0
|
||||
.syscon sol,SOL_ICMPV6,58,58,58,58,58,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_IRDA,266,0,0,0,0,0
|
||||
.syscon sol,SOL_IRDA,266,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_IUCV,277,0,0,0,0,0
|
||||
.syscon sol,SOL_IUCV,277,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_KCM,281,0,0,0,0,0
|
||||
.syscon sol,SOL_KCM,281,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_LLC,268,0,0,0,0,0
|
||||
.syscon sol,SOL_LLC,268,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_NETBEUI,267,0,0,0,0,0
|
||||
.syscon sol,SOL_NETBEUI,267,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_NETLINK,270,0,0,0,0,0
|
||||
.syscon sol,SOL_NETLINK,270,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_NFC,280,0,0,0,0,0
|
||||
.syscon sol,SOL_NFC,280,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_PACKET,263,0,0,0,0,0
|
||||
.syscon sol,SOL_PACKET,263,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_PNPIPE,275,0,0,0,0,0
|
||||
.syscon sol,SOL_PNPIPE,275,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_PPPOL2TP,273,0,0,0,0,0
|
||||
.syscon sol,SOL_PPPOL2TP,273,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_RAW,255,0,0,0,0,0
|
||||
.syscon sol,SOL_RAW,255,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_RDS,276,0,0,0,0,0
|
||||
.syscon sol,SOL_RDS,276,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_RXRPC,272,0,0,0,0,0
|
||||
.syscon sol,SOL_RXRPC,272,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_TIPC,271,0,0,0,0,0
|
||||
.syscon sol,SOL_TIPC,271,-1,-1,-1,-1,-1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sol,SOL_X25,262,0,0,0,0,0
|
||||
.syscon sol,SOL_X25,262,-1,-1,-1,-1,-1
|
||||
|
|
133
net/finger/describesyn.c
Normal file
133
net/finger/describesyn.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "net/finger/finger.h"
|
||||
|
||||
/**
|
||||
* Describes IP+TCP SYN packet
|
||||
*
|
||||
* The layout looks as follows:
|
||||
*
|
||||
* TTL:OPTIONS:WSIZE:MSS
|
||||
*
|
||||
* The `TTL`, `WSIZE`, and `MSS` fields are unsigned decimal fields.
|
||||
*
|
||||
* The `OPTIONS` field communicates the ordering of the commonly used
|
||||
* subset of tcp options. The following character mappings are defined.
|
||||
* TCP options not on this list will be ignored.
|
||||
*
|
||||
* - E: End of Option list
|
||||
* - N: No-Operation
|
||||
* - M: Maxmimum Segment Size
|
||||
* - K: Window Scale
|
||||
* - O: SACK Permitted
|
||||
* - A: SACK
|
||||
* - e: Echo (obsolete)
|
||||
* - r: Echo reply (obsolete)
|
||||
* - T: Timestamps
|
||||
*
|
||||
* @param q receives nul-terminated string
|
||||
* @param m is byte capacity of `q`
|
||||
* @param p is syn packet
|
||||
* @param n is byte length of `p`
|
||||
* @return pointer past last written byte in `q` or null if not a syn packet
|
||||
* @see https://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml
|
||||
*/
|
||||
char *DescribeSyn(char *q, size_t m, const char *p, size_t n) {
|
||||
char *e;
|
||||
int i, j, k, r, iplen, tcplen, ttl, wsize, mss;
|
||||
if (n >= 20 + 20 && n >= (iplen = (p[0] & 0x0F) * 4) + 20 &&
|
||||
n >= iplen + (tcplen = ((p[iplen + 12] & 0xF0) >> 4) * 4)) {
|
||||
e = q + m;
|
||||
n = iplen + tcplen;
|
||||
// Time to Live
|
||||
// ttl<=256 Crisco, Solaris 6
|
||||
// ttl<=128 Windows, OpenVMS 8+
|
||||
// ttl<= 64 Mac, Linux, BSD, Solaris 8+, Tru64, HP-UX
|
||||
ttl = p[8] & 255;
|
||||
wsize = READ16BE(p + 14);
|
||||
if (q + 13 <= e) {
|
||||
q = FormatUint32(q, ttl);
|
||||
*q++ = ':';
|
||||
}
|
||||
// TCP Options
|
||||
// We care about the order and presence of leading common options.
|
||||
for (mss = j = 0, i = iplen + 20; i < n; ++j) {
|
||||
k = p[i] & 255;
|
||||
if (k < 9 && q + 1 < e) {
|
||||
*q++ = "ENMKOAerT"[k];
|
||||
}
|
||||
if (k == 2 && i + 4 <= n) {
|
||||
mss = READ16BE(p + 2);
|
||||
}
|
||||
if (k == 1 || // no-operation
|
||||
k == 2 || // maximum segment size
|
||||
k == 3 || // window scale
|
||||
k == 4 || // sack permitted
|
||||
k == 8) { // timestamps
|
||||
if (k == 1) {
|
||||
// no-operation option has no length byte
|
||||
//
|
||||
// ┌───┐
|
||||
// │ 1 │
|
||||
// └───┘
|
||||
//
|
||||
++i;
|
||||
} else if (i + 1 < n) {
|
||||
// a normal tcp option should have
|
||||
//
|
||||
// ┌──┬───┬───┐
|
||||
// │OP│LEN│...│
|
||||
// └──┴───┴───┘
|
||||
//
|
||||
// e.g. sack permitted is encoded as
|
||||
//
|
||||
// ┌───┬───┐
|
||||
// │ 4 │ 2 │
|
||||
// └───┴───┘
|
||||
//
|
||||
// e.g. window scale of `7` would be encoded as
|
||||
//
|
||||
// ┌───┬───┬───┐
|
||||
// │ 3 │ 3 │ 7 │
|
||||
// └───┴───┴───┘
|
||||
//
|
||||
i += p[i + 1] & 255;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (q + (1 + 12) * 2 <= e) {
|
||||
*q++ = ':';
|
||||
q = FormatUint32(q, wsize);
|
||||
*q++ = ':';
|
||||
q = FormatUint32(q, mss);
|
||||
}
|
||||
if (q < e) {
|
||||
*q = 0;
|
||||
}
|
||||
return q;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
13
net/finger/finger.h
Normal file
13
net/finger/finger.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef COSMOPOLITAN_NET_FINGER_FINGER_H_
|
||||
#define COSMOPOLITAN_NET_FINGER_FINGER_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
char *DescribeSyn(char *, size_t, const char *, size_t);
|
||||
const char *GetOsName(int);
|
||||
int GetSynFingerOs(uint32_t);
|
||||
uint32_t FingerSyn(const char *, size_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_NET_FINGER_FINGER_H_ */
|
47
net/finger/finger.mk
Normal file
47
net/finger/finger.mk
Normal file
|
@ -0,0 +1,47 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += NET_FINGER
|
||||
|
||||
NET_FINGER_ARTIFACTS += NET_FINGER_A
|
||||
NET_FINGER = $(NET_FINGER_A_DEPS) $(NET_FINGER_A)
|
||||
NET_FINGER_A = o/$(MODE)/net/finger/finger.a
|
||||
NET_FINGER_A_FILES := $(wildcard net/finger/*)
|
||||
NET_FINGER_A_HDRS = $(filter %.h,$(NET_FINGER_A_FILES))
|
||||
NET_FINGER_A_INCS := $(filter %.inc,$(NET_FINGER_A_FILES))
|
||||
NET_FINGER_A_SRCS_C = $(filter %.c,$(NET_FINGER_A_FILES))
|
||||
NET_FINGER_A_SRCS_S = $(filter %.S,$(NET_FINGER_A_FILES))
|
||||
NET_FINGER_A_SRCS = $(NET_FINGER_A_SRCS_S) $(NET_FINGER_A_SRCS_C)
|
||||
NET_FINGER_A_OBJS_C = $(NET_FINGER_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
NET_FINGER_A_OBJS_S = $(NET_FINGER_A_SRCS_S:%.S=o/$(MODE)/%.o)
|
||||
NET_FINGER_A_OBJS = $(NET_FINGER_A_OBJS_S) $(NET_FINGER_A_OBJS_C)
|
||||
|
||||
NET_FINGER_A_CHECKS = \
|
||||
$(NET_FINGER_A).pkg \
|
||||
$(NET_FINGER_A_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
NET_FINGER_A_DIRECTDEPS = \
|
||||
LIBC_INTRIN \
|
||||
LIBC_NEXGEN32E
|
||||
|
||||
NET_FINGER_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(NET_FINGER_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(NET_FINGER_A): \
|
||||
net/finger/ \
|
||||
$(NET_FINGER_A).pkg \
|
||||
$(NET_FINGER_A_OBJS)
|
||||
|
||||
$(NET_FINGER_A).pkg: \
|
||||
$(NET_FINGER_A_OBJS) \
|
||||
$(foreach x,$(NET_FINGER_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
NET_FINGER_LIBS = $(foreach x,$(NET_FINGER_ARTIFACTS),$($(x)))
|
||||
NET_FINGER_SRCS = $(foreach x,$(NET_FINGER_ARTIFACTS),$($(x)_SRCS))
|
||||
NET_FINGER_HDRS = $(foreach x,$(NET_FINGER_ARTIFACTS),$($(x)_HDRS))
|
||||
NET_FINGER_OBJS = $(foreach x,$(NET_FINGER_ARTIFACTS),$($(x)_OBJS))
|
||||
NET_FINGER_CHECKS = $(foreach x,$(NET_FINGER_ARTIFACTS),$($(x)_CHECKS))
|
||||
|
||||
.PHONY: o/$(MODE)/net/finger
|
||||
o/$(MODE)/net/finger: \
|
||||
$(NET_FINGER_CHECKS)
|
64
net/finger/fingersyn.c
Normal file
64
net/finger/fingersyn.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
|
||||
/**
|
||||
* Fingers IP+TCP SYN packet.
|
||||
*
|
||||
* This returns a hash-like magic number that reflects the SYN packet
|
||||
* structure, e.g. ordering of options, maximum segment size, etc.
|
||||
*/
|
||||
uint32_t FingerSyn(const char *p, size_t n) {
|
||||
uint32_t h = 0;
|
||||
int i, j, k, q, r, iplen, tcplen, ttl;
|
||||
if (n >= 20 + 20 && n >= (iplen = (p[0] & 0x0F) * 4) + 20 &&
|
||||
n >= iplen + (tcplen = ((p[iplen + 12] & 0xF0) >> 4) * 4)) {
|
||||
n = iplen + tcplen;
|
||||
// Time to Live
|
||||
// ttl<=256 Crisco, Solaris 6
|
||||
// ttl<=128 Windows, OpenVMS 8+
|
||||
// ttl<=64 Mac, Linux, BSD, Solaris 8+, Tru64, HP-UX
|
||||
ttl = p[8] & 255;
|
||||
h += bsr(MAX(1, ttl - 1));
|
||||
h *= 0x9e3779b1;
|
||||
// TCP Options
|
||||
// We care about the order and presence of leading common options.
|
||||
for (j = 0, i = iplen + 20; i < n; ++j) {
|
||||
k = p[i] & 255;
|
||||
if (k == 0 || k == 1 || k == 2 || k == 3 || k == 4 || k == 8) {
|
||||
if (k <= 1) {
|
||||
++i;
|
||||
} else if (i + 1 < n) {
|
||||
i += p[i + 1] & 255;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
h += j << 8 | k;
|
||||
h *= 0x9e3779b1;
|
||||
}
|
||||
if (!h) {
|
||||
++h;
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
45
net/finger/getosname.c
Normal file
45
net/finger/getosname.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "net/finger/finger.h"
|
||||
|
||||
const char *GetOsName(int os) {
|
||||
if (os) {
|
||||
switch (bsr(os)) {
|
||||
case 0:
|
||||
return "LINUX";
|
||||
case 1:
|
||||
return "METAL";
|
||||
case 2:
|
||||
return "WINDOWS";
|
||||
case 3:
|
||||
return "XNU";
|
||||
case 4:
|
||||
return "OPENBSD";
|
||||
case 5:
|
||||
return "FREEBSD";
|
||||
case 6:
|
||||
return "NETBSD";
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
40
net/finger/getsynfingeros.c
Normal file
40
net/finger/getsynfingeros.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "net/finger/finger.h"
|
||||
|
||||
/**
|
||||
* Turns result of FingerprintSyn() into operating system.
|
||||
*/
|
||||
int GetSynFingerOs(uint32_t x) {
|
||||
switch (x) {
|
||||
case 0x7e7a6599:
|
||||
return XNU;
|
||||
case 0xbb724187:
|
||||
return LINUX;
|
||||
case 0xb228b212:
|
||||
return WINDOWS;
|
||||
case 0x77c30887:
|
||||
return FREEBSD;
|
||||
case 0xc45d694b:
|
||||
return OPENBSD;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -2,5 +2,6 @@
|
|||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
.PHONY: o/$(MODE)/net
|
||||
o/$(MODE)/net: o/$(MODE)/net/http \
|
||||
o/$(MODE)/net: o/$(MODE)/net/finger \
|
||||
o/$(MODE)/net/http \
|
||||
o/$(MODE)/net/https
|
||||
|
|
|
@ -48,6 +48,10 @@ STATIC_YOINK("libc/testlib/hyperion.txt");
|
|||
|
||||
#define THREADS 8
|
||||
|
||||
__attribute__((__constructor__)) static void init(void) {
|
||||
if (IsOpenbsd()) exit(0); // TODO(jart): flakes :'(
|
||||
}
|
||||
|
||||
void PullSomeZipFilesIntoLinkage(void) {
|
||||
gmtime(0);
|
||||
}
|
||||
|
|
290
test/net/finger/describesyn_test.c
Normal file
290
test/net/finger/describesyn_test.c
Normal file
|
@ -0,0 +1,290 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "net/finger/finger.h"
|
||||
|
||||
#define DESCRIBESYN(s) MyDescribeSyn(s, sizeof(s) - 1)
|
||||
|
||||
char o[128];
|
||||
|
||||
char *MyDescribeSyn(const char *p, size_t n) {
|
||||
char *q;
|
||||
rngset(o, sizeof(o), lemur64, -1);
|
||||
q = DescribeSyn(o, sizeof(o), p, n);
|
||||
CHECK_NOTNULL(q);
|
||||
CHECK_EQ(strlen(o), q - o);
|
||||
return o;
|
||||
}
|
||||
|
||||
TEST(DescribeSyn, badPacket) {
|
||||
ASSERT_EQ(NULL, DescribeSyn(o, sizeof(o), "123", 3));
|
||||
}
|
||||
|
||||
TEST(DescribeSyn, testWindows7) {
|
||||
// version = 4
|
||||
// ihl = 20
|
||||
// dscp = 0
|
||||
// ecn = 0
|
||||
// lengthtotal = 52
|
||||
// identification = 5538
|
||||
// flags = 2
|
||||
// fragmentoffset = 0
|
||||
// ttl = 128
|
||||
// protocol = 6
|
||||
// ipchecksum = 48124
|
||||
// srcip = 127.10.10.150
|
||||
// dstip = 127.10.10.124
|
||||
//
|
||||
// srcport = 50078
|
||||
// dstport = 7000
|
||||
// sequence = 305725139
|
||||
// acknumber = 0
|
||||
// dataoffset = 8
|
||||
// ns = 0
|
||||
// cwr = 0
|
||||
// ece = 0
|
||||
// urg = 0
|
||||
// ack = 0
|
||||
// psh = 0
|
||||
// rst = 0
|
||||
// syn = 1
|
||||
// fin = 0
|
||||
// wsize = 8192
|
||||
// tcpchecksum = 13806
|
||||
// urgpointer = 0
|
||||
//
|
||||
// option 2 4 5 180 (Maximum Segment Size)
|
||||
// option 1 (No-Operation)
|
||||
// option 3 3 2 (Window Scale)
|
||||
// option 1 (No-Operation)
|
||||
// option 1 (No-Operation)
|
||||
// option 4 2 (SACK Permitted)
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x34\x15\xa2\x40\x00\x80\x06\xbb\xfc\x7f\x0a\x0a\x96\
|
||||
\x7f\x0a\x0a\x7c\xc3\x9e\x1b\x58\x12\x38\xfe\xd3\x00\x00\x00\x00\
|
||||
\x80\x02\x20\x00\x35\xee\x00\x00\x02\x04\x05\xb4\x01\x03\x03\x02\
|
||||
\x01\x01\x04\x02";
|
||||
EXPECT_STREQ("128:MNKNNO:2710:52", DESCRIBESYN(s));
|
||||
}
|
||||
|
||||
TEST(DescribeSyn, testWindows10) {
|
||||
// version = 4
|
||||
// ihl = 20
|
||||
// dscp = 0
|
||||
// ecn = 0
|
||||
// lengthtotal = 52
|
||||
// identification = 24981
|
||||
// flags = 2
|
||||
// fragmentoffset = 0
|
||||
// ttl = 128
|
||||
// protocol = 6
|
||||
// ipchecksum = 28818
|
||||
// srcip = 127.10.10.13
|
||||
// dstip = 127.10.10.124
|
||||
//
|
||||
// srcport = 60914
|
||||
// dstport = 7000
|
||||
// sequence = 3953567664
|
||||
// acknumber = 0
|
||||
// dataoffset = 8
|
||||
// ns = 0
|
||||
// cwr = 0
|
||||
// ece = 0
|
||||
// urg = 0
|
||||
// ack = 0
|
||||
// psh = 0
|
||||
// rst = 0
|
||||
// syn = 1
|
||||
// fin = 0
|
||||
// wsize = 64240
|
||||
// tcpchecksum = 44768
|
||||
// urgpointer = 0
|
||||
//
|
||||
// option 2 4 5 180 (Maximum Segment Size)
|
||||
// option 1 (No-Operation)
|
||||
// option 3 3 8 (Window Scale)
|
||||
// option 1 (No-Operation)
|
||||
// option 1 (No-Operation)
|
||||
// option 4 2 (SACK Permitted)
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x34\x61\x95\x40\x00\x80\x06\x70\x92\x7f\x0a\x0a\x0d\
|
||||
\x7f\x0a\x0a\x7c\xed\xf2\x1b\x58\xeb\xa6\xa7\xb0\x00\x00\x00\x00\
|
||||
\x80\x02\xfa\xf0\xae\xe0\x00\x00\x02\x04\x05\xb4\x01\x03\x03\x08\
|
||||
\x01\x01\x04\x02";
|
||||
EXPECT_STREQ("128:MNKNNO:2573:52", DESCRIBESYN(s));
|
||||
}
|
||||
|
||||
TEST(FingerprintSyn, testLinuxAlpine_isLinux) {
|
||||
// version = 4
|
||||
// ihl = 20
|
||||
// dscp = 0
|
||||
// ecn = 0
|
||||
// lengthtotal = 60
|
||||
// identification = 16488
|
||||
// flags = 2
|
||||
// fragmentoffset = 0
|
||||
// ttl = 64
|
||||
// protocol = 6
|
||||
// ipchecksum = 53576
|
||||
// srcip = 127.10.10.124
|
||||
// dstip = 127.10.10.124
|
||||
//
|
||||
// srcport = 60978
|
||||
// dstport = 7000
|
||||
// sequence = 4272530606
|
||||
// acknumber = 0
|
||||
// dataoffset = 10
|
||||
// ns = 0
|
||||
// cwr = 0
|
||||
// ece = 0
|
||||
// urg = 0
|
||||
// ack = 0
|
||||
// psh = 0
|
||||
// rst = 0
|
||||
// syn = 1
|
||||
// fin = 0
|
||||
// wsize = 65495
|
||||
// tcpchecksum = 10554
|
||||
// urgpointer = 0
|
||||
//
|
||||
// option 2 4 255 215 (Maximum Segment Size)
|
||||
// option 4 2 (SACK Permitted)
|
||||
// option 8 10 67 61 171 124 0 0 0 0 (Timestamps)
|
||||
// option 1 (No-Operation)
|
||||
// option 3 3 7 (Window Scale)
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x3c\x40\x68\x40\x00\x40\x06\xd1\x48\x7f\x0a\x0a\x7c\
|
||||
\x7f\x0a\x0a\x7c\xee\x32\x1b\x58\xfe\xa9\xa4\xae\x00\x00\x00\x00\
|
||||
\xa0\x02\xff\xd7\x29\x3a\x00\x00\x02\x04\xff\xd7\x04\x02\x08\x0a\
|
||||
\x43\x3d\xab\x7c\x00\x00\x00\x00\x01\x03\x03\x07";
|
||||
EXPECT_STREQ("64:MOTNK:2684:60", DESCRIBESYN(s));
|
||||
}
|
||||
|
||||
TEST(FingerprintSyn, testLinuxDebian_isLinux) {
|
||||
// version = 4
|
||||
// ihl = 20
|
||||
// dscp = 0
|
||||
// ecn = 0
|
||||
// lengthtotal = 60
|
||||
// identification = 51388
|
||||
// flags = 2
|
||||
// fragmentoffset = 0
|
||||
// ttl = 64
|
||||
// protocol = 6
|
||||
// ipchecksum = 18678
|
||||
// srcip = 127.10.10.122
|
||||
// dstip = 127.10.10.124
|
||||
//
|
||||
// srcport = 57892
|
||||
// dstport = 7000
|
||||
// sequence = 4142527109
|
||||
// acknumber = 0
|
||||
// dataoffset = 10
|
||||
// ns = 0
|
||||
// cwr = 0
|
||||
// ece = 0
|
||||
// urg = 0
|
||||
// ack = 0
|
||||
// psh = 0
|
||||
// rst = 0
|
||||
// syn = 1
|
||||
// fin = 0
|
||||
// wsize = 64240
|
||||
// tcpchecksum = 24492
|
||||
// urgpointer = 0
|
||||
//
|
||||
// option 2 4 5 180 (Maximum Segment Size)
|
||||
// option 4 2 (SACK Permitted)
|
||||
// option 8 10 74 67 147 41 0 0 0 0 (Timestamps)
|
||||
// option 1 (No-Operation)
|
||||
// option 3 3 7 (Window Scale)
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x3c\xc8\xbc\x40\x00\x40\x06\x48\xf6\x7f\x0a\x0a\x7a\
|
||||
\x7f\x0a\x0a\x7c\xe2\x24\x1b\x58\xf6\xe9\xf2\x85\x00\x00\x00\x00\
|
||||
\xa0\x02\xfa\xf0\x5f\xac\x00\x00\x02\x04\x05\xb4\x04\x02\x08\x0a\
|
||||
\x4a\x43\x93\x29\x00\x00\x00\x00\x01\x03\x03\x07";
|
||||
EXPECT_STREQ("64:MOTNK:2682:60", DESCRIBESYN(s));
|
||||
}
|
||||
|
||||
TEST(FingerprintSyn, testLinuxFastOpen_isLinux) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x99\x6f\x97\x40\x00\x40\x06\xa1\xbc\x7f\x0a\x0a\x7c\
|
||||
\x7f\x0a\x0a\x7c\xee\x3a\x1b\x58\xe1\xbd\xd2\x8d\x00\x00\x00\x00\
|
||||
\xd0\x02\xff\xd7\x29\x97\x00\x00\x02\x04\xff\xd7\x04\x02\x08\x0a\
|
||||
\x43\x3f\x21\xf8\x00\x00\x00\x00\x01\x03\x03\x07\x22\x0a\xd4\x75\
|
||||
\x4f\x06\xc0\x97\x25\x6c\x01\x01";
|
||||
EXPECT_STREQ("64:MOTNK:2684:153", DESCRIBESYN(s));
|
||||
}
|
||||
|
||||
TEST(FingerprintSyn, testLinuxGceVm_isLinux) {
|
||||
static char s[] = "\
|
||||
\x45\x20\x00\x3c\x59\x9a\x40\x00\x3b\x06\xb0\xe4\x23\xe2\xfc\xb5\
|
||||
\x7f\x0a\x0a\x7c\xd2\xfe\x1b\x58\xf5\xb2\xf6\xca\x00\x00\x00\x00\
|
||||
\xa0\x02\xff\x28\x16\xe7\x00\x00\x02\x04\x05\x8c\x04\x02\x08\x0a\
|
||||
\xb6\x4d\x6b\xd8\x00\x00\x00\x00\x01\x03\x03\x07";
|
||||
EXPECT_STREQ("59:MOTNK:64693:60", DESCRIBESYN(s));
|
||||
}
|
||||
|
||||
TEST(FingerprintSyn, testOpenbsd) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x40\x7c\x71\x40\x00\x40\x06\x95\x32\x7f\x0a\x0a\x85\
|
||||
\x7f\x0a\x0a\x7c\xa2\x91\x1b\x58\x53\x54\xbc\xc5\x00\x00\x00\x00\
|
||||
\xb0\x02\x40\x00\x70\xf7\x00\x00\x02\x04\x05\xb4\x01\x01\x04\x02\
|
||||
\x01\x03\x03\x06\x01\x01\x08\x0a\xa2\x70\xeb\x7a\x00\x00\x00\x00";
|
||||
EXPECT_STREQ("64:MNNONKNNT:2693:64", DESCRIBESYN(s));
|
||||
}
|
||||
|
||||
TEST(FingerprintSyn, testXnu) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x40\x00\x00\x40\x00\x40\x06\x11\xb1\x7f\x0a\x0a\x78\
|
||||
\x7f\x0a\x0a\x7c\xd3\x63\x1b\x58\xe6\xd5\xf8\x7e\x00\x00\x00\x00\
|
||||
\xb0\x02\xff\xff\x70\x36\x00\x00\x02\x04\x05\xb4\x01\x03\x03\x06\
|
||||
\x01\x01\x08\x0a\x25\x85\xaa\x28\x00\x00\x00\x00\x04\x02\x00\x00";
|
||||
EXPECT_STREQ("64:MNKNNTOE:2680:64", DESCRIBESYN(s));
|
||||
}
|
||||
|
||||
TEST(FingerprintSyn, testFreebsd12) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x3c\x00\x00\x40\x00\x40\x06\x11\xae\x7f\x0a\x0a\x7f\
|
||||
\x7f\x0a\x0a\x7c\xde\x81\x1b\x58\x23\x39\xfc\x6b\x00\x00\x00\x00\
|
||||
\xa0\x02\xff\xff\x8c\x8c\x00\x00\x02\x04\x05\xb4\x01\x03\x03\x06\
|
||||
\x04\x02\x08\x0a\x1f\xa1\x59\x46\x00\x00\x00\x00";
|
||||
EXPECT_STREQ("64:MNKOT:2687:60", DESCRIBESYN(s));
|
||||
}
|
||||
|
||||
TEST(FingerprintSyn, testRedbeanGceVm_isFreebsd) {
|
||||
static char s[] = "\
|
||||
\x45\x20\x00\x3c\x00\x00\x40\x00\x3b\x06\x92\xe4\x23\xee\x74\x44\
|
||||
\x7f\x0a\x0a\x7c\x5a\x6e\x1b\x58\x0a\x15\xba\x1a\x00\x00\x00\x00\
|
||||
\xa0\x02\xff\xff\xe4\x60\x00\x00\x02\x04\x05\x8c\x01\x03\x03\x06\
|
||||
\x04\x02\x08\x0a\xc9\x06\xb4\x13\x00\x00\x00\x00";
|
||||
EXPECT_STREQ("59:MNKOT:29764:60", DESCRIBESYN(s));
|
||||
}
|
||||
|
||||
TEST(FingerprintSyn, testNetbsd_isFreebsdSadly) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x3c\x00\x00\x40\x00\x40\x06\x11\x98\x7f\x0a\x0a\x95\
|
||||
\x7f\x0a\x0a\x7c\xfc\x18\x1b\x58\x8e\xb8\x1b\xfe\x00\x00\x00\x00\
|
||||
\xa0\x02\x80\x00\xdc\xb6\x00\x00\x02\x04\x05\xb4\x01\x03\x03\x03\
|
||||
\x04\x02\x08\x0a\x00\x00\x00\x01\x00\x00\x00\x00";
|
||||
EXPECT_STREQ("64:MNKOT:2709:60", DESCRIBESYN(s));
|
||||
}
|
122
test/net/finger/fingersyn_test.c
Normal file
122
test/net/finger/fingersyn_test.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "net/finger/finger.h"
|
||||
|
||||
TEST(FingerSyn, testWindows7_isWindows) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x34\x15\xa2\x40\x00\x80\x06\xbb\xfc\x7f\x0a\x0a\x96\
|
||||
\x7f\x0a\x0a\x7c\xc3\x9e\x1b\x58\x12\x38\xfe\xd3\x00\x00\x00\x00\
|
||||
\x80\x02\x20\x00\x35\xee\x00\x00\x02\x04\x05\xb4\x01\x03\x03\x02\
|
||||
\x01\x01\x04\x02";
|
||||
EXPECT_EQ(WINDOWS, GetSynFingerOs(FingerSyn(s, sizeof(s) - 1)));
|
||||
}
|
||||
|
||||
TEST(FingerSyn, testWindows10_isWindows) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x34\x61\x95\x40\x00\x80\x06\x70\x92\x7f\x0a\x0a\x0d\
|
||||
\x7f\x0a\x0a\x7c\xed\xf2\x1b\x58\xeb\xa6\xa7\xb0\x00\x00\x00\x00\
|
||||
\x80\x02\xfa\xf0\xae\xe0\x00\x00\x02\x04\x05\xb4\x01\x03\x03\x08\
|
||||
\x01\x01\x04\x02";
|
||||
EXPECT_EQ(WINDOWS, GetSynFingerOs(FingerSyn(s, sizeof(s) - 1)));
|
||||
}
|
||||
|
||||
TEST(FingerSyn, testLinuxAlpine_isLinux) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x3c\x40\x68\x40\x00\x40\x06\xd1\x48\x7f\x0a\x0a\x7c\
|
||||
\x7f\x0a\x0a\x7c\xee\x32\x1b\x58\xfe\xa9\xa4\xae\x00\x00\x00\x00\
|
||||
\xa0\x02\xff\xd7\x29\x3a\x00\x00\x02\x04\xff\xd7\x04\x02\x08\x0a\
|
||||
\x43\x3d\xab\x7c\x00\x00\x00\x00\x01\x03\x03\x07";
|
||||
EXPECT_EQ(LINUX, GetSynFingerOs(FingerSyn(s, sizeof(s) - 1)));
|
||||
}
|
||||
|
||||
TEST(FingerSyn, testLinuxDebian_isLinux) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x3c\xc8\xbc\x40\x00\x40\x06\x48\xf6\x7f\x0a\x0a\x7a\
|
||||
\x7f\x0a\x0a\x7c\xe2\x24\x1b\x58\xf6\xe9\xf2\x85\x00\x00\x00\x00\
|
||||
\xa0\x02\xfa\xf0\x5f\xac\x00\x00\x02\x04\x05\xb4\x04\x02\x08\x0a\
|
||||
\x4a\x43\x93\x29\x00\x00\x00\x00\x01\x03\x03\x07";
|
||||
EXPECT_EQ(LINUX, GetSynFingerOs(FingerSyn(s, sizeof(s) - 1)));
|
||||
}
|
||||
|
||||
TEST(FingerSyn, testLinuxFastOpen_isLinux) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x99\x6f\x97\x40\x00\x40\x06\xa1\xbc\x7f\x00\x00\x7c\
|
||||
\x7f\x00\x00\x7c\xee\x3a\x1b\x58\xe1\xbd\xd2\x8d\x00\x00\x00\x00\
|
||||
\xd0\x02\xff\xd7\x29\x97\x00\x00\x02\x04\xff\xd7\x04\x02\x08\x0a\
|
||||
\x43\x3f\x21\xf8\x00\x00\x00\x00\x01\x03\x03\x07\x22\x0a\xd4\x75\
|
||||
\x4f\x06\xc0\x97\x25\x6c\x01\x01";
|
||||
EXPECT_EQ(LINUX, GetSynFingerOs(FingerSyn(s, sizeof(s) - 1)));
|
||||
}
|
||||
|
||||
TEST(FingerSyn, testLinuxGceVm_isLinux) {
|
||||
static char s[] = "\
|
||||
\x45\x20\x00\x3c\x59\x9a\x40\x00\x3b\x06\xb0\xe4\x23\xe2\xfc\xb5\
|
||||
\x7f\x00\x00\x7c\xd2\xfe\x1b\x58\xf5\xb2\xf6\xca\x00\x00\x00\x00\
|
||||
\xa0\x02\xff\x28\x16\xe7\x00\x00\x02\x04\x05\x8c\x04\x02\x08\x0a\
|
||||
\xb6\x4d\x6b\xd8\x00\x00\x00\x00\x01\x03\x03\x07";
|
||||
EXPECT_EQ(LINUX, GetSynFingerOs(FingerSyn(s, sizeof(s) - 1)));
|
||||
}
|
||||
|
||||
TEST(FingerSyn, testOpenbsd) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x40\x7c\x71\x40\x00\x40\x06\x95\x32\x7f\x00\x00\x85\
|
||||
\x7f\x00\x00\x7c\xa2\x91\x1b\x58\x53\x54\xbc\xc5\x00\x00\x00\x00\
|
||||
\xb0\x02\x40\x00\x70\xf7\x00\x00\x02\x04\x05\xb4\x01\x01\x04\x02\
|
||||
\x01\x03\x03\x06\x01\x01\x08\x0a\xa2\x70\xeb\x7a\x00\x00\x00\x00";
|
||||
EXPECT_EQ(OPENBSD, GetSynFingerOs(FingerSyn(s, sizeof(s) - 1)));
|
||||
}
|
||||
|
||||
TEST(FingerSyn, testXnu) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x40\x00\x00\x40\x00\x40\x06\x11\xb1\x7f\x00\x00\x78\
|
||||
\x7f\x00\x00\x7c\xd3\x63\x1b\x58\xe6\xd5\xf8\x7e\x00\x00\x00\x00\
|
||||
\xb0\x02\xff\xff\x70\x36\x00\x00\x02\x04\x05\xb4\x01\x03\x03\x06\
|
||||
\x01\x01\x08\x0a\x25\x85\xaa\x28\x00\x00\x00\x00\x04\x02\x00\x00";
|
||||
EXPECT_EQ(XNU, GetSynFingerOs(FingerSyn(s, sizeof(s) - 1)));
|
||||
}
|
||||
|
||||
TEST(FingerSyn, testFreebsd12) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x3c\x00\x00\x40\x00\x40\x06\x11\xae\x7f\x00\x00\x7f\
|
||||
\x7f\x00\x00\x7c\xde\x81\x1b\x58\x23\x39\xfc\x6b\x00\x00\x00\x00\
|
||||
\xa0\x02\xff\xff\x8c\x8c\x00\x00\x02\x04\x05\xb4\x01\x03\x03\x06\
|
||||
\x04\x02\x08\x0a\x1f\xa1\x59\x46\x00\x00\x00\x00";
|
||||
EXPECT_EQ(FREEBSD, GetSynFingerOs(FingerSyn(s, sizeof(s) - 1)));
|
||||
}
|
||||
|
||||
TEST(FingerSyn, testRedbeanGceVm_isFreebsd) {
|
||||
static char s[] = "\
|
||||
\x45\x20\x00\x3c\x00\x00\x40\x00\x3b\x06\x92\xe4\x23\xee\x74\x44\
|
||||
\x7f\x00\x00\x7c\x5a\x6e\x1b\x58\x0a\x15\xba\x1a\x00\x00\x00\x00\
|
||||
\xa0\x02\xff\xff\xe4\x60\x00\x00\x02\x04\x05\x8c\x01\x03\x03\x06\
|
||||
\x04\x02\x08\x0a\xc9\x06\xb4\x13\x00\x00\x00\x00";
|
||||
EXPECT_EQ(FREEBSD, GetSynFingerOs(FingerSyn(s, sizeof(s) - 1)));
|
||||
}
|
||||
|
||||
TEST(FingerSyn, testNetbsd_isFreebsdSadly) {
|
||||
static char s[] = "\
|
||||
\x45\x00\x00\x3c\x00\x00\x40\x00\x40\x06\x11\x98\x7f\x00\x00\x95\
|
||||
\x7f\x00\x00\x7c\xfc\x18\x1b\x58\x8e\xb8\x1b\xfe\x00\x00\x00\x00\
|
||||
\xa0\x02\x80\x00\xdc\xb6\x00\x00\x02\x04\x05\xb4\x01\x03\x03\x03\
|
||||
\x04\x02\x08\x0a\x00\x00\x00\x01\x00\x00\x00\x00";
|
||||
EXPECT_EQ(FREEBSD, GetSynFingerOs(FingerSyn(s, sizeof(s) - 1)));
|
||||
}
|
46
test/net/finger/test.mk
Normal file
46
test/net/finger/test.mk
Normal file
|
@ -0,0 +1,46 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += TEST_NET_FINGER
|
||||
|
||||
TEST_NET_FINGER_SRCS := $(wildcard test/net/finger/*.c)
|
||||
TEST_NET_FINGER_SRCS_TEST = $(filter %_test.c,$(TEST_NET_FINGER_SRCS))
|
||||
TEST_NET_FINGER_BINS = $(TEST_NET_FINGER_COMS) $(TEST_NET_FINGER_COMS:%=%.dbg)
|
||||
|
||||
TEST_NET_FINGER_OBJS = \
|
||||
$(TEST_NET_FINGER_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_NET_FINGER_COMS = \
|
||||
$(TEST_NET_FINGER_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_NET_FINGER_TESTS = \
|
||||
$(TEST_NET_FINGER_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
||||
|
||||
TEST_NET_FINGER_CHECKS = \
|
||||
$(TEST_NET_FINGER_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
||||
|
||||
TEST_NET_FINGER_DIRECTDEPS = \
|
||||
NET_FINGER \
|
||||
LIBC_LOG \
|
||||
LIBC_TESTLIB \
|
||||
THIRD_PARTY_MBEDTLS
|
||||
|
||||
TEST_NET_FINGER_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TEST_NET_FINGER_DIRECTDEPS),$($(x))))
|
||||
|
||||
o/$(MODE)/test/net/finger/finger.pkg: \
|
||||
$(TEST_NET_FINGER_OBJS) \
|
||||
$(foreach x,$(TEST_NET_FINGER_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/test/net/finger/%.com.dbg: \
|
||||
$(TEST_NET_FINGER_DEPS) \
|
||||
o/$(MODE)/test/net/finger/%.o \
|
||||
$(LIBC_TESTMAIN) \
|
||||
$(CRT) \
|
||||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
||||
.PHONY: o/$(MODE)/test/net/finger
|
||||
o/$(MODE)/test/net/finger: \
|
||||
$(TEST_NET_FINGER_BINS) \
|
||||
$(TEST_NET_FINGER_CHECKS)
|
|
@ -2,5 +2,6 @@
|
|||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
.PHONY: o/$(MODE)/test/net
|
||||
o/$(MODE)/test/net: o/$(MODE)/test/net/http \
|
||||
o/$(MODE)/test/net: o/$(MODE)/test/net/finger \
|
||||
o/$(MODE)/test/net/http \
|
||||
o/$(MODE)/test/net/https
|
||||
|
|
29
third_party/lua/lunix.c
vendored
29
third_party/lua/lunix.c
vendored
|
@ -1085,6 +1085,7 @@ static bool IsSockoptBool(int l, int x) {
|
|||
return x == TCP_NODELAY || //
|
||||
x == TCP_CORK || //
|
||||
x == TCP_QUICKACK || //
|
||||
x == TCP_SAVE_SYN || //
|
||||
x == TCP_FASTOPEN_CONNECT || //
|
||||
x == TCP_DEFER_ACCEPT; //
|
||||
} else if (l = SOL_IP) {
|
||||
|
@ -1136,6 +1137,11 @@ static int LuaUnixSetsockopt(lua_State *L) {
|
|||
fd = luaL_checkinteger(L, 1);
|
||||
level = luaL_checkinteger(L, 2);
|
||||
optname = luaL_checkinteger(L, 3);
|
||||
if (level == -1 || optname == 0) {
|
||||
NoProtocolOption:
|
||||
enoprotoopt();
|
||||
return SysretErrno(L, "setsockopt", olderr);
|
||||
}
|
||||
if (IsSockoptBool(level, optname)) {
|
||||
// unix.setsockopt(fd:int, level:int, optname:int, value:bool)
|
||||
// ├─→ true
|
||||
|
@ -1167,14 +1173,14 @@ static int LuaUnixSetsockopt(lua_State *L) {
|
|||
optval = &l;
|
||||
optsize = sizeof(l);
|
||||
} else {
|
||||
einval();
|
||||
return SysretErrno(L, "setsockopt", olderr);
|
||||
goto NoProtocolOption;
|
||||
}
|
||||
return SysretBool(L, "setsockopt", olderr,
|
||||
setsockopt(fd, level, optname, optval, optsize));
|
||||
}
|
||||
|
||||
static int LuaUnixGetsockopt(lua_State *L) {
|
||||
char *p;
|
||||
uint32_t size;
|
||||
struct linger l;
|
||||
struct timeval tv;
|
||||
|
@ -1182,6 +1188,11 @@ static int LuaUnixGetsockopt(lua_State *L) {
|
|||
fd = luaL_checkinteger(L, 1);
|
||||
level = luaL_checkinteger(L, 2);
|
||||
optname = luaL_checkinteger(L, 3);
|
||||
if (level == -1 || optname == 0) {
|
||||
NoProtocolOption:
|
||||
enoprotoopt();
|
||||
return SysretErrno(L, "setsockopt", olderr);
|
||||
}
|
||||
if (IsSockoptBool(level, optname) || IsSockoptInt(level, optname)) {
|
||||
// unix.getsockopt(fd:int, level:int, optname:int)
|
||||
// ├─→ value:int
|
||||
|
@ -1214,8 +1225,20 @@ static int LuaUnixGetsockopt(lua_State *L) {
|
|||
lua_pushboolean(L, !!l.l_onoff);
|
||||
return 1;
|
||||
}
|
||||
} else if (level == SOL_TCP && optname == TCP_SAVED_SYN) {
|
||||
// unix.getsockopt(fd:int, unix.SOL_TCP, unix.SO_SAVED_SYN)
|
||||
// ├─→ syn_packet_bytes:str
|
||||
// └─→ nil, unix.Errno
|
||||
if ((p = malloc((size = 1500)))) {
|
||||
if (getsockopt(fd, level, optname, p, &size) != -1) {
|
||||
lua_pushlstring(L, p, size);
|
||||
free(p);
|
||||
return 1;
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
} else {
|
||||
einval();
|
||||
goto NoProtocolOption;
|
||||
}
|
||||
return SysretErrno(L, "getsockopt", olderr);
|
||||
}
|
||||
|
|
|
@ -20,8 +20,20 @@ db:exec[[
|
|||
INSERT INTO test (content) VALUES ('Hello Sqlite3');
|
||||
]]
|
||||
|
||||
function OnServerListen(fd, ip, port)
|
||||
unix.setsockopt(fd, unix.SOL_TCP, unix.TCP_SAVE_SYN, true)
|
||||
return false
|
||||
end
|
||||
|
||||
function OnClientConnection(ip, port, serverip, serverport)
|
||||
syn, synerr = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SAVED_SYN)
|
||||
end
|
||||
|
||||
-- this intercepts all requests if it's defined
|
||||
function OnHttpRequest()
|
||||
Log(kLogInfo, "client is running %s and reports %s" % {
|
||||
finger.GetSynFingerOs(finger.FingerSyn(syn)),
|
||||
GetHeader('User-Agent')})
|
||||
if HasParam('magic') then
|
||||
Write('<p>\r\n')
|
||||
Write('OnHttpRequest() has intercepted your request<br>\r\n')
|
||||
|
|
65
tool/net/demo/finger.lua
Normal file
65
tool/net/demo/finger.lua
Normal file
|
@ -0,0 +1,65 @@
|
|||
-- fingerprinting example
|
||||
|
||||
Write[[<!doctype html>
|
||||
|
||||
<title>redbean binary trees</title>
|
||||
|
||||
<style>
|
||||
body { padding: 1em; }
|
||||
h1 a { color: inherit; text-decoration: none; }
|
||||
h1 img { border: none; vertical-align: middle; }
|
||||
input { margin: 1em; padding: .5em; }
|
||||
p { word-break: break-word; max-width: 650px; }
|
||||
dt { font-family: monospace; }
|
||||
dd { margin-top: 1em; margin-bottom: 1em; }
|
||||
.hdr { text-indent: -1em; padding-left: 1em; }
|
||||
</style>
|
||||
|
||||
<h1>
|
||||
<a href="/"><img src="/redbean.png"></a>
|
||||
<a href="finger.lua">redbean finger demo</a>
|
||||
</h1>
|
||||
|
||||
]]
|
||||
|
||||
Write[[
|
||||
<h2>Your TCP SYN Packet</h2>
|
||||
]]
|
||||
-- See .init.lua hooks which set SYN and SYNERR globals.
|
||||
if syn then
|
||||
if syn ~= '' then
|
||||
Write('<dl>\r\n')
|
||||
Write('<dt>syn = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SAVED_SYN)\r\n')
|
||||
Write('<dd>')
|
||||
Write(EscapeHtml(EncodeLua(syn)))
|
||||
Write('\r\n')
|
||||
Write('<dt>finger.FingerSyn(syn)\r\n')
|
||||
Write('<dd>')
|
||||
Write(EscapeHtml(EncodeLua(finger.FingerSyn(syn))))
|
||||
Write('\r\n')
|
||||
Write('<dt>finger.DescribeSyn(syn)\r\n')
|
||||
Write('<dd>')
|
||||
Write(EscapeHtml(EncodeLua(finger.DescribeSyn(syn))))
|
||||
Write('\r\n')
|
||||
Write('<dt>finger.GetSynFingerOs(finger.FingerSyn(syn))\r\n')
|
||||
Write('<dd>')
|
||||
Write(EscapeHtml(EncodeLua(finger.GetSynFingerOs(finger.FingerSyn(syn)))))
|
||||
Write('\r\n')
|
||||
Write('</dl>\r\n')
|
||||
else
|
||||
Write([[
|
||||
<p>
|
||||
your operating system returned an empty string as the syn
|
||||
packet! did you remember to use setsockopt(TCP_SAVE_SYN)?
|
||||
did you call getsockopt(TCP_SAVED_SYN) more than once?
|
||||
</p>
|
||||
]])
|
||||
end
|
||||
else
|
||||
Write([[
|
||||
<p>
|
||||
your operating system most likely doesn't support TCP_SAVED_SYN
|
||||
because getsockopt() returned %s.
|
||||
</p>
|
||||
]] % {EscapeHtml(tostring(synerr))})
|
||||
end
|
|
@ -1974,6 +1974,100 @@ MAXMIND MODULE
|
|||
For further details, please see maxmind.lua in redbean-demo.com.
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
FINGER MODULE
|
||||
|
||||
This is an experimental module that, like the maxmind module, gives
|
||||
you insight into what kind of device is connecting to your redbean.
|
||||
This module can help you protect your redbean because it provides
|
||||
tools for identifying clients that misrepresent themselves. For
|
||||
example the User-Agent header might report itself as a Windows
|
||||
computer when the SYN packet says it's a Linux computer.
|
||||
|
||||
function OnServerListen(fd, ip, port)
|
||||
unix.setsockopt(fd, unix.SOL_TCP, unix.TCP_SAVE_SYN, true)
|
||||
return false
|
||||
end
|
||||
|
||||
function OnClientConnection(ip, port, serverip, serverport)
|
||||
fd = GetClientFd()
|
||||
syn = unix.getsockopt(fd, unix.SOL_TCP, unix.TCP_SAVED_SYN)
|
||||
end
|
||||
|
||||
function OnHttpRequest()
|
||||
Log(kLogInfo, "client is running %s and reports %s" % {
|
||||
finger.GetSynFingerOs(finger.FingerSyn(syn)),
|
||||
GetHeader('User-Agent')})
|
||||
Route()
|
||||
end
|
||||
|
||||
The following functions are provided.
|
||||
|
||||
finger.FingerSyn(syn_packet_bytes:str)
|
||||
├─→ synfinger:uint32
|
||||
└─→ nil, error:str
|
||||
|
||||
Fingerprints IP+TCP SYN packet.
|
||||
|
||||
This returns a hash-like magic number that reflects the SYN packet
|
||||
structure, e.g. ordering of options, maximum segment size, etc. We
|
||||
make no guarantees this hashing algorithm won't change as we learn
|
||||
more about the optimal way to fingerprint, so be sure to save your
|
||||
syn packets too if you're using this feature, in case they need to
|
||||
be rehashed in the future.
|
||||
|
||||
This function is nil/error propagating.
|
||||
|
||||
finger.GetSynFingerOs(synfinger:uint32)
|
||||
├─→ osname:str
|
||||
└─→ nil, error:str
|
||||
|
||||
Fingerprints IP+TCP SYN packet.
|
||||
|
||||
If `synfinger` is a known hard-coded magic number, then one of the
|
||||
following strings may be returned:
|
||||
|
||||
- `"LINUX"`
|
||||
- `"WINDOWS"`
|
||||
- `"XNU"`
|
||||
- `"NETBSD"`
|
||||
- `"FREEBSD"`
|
||||
- `"OPENBSD"`
|
||||
|
||||
If this function returns nil, then one thing you can do to help is
|
||||
file an issue and share with us your SYN packet specimens. The way
|
||||
we prefer to receive them is in EncodeLua(syn_packet_bytes) format
|
||||
along with details on the operating system which you must know.
|
||||
|
||||
finger.DescribeSyn(syn_packet_bytes:str)
|
||||
├─→ description:str
|
||||
└─→ nil, error:str
|
||||
|
||||
Describes IP+TCP SYN packet.
|
||||
|
||||
The layout looks as follows:
|
||||
|
||||
TTL:OPTIONS:WSIZE:MSS
|
||||
|
||||
The `TTL`, `WSIZE`, and `MSS` fields are unsigned decimal fields.
|
||||
|
||||
The `OPTIONS` field communicates the ordering of the commonly used
|
||||
subset of tcp options. The following character mappings are defined.
|
||||
TCP options not on this list will be ignored.
|
||||
|
||||
- E: End of Option list
|
||||
- N: No-Operation
|
||||
- M: Maxmimum Segment Size
|
||||
- K: Window Scale
|
||||
- O: SACK Permitted
|
||||
- A: SACK
|
||||
- e: Echo (obsolete)
|
||||
- r: Echo reply (obsolete)
|
||||
- T: Timestamps
|
||||
|
||||
This function is nil/error propagating.
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
ARGON2 MODULE
|
||||
|
||||
|
@ -3071,6 +3165,17 @@ UNIX MODULE
|
|||
`level` and `optname` may be one of the following pairs. The ellipses
|
||||
type signature above changes depending on which options are used.
|
||||
|
||||
`optname` is the option feature magic number. The constants for
|
||||
these will be set to `0` if the option isn't supported on the host
|
||||
platform.
|
||||
|
||||
Raises `ENOPROTOOPT` if your `level` / `optname` combination isn't
|
||||
valid, recognized, or supported on the host platform.
|
||||
|
||||
Raises `ENOTSOCK` if `fd` is valid but isn't a socket.
|
||||
|
||||
Raises `EBADF` if `fd` isn't valid.
|
||||
|
||||
unix.getsockopt(fd:int, level:int, optname:int)
|
||||
├─→ value:int
|
||||
└─→ nil, unix.Errno
|
||||
|
@ -3145,9 +3250,19 @@ UNIX MODULE
|
|||
close(). Sometimes it's desirable to have extra assurance on errors
|
||||
happened, even if it comes at the cost of performance.
|
||||
|
||||
Returns `EINVAL` if settings other than the above are used.
|
||||
unix.setsockopt(serverfd:int, unix.SOL_TCP, unix.TCP_SAVE_SYN, enabled:int)
|
||||
├─→ true
|
||||
└─→ nil, unix.Errno
|
||||
unix.getsockopt(clientfd:int, unix.SOL_TCP, unix.TCP_SAVED_SYN)
|
||||
├─→ syn_packet_bytes:str
|
||||
└─→ nil, unix.Errno
|
||||
|
||||
Returns `ENOSYS` if setting isn't supported by the host OS.
|
||||
This `TCP_SAVED_SYN` option may be used to retrieve the bytes of the
|
||||
TCP SYN packet that the client sent when the connection for `fd` was
|
||||
opened. In order for this to work, `TCP_SAVE_SYN` must have been set
|
||||
earlier on the listening socket. This is Linux-only. You can use the
|
||||
`OnServerListen` hook to enable SYN saving in your Redbean. When the
|
||||
`TCP_SAVE_SYN` option isn't used, this may return empty string.
|
||||
|
||||
unix.poll({[fd:int]=events:int, ...}[, timeoutms:int])
|
||||
├─→ {[fd:int]=revents:int, ...}
|
||||
|
|
98
tool/net/lfinger.c
Normal file
98
tool/net/lfinger.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/finger/finger.h"
|
||||
#include "third_party/lua/lauxlib.h"
|
||||
|
||||
// finger.DescribeSyn(syn_packet_bytes:str)
|
||||
// ├─→ description:str
|
||||
// └─→ nil, error:str
|
||||
static int LuaDescribeSyn(lua_State *L) {
|
||||
char *q, *r;
|
||||
size_t n, m;
|
||||
const char *p;
|
||||
luaL_Buffer b;
|
||||
if (!lua_isnoneornil(L, 1)) {
|
||||
p = luaL_checklstring(L, 1, &n);
|
||||
m = 128;
|
||||
q = luaL_buffinitsize(L, &b, m);
|
||||
if ((r = DescribeSyn(q, m, p, n))) {
|
||||
luaL_pushresultsize(&b, r - q);
|
||||
return 1;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "bad syn packet");
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
return lua_gettop(L);
|
||||
}
|
||||
}
|
||||
|
||||
// finger.FingerSyn(syn_packet_bytes:str)
|
||||
// ├─→ synfinger:uint32
|
||||
// └─→ nil, error:str
|
||||
static int LuaFingerSyn(lua_State *L) {
|
||||
size_t n;
|
||||
uint32_t x;
|
||||
const char *p;
|
||||
if (!lua_isnoneornil(L, 1)) {
|
||||
p = luaL_checklstring(L, 1, &n);
|
||||
if ((x = FingerSyn(p, n))) {
|
||||
lua_pushinteger(L, x);
|
||||
return 1;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "bad syn packet");
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
return lua_gettop(L);
|
||||
}
|
||||
}
|
||||
|
||||
// finger.GetSynFingerOs(synfinger:uint32)
|
||||
// ├─→ osname:str
|
||||
// └─→ nil, error:str
|
||||
static int LuaGetSynFingerOs(lua_State *L) {
|
||||
int os;
|
||||
if (!lua_isnoneornil(L, 1)) {
|
||||
if ((os = GetSynFingerOs(luaL_checkinteger(L, 1)))) {
|
||||
lua_pushstring(L, GetOsName(os));
|
||||
return 1;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "unknown syn os fingerprint");
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
return lua_gettop(L);
|
||||
}
|
||||
}
|
||||
|
||||
static const luaL_Reg kLuaFinger[] = {
|
||||
{"DescribeSyn", LuaDescribeSyn}, //
|
||||
{"FingerSyn", LuaFingerSyn}, //
|
||||
{"GetSynFingerOs", LuaGetSynFingerOs}, //
|
||||
{0}, //
|
||||
};
|
||||
|
||||
int LuaFinger(lua_State *L) {
|
||||
luaL_newlib(L, kLuaFinger);
|
||||
return 1;
|
||||
}
|
11
tool/net/lfinger.h
Normal file
11
tool/net/lfinger.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_NET_LFINGER_H_
|
||||
#define COSMOPOLITAN_TOOL_NET_LFINGER_H_
|
||||
#include "third_party/lua/lauxlib.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int LuaFinger(lua_State *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_NET_LFINGER_H_ */
|
|
@ -54,6 +54,7 @@ TOOL_NET_DIRECTDEPS = \
|
|||
LIBC_UNICODE \
|
||||
LIBC_X \
|
||||
LIBC_ZIPOS \
|
||||
NET_FINGER \
|
||||
NET_HTTP \
|
||||
NET_HTTPS \
|
||||
THIRD_PARTY_ARGON2 \
|
||||
|
@ -95,6 +96,7 @@ o/$(MODE)/tool/net/redbean.com.dbg: \
|
|||
$(TOOL_NET_DEPS) \
|
||||
o/$(MODE)/tool/net/redbean.o \
|
||||
o/$(MODE)/tool/net/lfuncs.o \
|
||||
o/$(MODE)/tool/net/lfinger.o \
|
||||
o/$(MODE)/tool/net/lre.o \
|
||||
o/$(MODE)/tool/net/ljson.o \
|
||||
o/$(MODE)/tool/net/lmaxmind.o \
|
||||
|
@ -178,6 +180,7 @@ o/$(MODE)/tool/net/demo/unix-dir.lua.zip.o \
|
|||
o/$(MODE)/tool/net/demo/unix-info.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/unix-finger.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/fetch.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/finger.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/call-lua-module.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/store-asset.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/maxmind.lua.zip.o \
|
||||
|
@ -214,6 +217,7 @@ o/$(MODE)/tool/net/redbean-demo.com.dbg: \
|
|||
$(TOOL_NET_DEPS) \
|
||||
o/$(MODE)/tool/net/redbean.o \
|
||||
o/$(MODE)/tool/net/lfuncs.o \
|
||||
o/$(MODE)/tool/net/lfinger.o \
|
||||
o/$(MODE)/tool/net/lre.o \
|
||||
o/$(MODE)/tool/net/ljson.o \
|
||||
o/$(MODE)/tool/net/lmaxmind.o \
|
||||
|
@ -229,6 +233,7 @@ o/$(MODE)/tool/net/redbean-demo.com.dbg: \
|
|||
o/$(MODE)/tool/net/demo/unix-info.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/unix-finger.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/fetch.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/finger.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/store-asset.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/call-lua-module.lua.zip.o \
|
||||
o/$(MODE)/tool/net/demo/redbean.lua.zip.o \
|
||||
|
@ -331,6 +336,7 @@ o/$(MODE)/tool/net/redbean-unsecure.com.dbg: \
|
|||
$(TOOL_NET_DEPS) \
|
||||
o/$(MODE)/tool/net/redbean-unsecure.o \
|
||||
o/$(MODE)/tool/net/lfuncs.o \
|
||||
o/$(MODE)/tool/net/lfinger.o \
|
||||
o/$(MODE)/tool/net/lre.o \
|
||||
o/$(MODE)/tool/net/ljson.o \
|
||||
o/$(MODE)/tool/net/lmaxmind.o \
|
||||
|
|
|
@ -112,6 +112,7 @@
|
|||
#include "third_party/zlib/zlib.h"
|
||||
#include "tool/args/args.h"
|
||||
#include "tool/build/lib/case.h"
|
||||
#include "tool/net/lfinger.h"
|
||||
#include "tool/net/lfuncs.h"
|
||||
#include "tool/net/ljson.h"
|
||||
#include "tool/net/luacheck.h"
|
||||
|
@ -5253,6 +5254,7 @@ static const luaL_Reg kLuaLibs[] = {
|
|||
{"argon2", luaopen_argon2}, //
|
||||
{"lsqlite3", luaopen_lsqlite3}, //
|
||||
{"maxmind", LuaMaxmind}, //
|
||||
{"finger", LuaFinger}, //
|
||||
{"re", LuaRe}, //
|
||||
{"unix", LuaUnix}, //
|
||||
};
|
||||
|
|
137
tool/viz/maxmind.c
Normal file
137
tool/viz/maxmind.c
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "net/http/http.h"
|
||||
#include "net/http/ip.h"
|
||||
#include "third_party/maxmind/maxminddb.h"
|
||||
|
||||
#define PATH(...) \
|
||||
(const char *const[]) { \
|
||||
__VA_ARGS__, 0 \
|
||||
}
|
||||
|
||||
MMDB_s *ipdb, *asdb;
|
||||
|
||||
int PrintIpInfo(const char *ipstr) {
|
||||
int error;
|
||||
bool uhoh;
|
||||
int64_t ip;
|
||||
uint16_t cc;
|
||||
MMDB_entry_data_s e, f;
|
||||
MMDB_lookup_result_s r;
|
||||
if ((ip = ParseIp(ipstr, -1)) == -1) {
|
||||
fprintf(stderr, "BAD IP: %s\n", ipstr);
|
||||
return -1;
|
||||
}
|
||||
r = MMDB_lookup(ipdb, ip, &error);
|
||||
CHECK_EQ(MMDB_SUCCESS, error);
|
||||
if (!r.found_entry) {
|
||||
fprintf(stderr, "NOT FOUND: %s\n", ipstr);
|
||||
return -1;
|
||||
}
|
||||
printf("%hhu.%hhu.%hhu.%hhu\n", ip >> 24, ip >> 16, ip >> 8, ip);
|
||||
if (!MMDB_aget_value(&r.entry, &e, PATH("location", "metro_code"))) {
|
||||
printf("%s: %s\n", "metro", GetMetroName(e.uint16));
|
||||
}
|
||||
if (!MMDB_aget_value(&r.entry, &e, PATH("postal", "code"))) {
|
||||
printf("%s: %.*s\n", "postal", e.data_size, e.utf8_string);
|
||||
}
|
||||
if (!MMDB_aget_value(&r.entry, &e, PATH("city", "names", "en"))) {
|
||||
printf("%s: %.*s\n", "city", e.data_size, e.utf8_string);
|
||||
}
|
||||
if (!MMDB_aget_value(&r.entry, &e, PATH("subdivisions", "0", "iso_code")) &&
|
||||
!MMDB_aget_value(&r.entry, &f,
|
||||
PATH("subdivisions", "0", "names", "en"))) {
|
||||
printf("%s: %.*s (%.*s)\n", "region", e.data_size, e.utf8_string,
|
||||
f.data_size, f.utf8_string);
|
||||
}
|
||||
if (!MMDB_aget_value(&r.entry, &e, PATH("country", "iso_code")) &&
|
||||
!MMDB_aget_value(&r.entry, &f, PATH("country", "names", "en"))) {
|
||||
printf("%s: %.*s (%.*s)\n", "country", e.data_size, e.utf8_string,
|
||||
f.data_size, f.utf8_string);
|
||||
cc = READ16LE(e.utf8_string);
|
||||
} else {
|
||||
cc = 0;
|
||||
}
|
||||
if (!MMDB_aget_value(&r.entry, &e, PATH("registered_country", "iso_code")) &&
|
||||
!MMDB_aget_value(&r.entry, &f,
|
||||
PATH("registered_country", "names", "en"))) {
|
||||
uhoh = cc && cc != READ16LE(e.utf8_string);
|
||||
printf("%s%s: %.*s (%.*s)%s\n", uhoh ? "\e[1m" : "", "registered",
|
||||
e.data_size, e.utf8_string, f.data_size, f.utf8_string,
|
||||
uhoh ? "\e[0m" : "");
|
||||
}
|
||||
if ((!MMDB_aget_value(&r.entry, &e,
|
||||
PATH("country", "is_in_european_union")) &&
|
||||
e.boolean) ||
|
||||
(!MMDB_aget_value(&r.entry, &e,
|
||||
PATH("registered_country", "is_in_european_union")) &&
|
||||
e.boolean)) {
|
||||
printf("%s: %s\n", "is_in_european_union", "true");
|
||||
}
|
||||
if (!MMDB_aget_value(&r.entry, &e, PATH("continent", "code")) &&
|
||||
!MMDB_aget_value(&r.entry, &f, PATH("continent", "names", "en"))) {
|
||||
printf("%s: %.*s (%.*s)\n", "continent", e.data_size, e.utf8_string,
|
||||
f.data_size, f.utf8_string);
|
||||
}
|
||||
if (!MMDB_aget_value(&r.entry, &e, PATH("location", "time_zone"))) {
|
||||
printf("%s: %.*s\n", "timezone", e.data_size, e.utf8_string);
|
||||
}
|
||||
if (!MMDB_aget_value(&r.entry, &e, PATH("location", "latitude")) &&
|
||||
!MMDB_aget_value(&r.entry, &f, PATH("location", "longitude"))) {
|
||||
printf("%s: %g %g\n", "location", e.double_value, f.double_value);
|
||||
}
|
||||
if (!MMDB_aget_value(&r.entry, &e, PATH("location", "accuracy_radius"))) {
|
||||
printf("%s: %dkm\n", "accuracy", e.uint16);
|
||||
}
|
||||
printf("%s: %s\n", "category", GetIpCategoryName(CategorizeIp(ip)));
|
||||
if ((r = MMDB_lookup(asdb, ip, &error)).found_entry &&
|
||||
!MMDB_aget_value(&r.entry, &e, PATH("autonomous_system_number")) &&
|
||||
!MMDB_aget_value(&r.entry, &f, PATH("autonomous_system_organization"))) {
|
||||
printf("%s: AS%u (%.*s)\n", "asn", e.uint32, f.data_size, f.utf8_string);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i, rc;
|
||||
ipdb = gc(calloc(1, sizeof(MMDB_s)));
|
||||
CHECK_EQ(MMDB_SUCCESS,
|
||||
MMDB_open("/usr/local/share/maxmind/GeoLite2-City.mmdb", 0, ipdb));
|
||||
asdb = gc(calloc(1, sizeof(MMDB_s)));
|
||||
CHECK_EQ(MMDB_SUCCESS,
|
||||
MMDB_open("/usr/local/share/maxmind/GeoLite2-ASN.mmdb", 0, asdb));
|
||||
for (rc = 0, i = 1; i < argc; ++i) {
|
||||
if (PrintIpInfo(argv[i]) != -1) {
|
||||
if (i + 1 < argc) printf("\n");
|
||||
} else {
|
||||
fprintf(stderr, "NOT FOUND: %s\n", argv[i]);
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
MMDB_close(asdb);
|
||||
MMDB_close(ipdb);
|
||||
return rc;
|
||||
}
|
156
tool/viz/tcp.c
Normal file
156
tool/viz/tcp.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
// clang-format off
|
||||
|
||||
static char ip[] = "\
|
||||
\x45\x00\x00\x3c\xc8\xbc\x40\x00\x40\x06\x48\xf6\x7f\x0a\x0a\x7a\
|
||||
\x7f\x0a\x0a\x7c\xe2\x24\x1b\x58\xf6\xe9\xf2\x85\x00\x00\x00\x00\
|
||||
\xa0\x02\xfa\xf0\x5f\xac\x00\x00\x02\x04\x05\xb4\x04\x02\x08\x0a\
|
||||
\x4a\x43\x93\x29\x00\x00\x00\x00\x01\x03\x03\x07";
|
||||
|
||||
static const char *const kTcpOptionNames[] = {
|
||||
[0] = "End of Option List",
|
||||
[1] = "No-Operation",
|
||||
[2] = "Maximum Segment Size",
|
||||
[3] = "Window Scale",
|
||||
[4] = "SACK Permitted",
|
||||
[5] = "SACK",
|
||||
[6] = "Echo (obsoleted by option 8)",
|
||||
[7] = "Echo Reply (obsoleted by option 8)",
|
||||
[8] = "Timestamps",
|
||||
[9] = "Partial Order Connection Permitted (obsolete)",
|
||||
[10] = "Partial Order Service Profile (obsolete)",
|
||||
[11] = "CC (obsolete)",
|
||||
[12] = "CC.NEW (obsolete)",
|
||||
[13] = "CC.ECHO (obsolete)",
|
||||
[14] = "TCP Alternate Checksum Request (obsolete)",
|
||||
[15] = "TCP Alternate Checksum Data (obsolete)",
|
||||
[16] = "Skeeter",
|
||||
[17] = "Bubba",
|
||||
[18] = "Trailer Checksum Option",
|
||||
[19] = "MD5 Signature Option (obsoleted by option 29)",
|
||||
[20] = "SCPS Capabilities",
|
||||
[21] = "Selective Negative Acknowledgements",
|
||||
[22] = "Record Boundaries",
|
||||
[23] = "Corruption experienced",
|
||||
[24] = "SNAP",
|
||||
[25] = "Unassigned (released 2000-12-18)",
|
||||
[26] = "TCP Compression Filter",
|
||||
[27] = "Quick-Start Response",
|
||||
[28] = "User Timeout Option",
|
||||
[29] = "TCP Authentication Option (TCP-AO)",
|
||||
[30] = "Multipath TCP (MPTCP)",
|
||||
[31] = "Reserved (known unauthorized use without proper IANA assignm",
|
||||
[32] = "Reserved (known unauthorized use without proper IANA assignm",
|
||||
[33] = "Reserved (known unauthorized use without proper IANA assignm",
|
||||
[34] = "variable TCP Fast Open Cookie",
|
||||
[35] = "Reserved",
|
||||
[69] = "Encryption Negotiation",
|
||||
[253] = "RFC3692-1",
|
||||
[254] = "RFC3692-2",
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int version = (ip[0] & 0b11110000) >> 4;
|
||||
int ihl = (ip[0] & 0b00001111) >> 0;
|
||||
int dscp = (ip[1] & 0b11111100) >> 2;
|
||||
int ecn = (ip[1] & 0b00000011) >> 0;
|
||||
int lengthtotal = READ16BE(ip + 2);
|
||||
int identification = READ16BE(ip + 4);
|
||||
int flags = (ip[6] & 0b11100000) >> 5;
|
||||
int fragmentoffset = (ip[6] & 0b00011111) << 8 | (ip[7] & 255);
|
||||
int ttl = ip[8] & 255;
|
||||
int protocol = ip[9] & 255;
|
||||
int ipchecksum = (ip[10] & 255) << 8 | (ip[11] & 255);
|
||||
int srcip = READ32BE(ip + 12);
|
||||
int dstip = READ32BE(ip + 16);
|
||||
|
||||
printf("\n");
|
||||
printf("// version = %u\n", version);
|
||||
printf("// ihl = %u\n", ihl * 4);
|
||||
printf("// dscp = %u\n", dscp);
|
||||
printf("// ecn = %u\n", ecn);
|
||||
printf("// lengthtotal = %u\n", lengthtotal);
|
||||
printf("// identification = %u\n", identification);
|
||||
printf("// flags = %u\n", flags);
|
||||
printf("// fragmentoffset = %u\n", fragmentoffset);
|
||||
printf("// ttl = %u\n", ttl);
|
||||
printf("// protocol = %u\n", protocol);
|
||||
printf("// ipchecksum = %u\n", ipchecksum);
|
||||
printf("// srcip = %hhu.%hhu.%hhu.%hhu\n", srcip >> 24, srcip >> 16, srcip >> 8, srcip);
|
||||
printf("// dstip = %hhu.%hhu.%hhu.%hhu\n", dstip >> 24, dstip >> 16, dstip >> 8, dstip);
|
||||
printf("// \n");
|
||||
|
||||
char *tcp = ip + ihl * 4;
|
||||
int srcport = READ16BE(tcp + 0);
|
||||
int dstport = READ16BE(tcp + 2);
|
||||
int sequence = READ32BE(tcp + 4);
|
||||
int acknumber = READ32BE(tcp + 8);
|
||||
int dataoffset = (tcp[12] & 0b11110000) >> 4;
|
||||
bool ns = !!(tcp[12] & 0b00000001);
|
||||
bool cwr = !!(tcp[13] & 0b10000000);
|
||||
bool ece = !!(tcp[13] & 0b01000000);
|
||||
bool urg = !!(tcp[13] & 0b00100000);
|
||||
bool ack = !!(tcp[13] & 0b00010000);
|
||||
bool psh = !!(tcp[13] & 0b00001000);
|
||||
bool rst = !!(tcp[13] & 0b00000100);
|
||||
bool syn = !!(tcp[13] & 0b00000010);
|
||||
bool fin = !!(tcp[13] & 0b00000001);
|
||||
int wsize = READ16BE(tcp + 14);
|
||||
int tcpchecksum = READ16BE(tcp + 16);
|
||||
int urgpointer = READ16BE(tcp + 18);
|
||||
|
||||
printf("// srcport = %u\n", srcport);
|
||||
printf("// dstport = %u\n", dstport);
|
||||
printf("// sequence = %u\n", sequence);
|
||||
printf("// acknumber = %u\n", acknumber);
|
||||
printf("// dataoffset = %u\n", dataoffset);
|
||||
printf("// ns = %u\n", ns);
|
||||
printf("// cwr = %u\n", cwr);
|
||||
printf("// ece = %u\n", ece);
|
||||
printf("// urg = %u\n", urg);
|
||||
printf("// ack = %u\n", ack);
|
||||
printf("// psh = %u\n", psh);
|
||||
printf("// rst = %u\n", rst);
|
||||
printf("// syn = %u\n", syn);
|
||||
printf("// fin = %u\n", fin);
|
||||
printf("// wsize = %u\n", wsize);
|
||||
printf("// tcpchecksum = %u\n", tcpchecksum);
|
||||
printf("// urgpointer = %u\n", urgpointer);
|
||||
printf("// \n");
|
||||
|
||||
int c, i, j, n;
|
||||
for (i = 20; i + 1 < dataoffset * 4;) {
|
||||
printf("// option");
|
||||
switch ((c = tcp[i] & 255)) {
|
||||
case 0:
|
||||
case 1:
|
||||
printf(" %u", c);
|
||||
++i;
|
||||
break;
|
||||
default:
|
||||
n = tcp[i + 1] & 255;
|
||||
printf(" %u %u", c, n);
|
||||
for (j = 2; j < n; ++j) {
|
||||
printf(" %u", tcp[i + j] & 255);
|
||||
}
|
||||
i += n;
|
||||
break;
|
||||
}
|
||||
if (kTcpOptionNames[c]) {
|
||||
printf(" (%s)", kTcpOptionNames[c]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -50,8 +50,9 @@ TOOL_VIZ_DIRECTDEPS = \
|
|||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_STB \
|
||||
THIRD_PARTY_MAXMIND \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_STB \
|
||||
THIRD_PARTY_XED \
|
||||
THIRD_PARTY_ZLIB \
|
||||
TOOL_DECODE_LIB \
|
||||
|
|
Loading…
Reference in a new issue