add
This commit is contained in:
parent
eb1fe01a48
commit
70e47f3757
12
cmd/main.go
12
cmd/main.go
@ -9,9 +9,9 @@ import (
|
|||||||
var usage = `
|
var usage = `
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
pingtunnel -t server -l SERVER_IP:4455 -t TARGET_IP:443
|
pingtunnel -type server -t TARGET_IP:4455
|
||||||
|
|
||||||
pingtunnel -t client -l LOCAL_IP:4455 -t SERVER_IP:4455
|
pingtunnel -type client -l LOCAL_IP:4455 -t SERVER_IP
|
||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
@ -37,21 +37,21 @@ func main() {
|
|||||||
fmt.Printf("target %s\n", *target)
|
fmt.Printf("target %s\n", *target)
|
||||||
|
|
||||||
if *t == "server" {
|
if *t == "server" {
|
||||||
s, err := pingtunnel.NewPingTunnelServer(*listen, *target)
|
s, err := pingtunnel.NewServer(*target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: %s\n", err.Error())
|
fmt.Printf("ERROR: %s\n", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Printf("Server Listen %s (%s) Target %s (%s):\n", s.Addr(), s.IPAddr(), s.TargetAddr(), s.TargetIPAddr())
|
fmt.Printf("Server Target %s (%s):\n", s.TargetAddr(), s.TargetIPAddr())
|
||||||
s.Run()
|
s.Run()
|
||||||
}
|
}
|
||||||
if *t == "client" {
|
if *t == "client" {
|
||||||
c, err := pingtunnel.NewPingTunnelClient(*listen, *target)
|
c, err := pingtunnel.NewClient(*listen, *target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: %s\n", err.Error())
|
fmt.Printf("ERROR: %s\n", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.Run()
|
|
||||||
fmt.Printf("Client Listen %s (%s) Target %s (%s):\n", c.Addr(), c.IPAddr(), c.TargetAddr(), c.TargetIPAddr())
|
fmt.Printf("Client Listen %s (%s) Target %s (%s):\n", c.Addr(), c.IPAddr(), c.TargetAddr(), c.TargetIPAddr())
|
||||||
|
c.Run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
146
src/pingtunnel/client.go
Normal file
146
src/pingtunnel/client.go
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
package pingtunnel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"golang.org/x/net/icmp"
|
||||||
|
"golang.org/x/net/ipv4"
|
||||||
|
"net"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewClient(addr string, target string) (*Client, error) {
|
||||||
|
|
||||||
|
ipaddr, err := net.ResolveTCPAddr("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ipaddrTarget, err := net.ResolveIPAddr("ip", target)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Client{
|
||||||
|
ipaddr: ipaddr,
|
||||||
|
addr: addr,
|
||||||
|
ipaddrTarget: ipaddrTarget,
|
||||||
|
addrTarget: target,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
ipaddr *net.TCPAddr
|
||||||
|
addr string
|
||||||
|
|
||||||
|
ipaddrTarget *net.IPAddr
|
||||||
|
addrTarget string
|
||||||
|
|
||||||
|
conn *icmp.PacketConn
|
||||||
|
listenConn *net.TCPListener
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Client) Addr() string {
|
||||||
|
return p.addr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Client) IPAddr() *net.TCPAddr {
|
||||||
|
return p.ipaddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Client) TargetAddr() string {
|
||||||
|
return p.addrTarget
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Client) TargetIPAddr() *net.IPAddr {
|
||||||
|
return p.ipaddrTarget
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Client) Run() {
|
||||||
|
|
||||||
|
conn, err := icmp.ListenPacket("ip4:icmp", "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error listening for ICMP packets: %s\n", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
p.conn = conn
|
||||||
|
|
||||||
|
listener, err := net.ListenTCP("tcp", p.ipaddr)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error listening for tcp packets: %s\n", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.listenConn = listener
|
||||||
|
|
||||||
|
p.Accept()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Client) Accept() error {
|
||||||
|
|
||||||
|
fmt.Println("client waiting local accept")
|
||||||
|
|
||||||
|
for {
|
||||||
|
localConn, err := p.listenConn.AcceptTCP()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
localConn.SetLinger(0)
|
||||||
|
go p.handleConn(*localConn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Client) handleConn(conn net.TCPConn) {
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
uuid := UniqueId()
|
||||||
|
|
||||||
|
fmt.Printf("client new conn %s %s", conn.RemoteAddr().String(), uuid)
|
||||||
|
|
||||||
|
data, err := json.Marshal(RegisterData{localaddr: conn.RemoteAddr().String()})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Unable to marshal data %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
p.sendICMP(uuid, REGISTER, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Client) sendICMP(connId string, msgType MSGID, data []byte) error {
|
||||||
|
|
||||||
|
body := &Msg{
|
||||||
|
ID: connId,
|
||||||
|
TYPE: (int)(msgType),
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := &icmp.Message{
|
||||||
|
Type: ipv4.ICMPTypeExtendedEchoRequest,
|
||||||
|
Code: 0,
|
||||||
|
Body: body,
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := msg.Marshal(nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
if _, err := (*p.conn).WriteTo(bytes, p.ipaddrTarget); err != nil {
|
||||||
|
if neterr, ok := err.(*net.OpError); ok {
|
||||||
|
if neterr.Err == syscall.ENOBUFS {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Printf("sendICMP error %s %s\n", p.ipaddrTarget.String(), err)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,230 +1,24 @@
|
|||||||
package pingtunnel
|
package pingtunnel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"encoding/hex"
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
"net"
|
"io"
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewPingTunnelServer(addr string, target string) (*PingTunnelServer, error) {
|
type MSGID int
|
||||||
|
|
||||||
ipaddr, err := net.ResolveTCPAddr("tcp", addr)
|
const (
|
||||||
if err != nil {
|
REGISTER MSGID = 1
|
||||||
return nil, err
|
)
|
||||||
}
|
|
||||||
|
|
||||||
ipaddrTarget, err := net.ResolveTCPAddr("tcp", target)
|
const (
|
||||||
if err != nil {
|
protocolICMP = 1
|
||||||
return nil, err
|
)
|
||||||
}
|
|
||||||
|
|
||||||
return &PingTunnelServer{
|
|
||||||
ipaddr: ipaddr,
|
|
||||||
addr: addr,
|
|
||||||
ipaddrTarget: ipaddrTarget,
|
|
||||||
addrTarget: target,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPingTunnelClient(addr string, target string) (*PingTunnelClient, error) {
|
|
||||||
|
|
||||||
ipaddr, err := net.ResolveTCPAddr("tcp", addr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ipaddrTarget, err := net.ResolveTCPAddr("tcp", target)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &PingTunnelClient{
|
|
||||||
ipaddr: ipaddr,
|
|
||||||
addr: addr,
|
|
||||||
ipaddrTarget: ipaddrTarget,
|
|
||||||
addrTarget: target,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type PingTunnelClient struct {
|
|
||||||
ipaddr *net.TCPAddr
|
|
||||||
addr string
|
|
||||||
|
|
||||||
ipaddrTarget *net.IPAddr
|
|
||||||
addrTarget string
|
|
||||||
|
|
||||||
conn *icmp.PacketConn
|
|
||||||
listenConn *net.TCPListener
|
|
||||||
}
|
|
||||||
|
|
||||||
type PingTunnelServer struct {
|
|
||||||
ipaddr *net.TCPAddr
|
|
||||||
addr string
|
|
||||||
|
|
||||||
ipaddrTarget *net.TCPAddr
|
|
||||||
addrTarget string
|
|
||||||
|
|
||||||
conn net.PacketConn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelServer) Addr() string {
|
|
||||||
return p.addr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelServer) IPAddr() *net.TCPAddr {
|
|
||||||
return p.ipaddr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelServer) TargetAddr() string {
|
|
||||||
return p.addrTarget
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelServer) TargetIPAddr() *net.TCPAddr {
|
|
||||||
return p.ipaddrTarget
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelClient) Addr() string {
|
|
||||||
return p.addr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelClient) IPAddr() *net.TCPAddr {
|
|
||||||
return p.ipaddr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelClient) TargetAddr() string {
|
|
||||||
return p.addrTarget
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelClient) TargetIPAddr() *net.IPAddr {
|
|
||||||
return p.ipaddrTarget
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelServer) Run() {
|
|
||||||
conn, err := icmp.ListenPacket("ip4:icmp", "")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error listening for ICMP packets: %s\n", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
p.conn = conn
|
|
||||||
|
|
||||||
p.Recv()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelClient) Run() {
|
|
||||||
|
|
||||||
conn, err := icmp.ListenPacket("ip4:icmp", "")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error listening for ICMP packets: %s\n", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.conn = conn
|
|
||||||
|
|
||||||
ipaddrTarget, err := net.ResolveIPAddr("ip", p.addrTarget)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.ipaddrTarget = ipaddrTarget
|
|
||||||
|
|
||||||
ipAddr, err := net.ResolveTCPAddr("tcp", p.addr)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error listening for Local packets: %s\n", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.ipaddr = ipAddr
|
|
||||||
|
|
||||||
listener, err := net.ListenTCP("tcp", p.ipaddr)
|
|
||||||
|
|
||||||
p.listenConn = listener
|
|
||||||
|
|
||||||
go p.Accept()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelClient) Accept() error {
|
|
||||||
|
|
||||||
for {
|
|
||||||
localConn, err := p.listenConn.AcceptTCP()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
localConn.SetLinger(0)
|
|
||||||
go p.handleConn(*localConn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelClient) handleConn(conn net.TCPConn) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelClient) sendICMP(connId int, msgType int, data []byte) error {
|
|
||||||
|
|
||||||
body := &Msg{
|
|
||||||
ID: connId,
|
|
||||||
TYPE: msgType,
|
|
||||||
Data: data,
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := &icmp.Message{
|
|
||||||
Type: ipv4.ICMPTypeExtendedEchoRequest,
|
|
||||||
Code: 0,
|
|
||||||
Body: body,
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes, err := msg.Marshal(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
if _, err := p.conn.Write(bytes); err != nil {
|
|
||||||
if neterr, ok := err.(*net.OpError); ok {
|
|
||||||
if neterr.Err == syscall.ENOBUFS {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("send %d\n", id)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PingTunnelServer) Recv() error {
|
|
||||||
|
|
||||||
for {
|
|
||||||
bytes := make([]byte, 512)
|
|
||||||
p.conn.SetReadDeadline(time.Now().Add(time.Millisecond * 100))
|
|
||||||
n, srcaddr, err := p.conn.ReadFrom(bytes)
|
|
||||||
if err != nil {
|
|
||||||
if neterr, ok := err.(*net.OpError); ok {
|
|
||||||
if neterr.Timeout() {
|
|
||||||
// Read timeout
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sbytes []byte
|
|
||||||
sbytes = ipv4Payload(bytes)
|
|
||||||
|
|
||||||
var m *icmp.Message
|
|
||||||
if m, err = icmp.ParseMessage(1, sbytes[:n]); err != nil {
|
|
||||||
return fmt.Errorf("Error parsing icmp message")
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("%d %d %d %s \n", m.Type, m.Code, n, srcaddr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv4Payload(b []byte) []byte {
|
func ipv4Payload(b []byte) []byte {
|
||||||
if len(b) < ipv4.HeaderLen {
|
if len(b) < ipv4.HeaderLen {
|
||||||
@ -235,8 +29,8 @@ func ipv4Payload(b []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Msg struct {
|
type Msg struct {
|
||||||
ID int // identifier
|
|
||||||
TYPE int
|
TYPE int
|
||||||
|
ID string // identifier
|
||||||
Data []byte // data
|
Data []byte // data
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,23 +38,32 @@ func (p *Msg) Len(proto int) int {
|
|||||||
if p == nil {
|
if p == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return 8 + len(p.Data)
|
return 4 + 32 + len(p.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Msg) Marshal(proto int) ([]byte, error) {
|
func (p *Msg) Marshal(proto int) ([]byte, error) {
|
||||||
b := make([]byte, 8+len(p.Data))
|
b := make([]byte, p.Len(proto))
|
||||||
binary.BigEndian.PutUint32(b, uint32(p.ID))
|
|
||||||
binary.BigEndian.PutUint32(b, uint32(p.TYPE))
|
binary.BigEndian.PutUint32(b, uint32(p.TYPE))
|
||||||
copy(b[8:], p.Data)
|
copy(b[4:], p.ID)
|
||||||
|
copy(b[4+32:], p.Data)
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PingTunnelServer) listen(netProto string, source string) *icmp.PacketConn {
|
func UniqueId() string {
|
||||||
|
b := make([]byte, 48)
|
||||||
|
|
||||||
conn, err := icmp.ListenPacket(netProto, source)
|
if _, err := io.ReadFull(rand.Reader, b); err != nil {
|
||||||
if err != nil {
|
return ""
|
||||||
fmt.Printf("Error listening for ICMP packets: %s\n", err.Error())
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
return conn
|
return GetMd5String(base64.URLEncoding.EncodeToString(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMd5String(s string) string {
|
||||||
|
h := md5.New()
|
||||||
|
h.Write([]byte(s))
|
||||||
|
return hex.EncodeToString(h.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterData struct {
|
||||||
|
localaddr string
|
||||||
}
|
}
|
||||||
|
88
src/pingtunnel/server.go
Normal file
88
src/pingtunnel/server.go
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package pingtunnel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"golang.org/x/net/icmp"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewServer(target string) (*Server, error) {
|
||||||
|
|
||||||
|
ipaddrTarget, err := net.ResolveTCPAddr("tcp", target)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Server{
|
||||||
|
ipaddrTarget: ipaddrTarget,
|
||||||
|
addrTarget: target,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
ipaddrTarget *net.TCPAddr
|
||||||
|
addrTarget string
|
||||||
|
|
||||||
|
conn net.PacketConn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Server) TargetAddr() string {
|
||||||
|
return p.addrTarget
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Server) TargetIPAddr() *net.TCPAddr {
|
||||||
|
return p.ipaddrTarget
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Server) Run() {
|
||||||
|
|
||||||
|
conn, err := icmp.ListenPacket("ip4:icmp", "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error listening for ICMP packets: %s\n", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.conn = conn
|
||||||
|
|
||||||
|
p.Recv()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Server) Recv() error {
|
||||||
|
|
||||||
|
for {
|
||||||
|
bytes := make([]byte, 512)
|
||||||
|
p.conn.SetReadDeadline(time.Now().Add(time.Millisecond * 100))
|
||||||
|
n, srcaddr, err := p.conn.ReadFrom(bytes)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if neterr, ok := err.(*net.OpError); ok {
|
||||||
|
if neterr.Timeout() {
|
||||||
|
// Read timeout
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes1 := ipv4Payload(bytes)
|
||||||
|
|
||||||
|
var m *icmp.Message
|
||||||
|
if m, err = icmp.ParseMessage(protocolICMP, bytes1[:n]); err != nil {
|
||||||
|
fmt.Println("Error parsing icmp message")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%d %d %d %s \n", m.Type, m.Code, n, srcaddr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Server) listen(netProto string, source string) *icmp.PacketConn {
|
||||||
|
|
||||||
|
conn, err := icmp.ListenPacket(netProto, source)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error listening for ICMP packets: %s\n", err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return conn
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user