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
15struct 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
28static 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
45static 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
62static 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
73static 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
82static FlagsTypeHandler::FlagsList kRecvFlags;
83static EnumTypeHandler::EnumMap kSocketFamilyMap;
84static EnumTypeHandler::EnumMap kSocketTypeMap;
85static EnumTypeHandler::EnumMap kShutdownHowMap;
86
87
88void
89patch_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