IterateCIDR 迭代CIDR网段中的所有IP地址
(cidr string)
| 253 | |
| 254 | // IterateCIDR 迭代CIDR网段中的所有IP地址 |
| 255 | func IterateCIDR(cidr string) <-chan Host { |
| 256 | hostChan := make(chan Host, 100) |
| 257 | |
| 258 | go func() { |
| 259 | defer close(hostChan) |
| 260 | |
| 261 | // 解析CIDR |
| 262 | _, ipNet, err := net.ParseCIDR(cidr) |
| 263 | if err != nil { |
| 264 | printError(fmt.Sprintf("解析CIDR失败: %s - %v", cidr, err)) |
| 265 | return |
| 266 | } |
| 267 | |
| 268 | count := 0 |
| 269 | maxHosts := 65536 // 限制最大主机数,防止内存溢出 |
| 270 | |
| 271 | // 获取网络地址和掩码 |
| 272 | ip := make(net.IP, len(ipNet.IP)) |
| 273 | copy(ip, ipNet.IP) |
| 274 | |
| 275 | // 计算网络中的主机数 |
| 276 | ones, bits := ipNet.Mask.Size() |
| 277 | if bits-ones > 16 { // 如果主机位超过16位,限制扫描范围 |
| 278 | printError(fmt.Sprintf("CIDR %s 包含的主机数过多,已限制为前%d个", cidr, maxHosts)) |
| 279 | } |
| 280 | |
| 281 | // 遍历网络中的所有IP |
| 282 | for { |
| 283 | if !ipNet.Contains(ip) { |
| 284 | break |
| 285 | } |
| 286 | |
| 287 | if count >= maxHosts { |
| 288 | printError(fmt.Sprintf("CIDR %s 包含的主机数超过限制(%d),已截断", cidr, maxHosts)) |
| 289 | break |
| 290 | } |
| 291 | |
| 292 | // 创建新的Host并发送到channel |
| 293 | newHost := Host{ |
| 294 | IP: make(net.IP, len(ip)), |
| 295 | Origin: cidr, |
| 296 | Type: HostTypeIP, |
| 297 | } |
| 298 | copy(newHost.IP, ip) |
| 299 | hostChan <- newHost |
| 300 | |
| 301 | // 递增IP地址 |
| 302 | ip = NextIP(ip, true) |
| 303 | count++ |
| 304 | } |
| 305 | |
| 306 | if config.Verbose { |
| 307 | printInfo(fmt.Sprintf("CIDR %s 展开为 %d 个IP地址", cidr, count)) |
| 308 | } |
| 309 | }() |
| 310 | |
| 311 | return hostChan |
| 312 | } |
no test coverage detected