Sfoglia il codice sorgente

UserspaceEmulator: Intercept sendto()

With this, `ue /bin/ntpquery` can be used to test sendto() and
recvfrom() in ue. (It eventually hits an unimplemented FILD_RM64,
but not before doing emulated network i/o and printing response
details.)
Nico Weber 4 anni fa
parent
commit
f0018aca1d

+ 16 - 0
DevTools/UserspaceEmulator/Emulator.cpp

@@ -354,6 +354,8 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
         return virt$listen(arg1, arg2);
     case SC_select:
         return virt$select(arg1);
+    case SC_sendto:
+        return virt$sendto(arg1);
     case SC_recvfrom:
         return virt$recvfrom(arg1);
     case SC_kill:
@@ -619,6 +621,20 @@ int Emulator::virt$recvfrom(FlatPtr params_addr)
     return rc;
 }
 
+int Emulator::virt$sendto(FlatPtr params_addr)
+{
+    Syscall::SC_sendto_params params;
+    mmu().copy_from_vm(&params, params_addr, sizeof(params));
+
+    auto buffer = mmu().copy_buffer_from_vm((FlatPtr)params.data.data, params.data.size);
+
+    sockaddr_storage address;
+    if (params.addr)
+        mmu().copy_from_vm(&address, (FlatPtr)params.addr, min(sizeof(address), (size_t)params.addr_length));
+
+    return sendto(params.sockfd, buffer.data(), buffer.size(), params.flags, params.addr ? (struct sockaddr*)&address : nullptr, params.addr_length);
+}
+
 int Emulator::virt$select(FlatPtr params_addr)
 {
     Syscall::SC_select_params params;

+ 1 - 0
DevTools/UserspaceEmulator/Emulator.h

@@ -132,6 +132,7 @@ private:
     int virt$accept(int sockfd, FlatPtr address, FlatPtr address_length);
     int virt$bind(int sockfd, FlatPtr address, socklen_t address_length);
     int virt$recvfrom(FlatPtr);
+    int virt$sendto(FlatPtr);
     int virt$connect(int sockfd, FlatPtr address, socklen_t address_size);
     void virt$exit(int);
     ssize_t virt$getrandom(FlatPtr buffer, size_t buffer_size, unsigned int flags);