/** * Filename: main.go * Description: the PortForward main entry point * It supports tcp/udp protocol layer traffic forwarding, forward/reverse * creation of forwarding links, and multi-level cascading use. * Author: knownsec404 * Time: 2020.09.02 */ package main import ( "errors" "fmt" "os" "strings" ) const VERSION string = "version: 0.5.0(build-20201022)" // C:\Users\wdd\go\bin\gox.exe -osarch="linux/amd64" -output "build/port_forward_{{.OS}}_{{.Arch}}" /********************************************************************** * @Function: main() * @Description: the PortForward entry point, parse command-line argument * @Parameter: nil * @Return: nil **********************************************************************/ func main() { if len(os.Args) != 4 { usage() return } proto := os.Args[1] sock1 := os.Args[2] sock2 := os.Args[3] // parse and check argument protocol := PORTFORWARD_PROTO_TCP if strings.ToUpper(proto) == "TCP" { protocol = PORTFORWARD_PROTO_TCP } else if strings.ToUpper(proto) == "UDP" { protocol = PORTFORWARD_PROTO_UDP } else { fmt.Printf("unknown protocol [%s]\n", proto) return } m1, a1, err := parseSock(sock1) if err != nil { fmt.Println(err) return } m2, a2, err := parseSock(sock2) if err != nil { fmt.Println(err) return } // launch args := Args{ Protocol: protocol, Method1: m1, Addr1: a1, Method2: m2, Addr2: a2, } Launch(args) } /********************************************************************** * @Function: parseSock(sock string) (uint8, string, error) * @Description: parse and check sock string * @Parameter: sock string, the sock string from command-line * @Return: (uint8, string, error), the method, address and error **********************************************************************/ func parseSock(sock string) (uint8, string, error) { // split "method" and "address" items := strings.SplitN(sock, ":", 2) if len(items) != 2 { return PORTFORWARD_SOCK_NIL, "", errors.New("host format must [method:address:port]") } method := items[0] address := items[1] // check the method field if strings.ToUpper(method) == "LISTEN" { return PORTFORWARD_SOCK_LISTEN, address, nil } else if strings.ToUpper(method) == "CONN" { return PORTFORWARD_SOCK_CONN, address, nil } else { errmsg := fmt.Sprintf("unknown method [%s]", method) return PORTFORWARD_SOCK_NIL, "", errors.New(errmsg) } } /********************************************************************** * @Function: usage() * @Description: the PortForward usage * @Parameter: nil * @Return: nil **********************************************************************/ func usage() { fmt.Println("Usage:") fmt.Println(" ./portforward [proto] [sock1] [sock2]") fmt.Println("Option:") fmt.Println(" proto the port forward with protocol(tcp/udp)") fmt.Println(" sock format: [method:address:port]") fmt.Println(" method the sock mode(listen/conn)") fmt.Println("Example:") fmt.Println(" tcp conn:192.168.1.1:3389 conn:192.168.1.10:23333") fmt.Println(" udp listen:192.168.1.3:5353 conn:8.8.8.8:53") fmt.Println(" tcp listen:[fe80::1%lo0]:8888 conn:[fe80::1%lo0]:7777") fmt.Println() fmt.Println(VERSION) }