On Jan 11, 2006, at 7:24 PM, David S. Madole wrote:
From: "Dan Joumaa" <[EMAIL PROTECTED]>
I'm trying to code a software gateway with divert sockets. So far
basic things are working, but the net stack constantly resets the
connection whenever a SYN-ACK is sent to it.
Any ideas on how to stop the net stack from resetting my connections,
preferably programmatically?
I think you are doing something wrong, either not diverting packets
that should be, or reinjecting packets from your code that are
incorrect in some way.
Without seeing the ipfw rules or code, there's not much else that can
be said.
David
Here's the rules:
00001 divert 4747 tcp from 192.168.1.6 to any in
00001 divert 4747 udp from 192.168.1.6 to any in
The following rules are added dynamically when my client sends a packet
to a server so we can get it back on the divert socket. In this case,
it would be:
00001 divert 4747 tcp from 205.166.76.216 to any in
00001 divert 4747 udp from 205.166.76.216 to any in
First thing, I receive the packets from the divert socket.
...
if( (datagramlen = recvfrom( sock->ipfd, buffer, buflen, 0x0,
(struct sockaddr *)&sin, &sinlen )) <
0 )
(void)fprintf( stderr, "Failed to receive packet. Error: %i\n",
errno );
...
If it is from my client, I add the destination host the client wants to
talk to as a divert rule to the IPFW...
entry->version = IP_FW_CURRENT_API_VERSION;
entry->fw_number = 1;
entry->fw_src.s_addr = htonl(host);
entry->fw_smsk.s_addr = ~0;
entry->fw_prot = IPPROTO_TCP;
entry->fw_flg = IP_FW_F_DIVERT|IP_FW_F_IN;
entry->fw_un.fu_divert_port = DIVERTSOCKET_PORT;
(void)memcpy( entry->fw_in_if.fu_via_if.name, sock->dev, FW_IFNLEN );
entry->fw_in_if.fu_via_if.unit = -1;
if( setsockopt( sock->fwfd, IPPROTO_IP, IP_FW_ADD, entry,
sizeof(struct ip_fw) ) < 0 ) {
(void)fprintf( stderr, "Failed to add entry to filter. Error:
%i\n",
errno );
return (-1);
}
... modify the packet for sending ...
ip_hdr->ip_src.s_addr = htonl( thisIP );
/* checksuming code below */
... and send it through a raw socket.
sin.sin_family = AF_INET;
sin.sin_port = 0;
sin.sin_addr.s_addr = ip_hdr->ip_dst.s_addr;
if( (datagramlen = sendto( socket->fwfd, buffer, buflen, 0x0,
(struct sockaddr *)&sin, sizeof(sin) ))
< 0 )
(void)fprintf( stderr, "Failed to send packet. Error: %i\n",
errno );
If it's from someone outside the LAN, modify it for forwarding to the
client...
ip_hdr->ip_dst.s_addr = htonl( clientIP );
ip_hdr->ip_sum = 0;
ip_hdr->ip_sum = htons( in_cksum( (u_short *)ip_hdr,
sizeof(struct iphdr) ) );
/* checksuming code below */
And send it through a raw socket.
All in all, that's really what it is. This seems to work with normal
HTTP requests, but fails to work with establishing a connection on
HTTPS. :/
--ness
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"