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