+ case 8: { // sendto
+ if(!CheckMem(Data, 2*sizeof(void*)+2)) {
+ LOG("Data pointer invalid");
+ LEAVE_RET('i', -1);
+ }
+ const struct sSendToArgs {
+ const tUDPEndpoint* ep;
+ const void* buf;
+ const Uint16 buflen;
+ } info = *(const struct sSendToArgs*)Data;
+ LOG("sendto(buf=%p + %u, ep=%p)", info.buf, info.buflen, info.ep);
+ if(!CheckMem(info.ep, 2+2) || !CheckMem(info.ep, 2+2+IPStack_GetAddressSize(info.ep->AddrType)) ) {
+ LEAVE_RET('i', -1);
+ }
+ if(!CheckMem(info.buf, info.buflen)) {
+ LEAVE_RET('i', -1);
+ }
+
+ UDP_SendPacketTo(chan, info.ep->AddrType, &info.ep->Addr, info.ep->Port,
+ info.buf, (size_t)info.buflen);
+
+ LEAVE_RET('i', info.buflen); }
+ case 9: { // recvfrom
+ if(!CheckMem(Data, 2*sizeof(void*)+2)) {
+ LOG("Data pointer invalid");
+ LEAVE_RET('i', -1);
+ }
+ const struct sRecvFromArgs {
+ tUDPEndpoint* ep;
+ void* buf;
+ Uint16 buflen;
+ } info = *(const struct sRecvFromArgs*)Data;
+ LOG("recvfrom(buf=%p + %u, ep=%p)", info.buf, info.buflen, info.ep);
+ if(!CheckMem(info.ep, 2+2)) {
+ LEAVE_RET('i', -1);
+ }
+ if(!CheckMem(info.buf, info.buflen)) {
+ LEAVE_RET('i', -1);
+ }
+
+ tUDPPacket *pack = UDP_Channel_WaitForPacket(chan, 0);
+ if( pack == NULL ) {
+ LOG("No packet");
+ LEAVE_RET('i', 0);
+ }
+
+ size_t addrsize = IPStack_GetAddressSize(pack->Remote.AddrType);
+ if( !CheckMem(info.ep, 2+2+addrsize) ) {
+ LOG("Insufficient space for source address");
+ free(pack);
+ LEAVE_RET('i', -1);
+ }
+ info.ep->Port = pack->Remote.Port;
+ info.ep->AddrType = pack->Remote.AddrType;
+ memcpy(&info.ep->Addr, &pack->Remote.Addr, addrsize);
+
+ size_t retlen = (info.buflen < pack->Length ? info.buflen : pack->Length);
+ memcpy(info.buf, pack->Data, retlen);
+
+ free(pack);
+
+ LEAVE_RET('i', retlen); }