socket.c revision 56ddefc0b36ad1ad21a595bf75c4ac460085c24b
3261N/A * Copyright (c) 1995 Danny Gasparovski. 0N/A * Please read the file COPYRIGHT for the 0N/A * terms and conditions of the copyright. 0N/A * Create a new socket, initialise the fields 0N/A * It is the responsibility of the caller to 0N/A * insque() it into the correct linked-list 0N/A * remque and free a socket, clobber cache 0N/A * Read from so's socket into sb_snd, updating all relevant sbuf fields 0N/A * NOTE: This will only be called if it is select()ed for reading, so 0N/A * a read() of 0 (or less) means it's disconnected 0N/A * No need to check if there's enough room to read. 0N/A * soread wouldn't have been called if there weren't 1173N/A /* Should never succeed, but... */ 1173N/A /* Should never succeed, but... */ 0N/A * Special case for WSAEnumNetworkEvents: If we receive 0 bytes that 0N/A * _could_ mean that the connection is closed. But we will receive an 0N/A * FD_CLOSE event later if the connection was _really_ closed. With 0N/A * would be dangerous. 0N/A /* nn == 0 means peer has performed an orderly shutdown */ 0N/A * If there was no error, try and read the second time round 0N/A * We read again if n = 2 (ie, there's another part of the buffer) 0N/A * and we read as much as we could in the first read 0N/A * We don't test for <= 0 this time, because there legitimately 0N/A * might not be any more data (since the socket is non-blocking), 0N/A * a close will be detected on next iteration. 0N/A * A return of -1 wont (shouldn't) happen, since it didn't happen above 1173N/A * When the socket is created, we set it SO_OOBINLINE, 1173N/A * so when OOB data arrives, we soread() it and everything 1173N/A * in the send buffer is sent as urgent data 0N/A * We take a guess at how much urgent data has arrived. 0N/A * In most situations, when urgent data arrives, the next 0N/A * read() should get all the urgent data. This guess will 0N/A * be wrong however if more data arrives just after the 0N/A * urgent data, or the read() doesn't return all the 0N/A * There's a lot duplicated code here, but... 0N/A char buff[
2048];
/* XXX Shouldn't be sending more oob data than this */ 0N/A /* We can send it directly */ 0N/A * Since there's no sendv or sendtov like writev, 0N/A * we must copy all data to a linear buffer then 0N/A * Write data from so_rcv to so's socket, 0N/A * updating all sbuf field as necessary 0N/A * No need to check if there's something to write, 0N/A * sowrite wouldn't have been called otherwise 0N/A /* Should never succeed, but... */ 0N/A /* Check if there's urgent data to send, and if so, send it */ 0N/A /* This should never happen, but people tell me it does *shrug* */ 0N/A * If in DRAIN mode, and there's no more data, set 0N/A * recvfrom() a UDP socket 0N/A /* This is a "ping" reply */ 0N/A /* A "normal" UDP packet */ 0N/A * XXX Shouldn't FIONREAD packets destined for port 53, 0N/A * but I don't know the max packet size for DNS lookups 0N/A /* if (so->so_fport != htons(53)) */ 1173N/A * Hack: domain name lookup will be used the most for UDP, 1173N/A * and since they'll only be used once there's no need 1173N/A * for the 4 minute (or whatever) timeout... So we time them 0N/A * out much quicker (10 seconds for now...) 0N/A * If this packet was destined for CTL_ADDR, 0N/A * make it look like that's where it came from, done by udp_output 0N/A }
/* if ping packet */ 0N/A /* handle this case at 'default:' */ 0N/A /* Send the packet to host to fully emulate broadcast */ 0N/A /** @todo r=klaus: on Linux host this causes the host to receive 0N/A * the packet twice for some reason. And I cannot find any place 0N/A * in the man pages which states that sending a broadcast does not 0N/A * reach the host itself. */ 0N/A /* Don't care what port we get */ 0N/A * Kill the socket if there's no reply in 4 minutes, 0N/A * but only if it's an expirable socket 0N/A * XXX This should really be tcp_listen 0N/A /* free(so); Not sofree() ??? free(NULL) == NOP */ 0N/A /* Don't tcp_attach... we don't need so_snd nor so_rcv */ 0N/A * SS_FACCEPTONCE sockets must time out. 0N/A /* Restore the real errno */ 0N/A /* Restore the real errno */ 0N/A * Data is available in so_rcv 0N/A * Just write() the data to the socket 0N/A * Data has been freed in so_snd 0N/A * We have room for a read() if we want to 0N/A * For now, don't read, it'll be done in the main loop 0N/A * Various session state calls 0N/A * XXX Should be #define's 1173N/A * The socket state stuff needs work, these often get call 2 or 3 1173N/A * times each when only 1 was needed 0N/A /* XXX close() here as well? */ 0N/A * XXX Do nothing ... ? 0N/A * Set write drain mode 0N/A * Set CANTSENDMORE once all data has been write()n 0N/A LogRel((
"NAT: Can't find the corresponding packet for the received ICMP\n"));
0N/A /* Now ip is pointing on header we've sent from guest */ 0N/A /* source address from original IP packet*/ 0N/A /* overide ther tail of old packet */ 0N/A ip =
mtod(m,
struct ip *);
/* ip is from mbuf we've overrided */ 0N/A /* according RFC 793 error messages required copy of initial IP header + 64 bit */ 1173N/A /* the low level expects fields to be in host format so let's convert them*/ 0N/A /* Don't call m_free here*/ 0N/A return;
/* no error */ 0N/A /* UNREACH error inject here */ 0N/A ip->
ip_hl =
sizeof(
struct ip) >>
2;
/* requiered for icmp_reflect, no IP options */ 0N/A#
endif /* RT_OS_WINDOWS */ 0N/A#
endif /* VBOX_WITH_SLIRP_ICMP */ 0N/A /* XXX Check if reply is "correct"? */