xref: /haiku/src/bin/debug/strace/network.cpp (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
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 FlagsTypeHandler::FlagsList kRecvFlags;
83 static EnumTypeHandler::EnumMap kSocketFamilyMap;
84 static EnumTypeHandler::EnumMap kSocketTypeMap;
85 static EnumTypeHandler::EnumMap kShutdownHowMap;
86 
87 
88 void
89 patch_network()
90 {
91 	for (int i = 0; kRecvFlagInfos[i].name != NULL; i++) {
92 		kRecvFlags.push_back(kRecvFlagInfos[i]);
93 	}
94 	for (int i = 0; kSocketFamily[i].name != NULL; i++) {
95 		kSocketFamilyMap[kSocketFamily[i].index] = kSocketFamily[i].name;
96 	}
97 	for (int i = 0; kSocketType[i].name != NULL; i++) {
98 		kSocketTypeMap[kSocketType[i].index] = kSocketType[i].name;
99 	}
100 	for (int i = 0; kShutdownHow[i].name != NULL; i++) {
101 		kShutdownHowMap[kShutdownHow[i].index] = kShutdownHow[i].name;
102 	}
103 
104 	Syscall *recv = get_syscall("_kern_recv");
105 	recv->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
106 	Syscall *recvfrom = get_syscall("_kern_recvfrom");
107 	recvfrom->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
108 	Syscall *recvmsg = get_syscall("_kern_recvmsg");
109 	recvmsg->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
110 	Syscall *send = get_syscall("_kern_send");
111 	send->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
112 	Syscall *sendmsg = get_syscall("_kern_sendmsg");
113 	sendmsg->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
114 	Syscall *sendto = get_syscall("_kern_sendto");
115 	sendto->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kRecvFlags));
116 
117 	Syscall *socket = get_syscall("_kern_socket");
118 	socket->GetParameter("family")->SetHandler(
119 		new EnumTypeHandler(kSocketFamilyMap));
120 	socket->GetParameter("type")->SetHandler(
121 		new EnumTypeHandler(kSocketTypeMap));
122 
123 	Syscall *shutdown = get_syscall("_kern_shutdown_socket");
124 	shutdown->GetParameter("how")->SetHandler(
125 		new EnumTypeHandler(kShutdownHowMap));
126 
127 	Syscall *poll = get_syscall("_kern_poll");
128 	poll->ParameterAt(0)->SetInOut(true);
129 
130 	Syscall *select = get_syscall("_kern_select");
131 	select->ParameterAt(1)->SetInOut(true);
132 	select->ParameterAt(2)->SetInOut(true);
133 	select->ParameterAt(3)->SetInOut(true);
134 
135 	Syscall *wait = get_syscall("_kern_wait_for_child");
136 	wait->ParameterAt(2)->SetOut(true);
137 	wait->ParameterAt(3)->SetOut(true);
138 
139 	Syscall *createPipe = get_syscall("_kern_create_pipe");
140 	createPipe->ParameterAt(0)->SetOut(true);
141 	createPipe->ParameterAt(0)->SetCount(2);
142 
143 	Syscall *socketPair = get_syscall("_kern_socketpair");
144 	socketPair->ParameterAt(3)->SetOut(true);
145 	socketPair->ParameterAt(3)->SetCount(2);
146 	socketPair->GetParameter("family")->SetHandler(
147 		new EnumTypeHandler(kSocketFamilyMap));
148 	socketPair->GetParameter("type")->SetHandler(
149 		new EnumTypeHandler(kSocketTypeMap));
150 
151 }
152