From owner-freebsd-hackers@FreeBSD.ORG Thu Jan 12 04:06:15 2006 Return-Path: X-Original-To: freebsd-hackers@freebsd.org Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 688DC16A41F for ; Thu, 12 Jan 2006 04:06:15 +0000 (GMT) (envelope-from nessup@gmail.com) Received: from fed1rmmtao05.cox.net (fed1rmmtao05.cox.net [68.230.241.34]) by mx1.FreeBSD.org (Postfix) with ESMTP id 089D543D45 for ; Thu, 12 Jan 2006 04:06:09 +0000 (GMT) (envelope-from nessup@gmail.com) Received: from [192.168.1.2] (really [68.111.13.24]) by fed1rmmtao05.cox.net (InterMail vM.6.01.05.02 201-2131-123-102-20050715) with ESMTP id <20060112040415.QNVS17838.fed1rmmtao05.cox.net@[192.168.1.2]>; Wed, 11 Jan 2006 23:04:15 -0500 In-Reply-To: <096b01c6171f$62711140$c3e7a8c0@david> References: <096b01c6171f$62711140$c3e7a8c0@david> Mime-Version: 1.0 (Apple Message framework v623) Content-Type: text/plain; charset=US-ASCII; format=flowed Message-Id: Content-Transfer-Encoding: 7bit From: Dan Joumaa Date: Wed, 11 Jan 2006 21:06:08 -0700 To: David S. Madole , julian@elischer.org X-Mailer: Apple Mail (2.623) Cc: freebsd-hackers@freebsd.org Subject: Re: Telling BSD to stop resetting the connection! X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Jan 2006 04:06:15 -0000 On Jan 11, 2006, at 7:24 PM, David S. Madole wrote: > From: "Dan Joumaa" >> >> 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