标题 简介 类型 公开时间
关联规则 关联知识 关联工具 关联文档 关联抓包
参考1(官网)
参考2
参考3
详情
[SAFE-ID: JIWO-2024-476]   作者: ecawen 发表于: [2017-08-27]

本文共 [457] 位读者顶过

After a colleague with a PhD in Networking and myself spent the best part of a day trying to NAT UDP syslog packets without success (the Destination-NAT half is fine, but Source-NAT eludes: the external system still sees the internal IP), I decided to change tack and solve the problem by handling packets in user-space. [出自:jiwo.org]

The code at http://www.brokestream.com/udp_redirect.html works, but two instances need to be chained together via an intermediate port if the source port as seen by the external system needs to differ from that of the proxy host.

With that in mind, I updated the code as follows:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
 
  Build: gcc -o udp_redirect udp_redirect.c
 
  udp_redirect.c
  Version 2013-05-30
 
  Copyright (C) 2007 Ivan Tikhonov
  Copyright (C) 2013 Stuart Shelton, HP Autonomy
 
  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.
 
  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:
 
  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
 
  Ivan Tikhonov, kefeer@brokestream.com
 
  This source has been modified to support sending data to the destination
  IP address from a different source-ip to the listen-ip, to enable proxying
  on multi-homed hosts
 
  Stuart Shelton, stuart.shelton@hp.com
 
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
 
intbindsocket(char* ip,intport );
intmain(intargc,char* argv[] );
 
intbindsocket(char* ip,intport ) {
    intfd;
    structsockaddr_in addr;
 
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr( ip );
    addr.sin_port = htons( port );
 
    fd = socket( PF_INET, SOCK_DGRAM, IPPROTO_IP );
    if( -1 == bind( fd, (structsockaddr*)&addr,sizeof( addr ) ) ) {
        fprintf( stderr,"Cannot bind address (%s:%d)\n", ip, port );
        exit( 1 );
    }
 
    returnfd;
}
 
intmain(intargc,char* argv[] ) {
    inti, listen, output;
    char*inip, *inpt, *srcip, *dstip, *dstpt;
    structsockaddr_in src;
    structsockaddr_in dst;
    structsockaddr_in ret;
 
    if( 3 != argc && 5 != argc && 6 != argc ) {
        fprintf( stderr,"Usage: %s <listen-ip> <listen-port> [[source-ip] <destination-ip> <destination-port>]\n", argv[ 0 ] );
        exit( 1 );
    }
 
    i = 1;
    inip = argv[ i++ ];    /* 1 */
    inpt = argv[ i++ ];    /* 2 */
    if( 6 == argc )
        srcip = argv[ i++ ];   /* 3 */
    if( 3 != argc ) {
        dstip = argv[ i++ ];   /* 3 or 4 */
        dstpt = argv[ i++ ];   /* 4 or 5 */
    }
     
    listen = bindsocket( inip,atoi( inpt ) );
    if( 6 == argc ) {
        output = bindsocket( srcip,atoi( inpt ) );
    }else{
        output = listen;
    }
 
    if( 3 != argc ) {
        dst.sin_family = AF_INET;
        dst.sin_addr.s_addr = inet_addr( dstip );
        dst.sin_port = htons(atoi( dstpt ) );
    }
    ret.sin_addr.s_addr = 0;
 
    while( 1 ) {
        charbuffer[65535];
        unsignedintsize =sizeof( src );
        intlength = recvfrom( listen, buffer,sizeof( buffer ), 0, (structsockaddr*)&src, &size );
        if( length <= 0 )
            continue;
 
        if( 3 == argc ) {
            /* echo, without tracking return packets */
            sendto( listen, buffer, length, 0, (structsockaddr*)&src, size );
        }elseif( ( src.sin_addr.s_addr == dst.sin_addr.s_addr ) && ( src.sin_port == dst.sin_port ) ) {
            /* If we receive a return packet back from our destination ... */
            if( ret.sin_addr.s_addr )
                /* ... and we've previously remembered having sent packets to this location,
                   then return them to the original sender */
                sendto( output, buffer, length, 0, (structsockaddr*)&ret,sizeof( ret ) );
        }else{
            sendto( output, buffer, length, 0, (structsockaddr*)&dst,sizeof( dst ) );
            /* Remeber original sender to direct return packets towards */
            ret = src;
        }
    }
}

The above source can be downloaded from http://files.stuart.shelton.me/unix/udp-proxy.c.

评论

暂无
发表评论
 返回顶部 
热度(457)
 关注微信