Skip to content

Commit 6903304

Browse files
author
coolrc136
authored
Merge pull request #20 from LinuxHub-Group/revert-19-directory-structure
Revert "Divide code into packages; Use hosts+index to improve perform…
2 parents 8cf38b1 + 2f07683 commit 6903304

8 files changed

Lines changed: 170 additions & 200 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Binaries for programs and plugins
2-
/lmap
2+
lmap
33
*.exe
44
*.exe~
55
*.dll

Makefile

Lines changed: 0 additions & 3 deletions
This file was deleted.

cmd/lmap/main.go

Lines changed: 0 additions & 20 deletions
This file was deleted.

lib/lmap/checkIP.go

Lines changed: 0 additions & 66 deletions
This file was deleted.

lib/lmap/common.go

Lines changed: 0 additions & 9 deletions
This file was deleted.

lib/lmap/parseSubnet.go

Lines changed: 0 additions & 38 deletions
This file was deleted.

lib/lmap/ping.go

Lines changed: 0 additions & 63 deletions
This file was deleted.

lmap.go

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"encoding/binary"
6+
"flag"
7+
"fmt"
8+
"log"
9+
"net"
10+
"os"
11+
"sort"
12+
"sync"
13+
"sync/atomic"
14+
"time"
15+
)
16+
17+
type ICMP struct {
18+
Type uint8
19+
Code uint8
20+
Checksum uint16
21+
Identifier uint16
22+
SequenceNum uint16
23+
}
24+
25+
func main() {
26+
isVerbose := false
27+
flag.BoolVar(&isVerbose, "v", false, "be verbose")
28+
flag.Parse()
29+
args := flag.Args()
30+
if len(args) < 1 {
31+
fmt.Printf("使用方法:%s [-v] <网络号>/<CIDR>\n", os.Args[0])
32+
os.Exit(-1)
33+
}
34+
CheckIP(args[0], isVerbose)
35+
}
36+
37+
func CheckIP(subnet string, isVerbose bool) {
38+
checkerGroup := &sync.WaitGroup{}
39+
t := time.Now()
40+
hosts, _ := getAllHostsFromCIDR(subnet)
41+
usedIP := make([]string, len(hosts))
42+
unusedIP := make([]string, len(hosts))
43+
var (
44+
usedIndex int64 = 0
45+
unusedIndex int64 = 0
46+
)
47+
for _, ip := range hosts {
48+
time.Sleep(500)
49+
checkerGroup.Add(1)
50+
go func(data string) {
51+
defer checkerGroup.Done()
52+
isUsed := ping(data)
53+
if isUsed {
54+
old := atomic.LoadInt64(&usedIndex)
55+
for !atomic.CompareAndSwapInt64(&usedIndex, old, old+1) {
56+
old = atomic.LoadInt64(&usedIndex)
57+
}
58+
usedIP[old] = data
59+
if isVerbose {
60+
fmt.Println("已使用IP:", data)
61+
}
62+
} else {
63+
old := atomic.LoadInt64(&unusedIndex)
64+
for !atomic.CompareAndSwapInt64(&unusedIndex, old, old+1) {
65+
old = atomic.LoadInt64(&unusedIndex)
66+
}
67+
unusedIP[old] = data
68+
if isVerbose {
69+
fmt.Println("未使用IP:", data)
70+
}
71+
}
72+
}(ip)
73+
}
74+
checkerGroup.Wait()
75+
elapsed := time.Since(t)
76+
fmt.Println("IP扫描完成,耗时", elapsed)
77+
fmt.Println("已使用IP:", sortIPList(usedIP[:usedIndex]))
78+
fmt.Println("未使用IP:", sortIPList(unusedIP[:unusedIndex]))
79+
}
80+
81+
func sortIPList(ipStrings []string) (result []string) {
82+
var ips []net.IP
83+
for _, ipString := range ipStrings {
84+
ips = append(ips, net.ParseIP(ipString))
85+
}
86+
sort.Slice(ips, func(i, j int) bool {
87+
return bytes.Compare(ips[i], ips[j]) < 0
88+
})
89+
for _, ip := range ips {
90+
result = append(result, ip.String())
91+
}
92+
return
93+
}
94+
95+
func getAllHostsFromCIDR(cidr string) ([]string, error) {
96+
ip, ipnet, err := net.ParseCIDR(cidr)
97+
if err != nil {
98+
return nil, err
99+
}
100+
101+
var ips []string
102+
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
103+
ips = append(ips, ip.String())
104+
}
105+
return ips[1 : len(ips)-1], nil
106+
}
107+
108+
func inc(ip net.IP) {
109+
for j := len(ip) - 1; j >= 0; j-- {
110+
ip[j]++
111+
if ip[j] > 0 {
112+
break
113+
}
114+
}
115+
}
116+
117+
func ping(ip string) bool {
118+
var icmp ICMP
119+
//开始填充数据包
120+
icmp.Type = 8 //8->echo message 0->reply message
121+
122+
recvBuf := make([]byte, 32)
123+
var buffer bytes.Buffer
124+
125+
//先在buffer中写入icmp数据报求去校验和
126+
binary.Write(&buffer, binary.BigEndian, icmp)
127+
icmp.Checksum = CheckSum(buffer.Bytes())
128+
//然后清空buffer并把求完校验和的icmp数据报写入其中准备发送
129+
buffer.Reset()
130+
binary.Write(&buffer, binary.BigEndian, icmp)
131+
132+
conn, err := net.DialTimeout("ip4:icmp", ip, 1*time.Second)
133+
if err != nil {
134+
return false
135+
}
136+
_, err = conn.Write(buffer.Bytes())
137+
if err != nil {
138+
log.Println("conn.Write error:", err)
139+
return false
140+
}
141+
conn.SetReadDeadline(time.Now().Add(time.Second * 2))
142+
num, err := conn.Read(recvBuf)
143+
if err != nil {
144+
return false
145+
}
146+
147+
conn.SetReadDeadline(time.Time{})
148+
149+
return string(recvBuf[0:num]) != ""
150+
}
151+
152+
func CheckSum(data []byte) uint16 {
153+
var (
154+
sum uint32
155+
length int = len(data)
156+
index int
157+
)
158+
for length > 1 {
159+
sum += uint32(data[index])<<8 + uint32(data[index+1])
160+
index += 2
161+
length -= 2
162+
}
163+
if length > 0 {
164+
sum += uint32(data[index])
165+
}
166+
sum += (sum >> 16)
167+
168+
return uint16(^sum)
169+
}

0 commit comments

Comments
 (0)