parent
86e39c2b23
commit
dba220995b
@ -0,0 +1,108 @@
|
||||
// +build linux,cgo
|
||||
|
||||
package obfssh
|
||||
|
||||
/*
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/if.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
int get_original_dst4(int fd, void *addr);
|
||||
int get_original_dst6(int fd, void *addr);
|
||||
|
||||
unsigned short _ntohs(unsigned short a);
|
||||
|
||||
int get_original_dst4(int fd, void *addr){
|
||||
int ret;
|
||||
int l = sizeof(struct sockaddr_in);
|
||||
ret = getsockopt(fd, SOL_IP, SO_ORIGINAL_DST,
|
||||
(struct sockaddr_in *)addr, &l);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int get_original_dst6(int fd, void *addr){
|
||||
int ret;
|
||||
int l = sizeof(struct sockaddr_in6);
|
||||
ret = getsockopt(fd, SOL_IPV6, IP6T_SO_ORIGINAL_DST,
|
||||
(struct sockaddr_in6 *)addr, &l);
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned short _ntohs(unsigned short a) {
|
||||
return ntohs(a);
|
||||
}
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
//"log"
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func getOriginDst(c net.Conn) (net.Addr, error) {
|
||||
var addr net.Addr
|
||||
var err error
|
||||
|
||||
if _, ok := c.(*net.TCPConn); !ok {
|
||||
return nil, fmt.Errorf("only tcp socket supported")
|
||||
}
|
||||
|
||||
ip := c.LocalAddr().(*net.TCPAddr).IP
|
||||
|
||||
if ip.To4() != nil { // ipv4
|
||||
addr, err = getOriginDst4(c)
|
||||
} else {
|
||||
addr, err = getOriginDst6(c)
|
||||
}
|
||||
return addr, err
|
||||
}
|
||||
|
||||
func getOriginDst4(c net.Conn) (net.Addr, error) {
|
||||
|
||||
c1 := c.(*net.TCPConn)
|
||||
|
||||
f, _ := c1.File()
|
||||
|
||||
defer f.Close()
|
||||
|
||||
var addr4 syscall.RawSockaddrInet4
|
||||
|
||||
ret := C.get_original_dst4(C.int(f.Fd()), unsafe.Pointer(&addr4))
|
||||
if int(ret) != 0 {
|
||||
return nil, fmt.Errorf("ipv4 getsockopt SO_ORIGINAL_DST return %v", int(ret))
|
||||
}
|
||||
|
||||
port := int(C._ntohs(C.ushort(addr4.Port)))
|
||||
ip := net.IP(addr4.Addr[0:])
|
||||
|
||||
return &net.TCPAddr{IP: ip, Port: port}, nil
|
||||
}
|
||||
|
||||
func getOriginDst6(c net.Conn) (net.Addr, error) {
|
||||
|
||||
c1 := c.(*net.TCPConn)
|
||||
|
||||
f, _ := c1.File()
|
||||
|
||||
defer f.Close()
|
||||
|
||||
var addr6 syscall.RawSockaddrInet6
|
||||
|
||||
ret := C.get_original_dst6(C.int(f.Fd()), unsafe.Pointer(&addr6))
|
||||
if int(ret) != 0 {
|
||||
return nil, fmt.Errorf("ipv6 getsockopt IP6T_ORIGINAL_DST return %v", int(ret))
|
||||
}
|
||||
|
||||
port := int(C._ntohs(C.ushort(addr6.Port)))
|
||||
ip := net.IP(addr6.Addr[0:])
|
||||
|
||||
return &net.TCPAddr{IP: ip, Port: port}, nil
|
||||
}
|
Loading…
Reference in New Issue