xref: /haiku/src/bin/debug/strace/network.cpp (revision 8b5cc9cf52bc7de09b9fa2db0f16fced0f4ae2e9)
1 /*
2  * Copyright 2023, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 //#include <OS.h>
8 #include <sys/socket.h>
9 
10 #include "strace.h"
11 #include "Syscall.h"
12 #include "TypeHandler.h"
13 
14 
15 struct enum_info {
16 	unsigned int index;
17 	const char *name;
18 };
19 
20 #define ENUM_INFO_ENTRY(name) \
21 	{ name, #name }
22 
23 
24 #define FLAG_INFO_ENTRY(name) \
25 	{ name, #name }
26 
27 
28 static const FlagsTypeHandler::FlagInfo kRecvFlagInfos[] = {
29 	FLAG_INFO_ENTRY(MSG_PEEK),
30 	FLAG_INFO_ENTRY(MSG_OOB),
31 	FLAG_INFO_ENTRY(MSG_DONTROUTE),
32 	FLAG_INFO_ENTRY(MSG_EOR),
33 	FLAG_INFO_ENTRY(MSG_TRUNC),
34 	FLAG_INFO_ENTRY(MSG_CTRUNC),
35 	FLAG_INFO_ENTRY(MSG_WAITALL),
36 	FLAG_INFO_ENTRY(MSG_DONTWAIT),
37 	FLAG_INFO_ENTRY(MSG_BCAST),
38 	FLAG_INFO_ENTRY(MSG_MCAST),
39 	FLAG_INFO_ENTRY(MSG_EOF),
40 	FLAG_INFO_ENTRY(MSG_NOSIGNAL),
41 	{ 0, NULL }
42 };
43 
44 
45 static const enum_info kSocketFamily[] = {
46 	ENUM_INFO_ENTRY(AF_UNSPEC),
47 	ENUM_INFO_ENTRY(AF_INET),
48 	ENUM_INFO_ENTRY(AF_APPLETALK),
49 	ENUM_INFO_ENTRY(AF_ROUTE),
50 	ENUM_INFO_ENTRY(AF_LINK),
51 	ENUM_INFO_ENTRY(AF_INET6),
52 	ENUM_INFO_ENTRY(AF_DLI),
53 	ENUM_INFO_ENTRY(AF_IPX),
54 	ENUM_INFO_ENTRY(AF_NOTIFY),
55 	ENUM_INFO_ENTRY(AF_UNIX),
56 	ENUM_INFO_ENTRY(AF_BLUETOOTH),
57 
58 	{ 0, NULL }
59 };
60 
61 
62 static const enum_info kSocketType[] = {
63 	ENUM_INFO_ENTRY(SOCK_STREAM),
64 	ENUM_INFO_ENTRY(SOCK_DGRAM),
65 	ENUM_INFO_ENTRY(SOCK_RAW),
66 	ENUM_INFO_ENTRY(SOCK_SEQPACKET),
67 	ENUM_INFO_ENTRY(SOCK_MISC),
68 
69 	{ 0, NULL }
70 };
71 
72 
73 static const enum_info kShutdownHow[] = {
74 	ENUM_INFO_ENTRY(SHUT_RD),
75 	ENUM_INFO_ENTRY(SHUT_WR),
76 	ENUM_INFO_ENTRY(SHUT_RDWR),
77 
78 	{ 0, NULL }
79 };
80 
81 
82 static const FlagsTypeHandler::FlagInfo kSocketFlagInfos[] = {
83 	FLAG_INFO_ENTRY(SOCK_NONBLOCK),
84 	FLAG_INFO_ENTRY(SOCK_CLOEXEC),
85 
86 	{ 0, NULL }
87 };
88 
89 
90 static FlagsTypeHandler::FlagsList kRecvFlags;
91 static EnumTypeHandler::EnumMap kSocketFamilyMap;
92 static EnumTypeHandler::EnumMap kSocketTypeMap;
93 static EnumTypeHandler::EnumMap kShutdownHowMap;
94 static FlagsTypeHandler::FlagsList kSocketFlags;
95 
96 
97 void
98 patch_network()
99 {
100 	for (int i = 0; kRecvFlagInfos[i].name != NULL; i++) {
101 		kRecvFlags.push_back(kRecvFlagInfos[i]);
102 	}
103 	for (int i = 0; kSocketFamily[i].name != NULL; i++) {
104 		kSocketFamilyMap[kSocketFamily[i].index] = kSocketFamily[i].name;
105 	}
106 	for (int i = 0; kSocketType[i].name != NULL; i++) {
107 		kSocketTypeMap[kSocketType[i].index] = kSocketType[i].name;
108 	}
109 	for (int i = 0; kShutdownHow[i].name != NULL; i++) {
110 		kShutdownHowMap[kShutdownHow[i].index] = kShutdownHow[i].name;
111 	}
112 	for (int i = 0; kSocketFlagInfos[i].name != NULL; i++) {
113 		kSocketFlags.push_back(kSocketFlagInfos[i]);
114 	}
115 
116 	Syscall *recv = get_syscall("_kern_recv");
117 	recv->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
118 	Syscall *recvfrom = get_syscall("_kern_recvfrom");
119 	recvfrom->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
120 	Syscall *recvmsg = get_syscall("_kern_recvmsg");
121 	recvmsg->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
122 	Syscall *send = get_syscall("_kern_send");
123 	send->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
124 	Syscall *sendmsg = get_syscall("_kern_sendmsg");
125 	sendmsg->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
126 	Syscall *sendto = get_syscall("_kern_sendto");
127 	sendto->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
128 
129 	Syscall *socket = get_syscall("_kern_socket");
130 	socket->GetParameter("family")->SetHandler(
131 		new EnumTypeHandler(kSocketFamilyMap));
132 	socket->GetParameter("type")->SetHandler(
133 		new EnumFlagsTypeHandler(kSocketTypeMap, kSocketFlags));
134 
135 	Syscall *shutdown = get_syscall("_kern_shutdown_socket");
136 	shutdown->GetParameter("how")->SetHandler(
137 		new EnumTypeHandler(kShutdownHowMap));
138 
139 	Syscall *socketPair = get_syscall("_kern_socketpair");
140 	socketPair->ParameterAt(3)->SetOut(true);
141 	socketPair->ParameterAt(3)->SetCount(2);
142 	socketPair->GetParameter("family")->SetHandler(
143 		new EnumTypeHandler(kSocketFamilyMap));
144 	socketPair->GetParameter("type")->SetHandler(
145 		new EnumFlagsTypeHandler(kSocketTypeMap, kSocketFlags));
146 
147 	Syscall *accept = get_syscall("_kern_accept");
148 	accept->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kSocketFlags));
149 }
150