-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.go
163 lines (131 loc) · 3.54 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
*/
package main
import (
"flag"
"fmt"
"net"
"os"
"strconv"
"strings"
)
var host, port, ip, t1, t2 string
var verbose bool
func main() {
flag.StringVar(&t1, "t1", "", "Single ip to test. Also needs -t2")
flag.StringVar(&t2, "t2", "", "Single ip to test. Also needs -t1")
flag.StringVar(&host, "h", "", "DNS host to query for addresses")
flag.StringVar(&port, "p", "", "Port encode")
flag.StringVar(&ip, "i", "", "Real ip to encode")
flag.BoolVar(&verbose, "v", false, "Display additional information")
flag.Parse()
if host != "" && ip != "" {
fmt.Printf("Please only select a host with -h OR an ip address with -i\n")
}
if t1 != "" && t2 == "" {
fmt.Printf("Please enter both -t1 and -t2 at the same time\n")
}
if t2 != "" && t1 == "" {
fmt.Printf("Please enter both -t1 and -t2 at the same time\n")
}
// convert an ip & port to real & encoded addresses
if ip != "" {
encodeip(ip, port)
}
// pull ip addresses from dns server and decode them
if host != "" {
var lookuphost string
if x := strings.HasPrefix(host, "nonstd."); x == false {
lookuphost = "nonstd." + host
} else {
lookuphost = host
}
ips, err := net.LookupHost(lookuphost)
if err != nil {
fmt.Printf("Error - unable to lookup addresses from %s %v\n", host, err)
}
decodeips(ips)
}
if t1 != "" && t2 != "" {
ips := []string{t1, t2}
decodeips(ips)
}
fmt.Printf("\nProgram exiting. Bye\n")
}
// decideips receives a slice of ip addresses and displays information
// about the ip addresses and ports encoded in them
func decodeips(ips []string) {
var match bool
if verbose && host != "" {
fmt.Printf("Received %v addresses from %s\n", len(ips), host)
}
for _, ip := range ips {
netip := net.ParseIP(ip)
netip = netip.To4()
if netip == nil {
continue
}
crcAddr := crc16(netip)
match = false
for _, ipport := range ips {
netipport := net.ParseIP(ipport)
netipport = netipport.To4()
if netipport == nil {
continue
}
if (netipport[0] == byte(crcAddr>>8)) && (netipport[1] == byte(crcAddr&0xff)) {
theport := (uint16(netipport[2]) << 8) + uint16(netipport[3])
fmt.Printf("realip: %s\tport: %v\tencodedip: %s\n", ip, theport, ipport)
if verbose {
fmt.Printf("crcAddr: 0x%x encoded bytes: 0x%x 0x%x 0x%x 0x%x\n", crcAddr, netipport[0], netipport[1], netipport[2], netipport[3])
}
match = true
}
}
if match == false && verbose {
fmt.Printf("No match found for ip: %s\n", ip)
}
}
}
// encodeip takes an ip address and port strings and displays the encoded
// ip address they would use
func encodeip(ip, port string) {
var netport int
if port != "" {
netport, _ = strconv.Atoi(port)
}
netip := net.ParseIP(ip)
netip = netip.To4()
if netip == nil {
fmt.Printf("error changing ip: %s to 4 bytes storage\n", ip)
os.Exit(0)
}
crcAddr := crc16(netip)
bs := make([]byte, 4)
bs[0] = byte(crcAddr >> 8)
bs[1] = byte(crcAddr & 0xff)
bs[2] = byte(netport >> 8)
bs[3] = byte(netport & 0xff)
encodedip := net.IPv4(bs[0], bs[1], bs[2], bs[3])
if x := encodedip.To4(); x == nil {
fmt.Printf("Error checking encoded ip to real ip\n")
fmt.Printf("Real ip: \t%s\n", ip)
fmt.Printf("Encoded ip:\t%v.%v.%v.%v\n", bs[0], bs[1], bs[2], bs[3])
} else {
fmt.Printf("crcAddr:\t%#v\n", crcAddr)
fmt.Printf("Real ip: \t%s\n", ip)
fmt.Printf("Encoded ip:\t%s\n", encodedip.String())
}
}
func crc16(bs []byte) uint16 {
var x, crc uint16
crc = 0xffff
for _, v := range bs {
x = crc>>8 ^ uint16(v)
x ^= x >> 4
crc = (crc << 8) ^ (x << 12) ^ (x << 5) ^ x
}
return crc
}
/*
*/