All of lore.kernel.org
 help / color / mirror / Atom feed
* Problem using REDIRECT and SO_ORIGINAL_DST
@ 2002-11-06 15:22 Wilson Padovani Júnior
  2002-11-06 19:06 ` Balazs Scheidler
  0 siblings, 1 reply; 3+ messages in thread
From: Wilson Padovani Júnior @ 2002-11-06 15:22 UTC (permalink / raw)
  To: netfilter-devel

Hi.

    I trying to write a transparent proxy program, but I having 
trouble to retrieve the original destination address of the redirected 
connections.
    I using the Linux Slackware 7.0 distribution with the glibc-2.1.2 
installed and running the kernel-2.4.17 and iptables-1.2.6a. To test 
the packet redirection, I wrote the following test program, based on 
the explanations found in this mailinglist and the code of the squid 
2.4 source:

######################################################

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <dlfcn.h>
#include <linux/netfilter_ipv4.h>

#define SD_BOTH             2
#define SOCKET              int
#define INVALID_SOCKET      (SOCKET)(~0)
#define SOCKET_ERROR        (-1)

int main(void)
{
    SOCKET listen_sock, new_sock;
    struct sockaddr_in client;
    struct sockaddr_in me;
    struct sockaddr_in peer;

    unsigned long sockmode = 0;
    socklen_t SLen = sizeof(client);

    if ((listen_sock = socket(AF_INET, SOCK_STREAM, 0))== 
INVALID_SOCKET) {
        exit(1);
    }

    /* Local address and port */
    me.sin_family = AF_INET;
    me.sin_port = htons(10101);
    inet_aton("10.0.0.1", &me.sin_addr);

    if (ioctl(listen_sock, FIONBIO, &sockmode) == SOCKET_ERROR) {
        close(listen_sock);
        exit(1);
    }

    if (bind(listen_sock, (struct sockaddr *)&me, sizeof(me)) == 
SOCKET_ERROR) {
        close(listen_sock);
        exit(1);
    }

    if (listen(listen_sock, SOMAXCONN) == SOCKET_ERROR) {
        shutdown(listen_sock, SD_BOTH);
        close(listen_sock);
        exit(1);
    }

    while ((new_sock = accept(listen_sock, (struct sockaddr *)&client, 
&SLen))
            != INVALID_SOCKET)
    {
        SLen = sizeof(peer);
        memset(&peer, 0, SLen);
        getsockopt(new_sock, SOL_IP, SO_ORIGINAL_DST, &peer, &SLen);
        printf( "Client: %s:%hu\nMe: %s:%hu\nPeer: %s:%hu\n",
                inet_ntoa(client.sin_addr), ntohs(client.sin_port),
                inet_ntoa(me.sin_addr), ntohs(me.sin_port),
                inet_ntoa(peer.sin_addr), ntohs(peer.sin_port) );

        if ( shutdown(new_sock, SD_BOTH) == SOCKET_ERROR ||
             close(new_sock) == SOCKET_ERROR )
        {
            shutdown(listen_sock, SD_BOTH);
            close(listen_sock);
            exit(1);
        }
    }
    if(new_sock == INVALID_SOCKET) {
        shutdown(listen_sock, SD_BOTH);
        close(listen_sock);
        exit(1);
    }

    if (shutdown(listen_sock, SD_BOTH) == SOCKET_ERROR ||
        close(listen_sock) == SOCKET_ERROR)
    {
        exit(1);
    }

    exit(0);
}

######################################################

    And I create the iptables rules to make the NAT of my intranet 
network addresses and the redirection of the outgoing connections, as 
follow :

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1234 -j REDIRECT 
--to-port 10101
iptables -t nat -A POSTROUTING -o eth1 -s 10.0.0.0/24 -j SNAT --to 
1.2.3.4

    When I run the program and make the test opening a telnet session 
to any external IP on port 1234, the test program even show the result 
:

Client: 10.0.0.100:<anyport>
Me: 10.0.0.100:10101
Peer: 10.0.0.100:1234

    This tells me the redirected port and the original port, but all 
IP addresses always points to the client's address!! What's wrong in this?

Any help is welcome.

Wilson.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Problem using REDIRECT and SO_ORIGINAL_DST
  2002-11-06 15:22 Wilson Padovani Júnior
@ 2002-11-06 19:06 ` Balazs Scheidler
  0 siblings, 0 replies; 3+ messages in thread
From: Balazs Scheidler @ 2002-11-06 19:06 UTC (permalink / raw)
  To: Wilson Padovani Júnior; +Cc: netfilter-devel

On Wed, Nov 06, 2002 at 03:22:29PM +0000, Wilson Padovani Júnior wrote:
> Hi.
> 
>     I trying to write a transparent proxy program, but I having 
> trouble to retrieve the original destination address of the redirected 
> connections.
>         SLen = sizeof(peer);
>         memset(&peer, 0, SLen);
>         getsockopt(new_sock, SOL_IP, SO_ORIGINAL_DST, &peer, &SLen);
>         printf( "Client: %s:%hu\nMe: %s:%hu\nPeer: %s:%hu\n",
>                 inet_ntoa(client.sin_addr), ntohs(client.sin_port),
>                 inet_ntoa(me.sin_addr), ntohs(me.sin_port),
>                 inet_ntoa(peer.sin_addr), ntohs(peer.sin_port) );

inet_ntoa() uses a static buffer to format its result, you are calling
inet_ntoa three times which all work on the same buffer -> the result of the
last invocation will be used three times.

try writing 3 printf() statements, or copy the result of inet_ntoa() to a
private buffer, or create your own inet_ntoa() function.

-- 
Bazsi
PGP info: KeyID 9AF8D0A9 Fingerprint CD27 CFB0 802C 0944 9CFD 804E C82C 8EB1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Problem using REDIRECT and SO_ORIGINAL_DST
@ 2002-11-07 17:49 Wilson Padovani Júnior
  0 siblings, 0 replies; 3+ messages in thread
From: Wilson Padovani Júnior @ 2002-11-07 17:49 UTC (permalink / raw)
  To: netfilter-devel

Balazs Scheidler wrote:
>
> inet_ntoa() uses a static buffer to format its result, you are calling
> inet_ntoa three times which all work on the same buffer -> the result of 
the
> last invocation will be used three times.
>
> try writing 3 printf() statements, or copy the result of inet_ntoa() 
to a
> private buffer, or create your own inet_ntoa() function.
>
> --
> Bazsi
> PGP info: KeyID 9AF8D0A9 Fingerprint CD27 CFB0 802C 0944 9CFD 804E 
C82C 8EB1

Thanks Bazsi.

    I changed the code to use 3 printf() statements, as you said, and 
it worked. I was expecting an error on my program, but not something 
stupid like that!!

Wilson.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2002-11-07 17:49 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-11-07 17:49 Problem using REDIRECT and SO_ORIGINAL_DST Wilson Padovani Júnior
  -- strict thread matches above, loose matches on Subject: below --
2002-11-06 15:22 Wilson Padovani Júnior
2002-11-06 19:06 ` Balazs Scheidler

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.