用Go开发可以内网活跃主机嗅探器

timest · · 1422 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。
## 文章关键词 * go/golang * gopacket * 抓包 * pcap/libpcap * arp * nbns * mdns * manuf ## 程序截图 ![image.png](http://upload-images.jianshu.io/upload_images/6285600-cec041b47b5f7b1f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ## 说明 本文对于Go语言本身的讲解不会太多,想把更多的时间花在几个网络协议的讲解上,希望本文对打算或正在用Go进行TCP/IP编程和抓包的朋友带来帮助。 github地址:[https://github.com/timest/goscan](https://github.com/timest/goscan) ## 程序思路 * 通过内网IP和子网掩码计算出内网IP范围 * 向内网广播ARP Request * 监听并抓取ARP Response包,记录IP和Mac地址 * 发活跃IP发送MDNS和NBNS包,并监听和解析Hostname * 根据Mac地址计算出厂家信息 ## 通过内网IP和子网掩码计算出内网IP范围 如果仅仅只是知道一个IP地址,是无法得知内网IP的网段,不能只是简单的把本机IP的最后一个字节改成1-255。需要通过子网掩码来计算得出内网的网段,这块比较简单,这里不赘述了,有疑问的网上搜索子网掩码获取更多资料。值得一提的是IP地址的最后一个字段是不能为0和255,前者是RFC规定,后者一般是广播地址。 ```go // 单网卡模式 addrs, err := net.InterfaceAddrs() if err != nil { log.Fatal("无法获取本地网络信息:", err) } for i, a := range addrs { if ip, ok := a.(*net.IPNet); ok && !ip.IP.IsLoopback() { if ip.IP.To4() != nil { fmt.Println("IP:", ip.IP) fmt.Println("子网掩码:", ip.Mask) it, _ := net.InterfaceByIndex(i) fmt.Println("Mac地址:", it.HardwareAddr) break } } } ``` 根据上面得到的IPNet,可以算出内网IP范围: ```go type IP uint32 // 根据IP和mask换算内网IP范围 func Table(ipNet *net.IPNet) []IP { ip := ipNet.IP.To4() log.Info("本机ip:", ip) var min, max IP var data []IP for i := 0; i < 4; i++ { b := IP(ip[i] & ipNet.Mask[i]) min += b << ((3 - uint(i)) * 8) } one, _ := ipNet.Mask.Size() max = min | IP(math.Pow(2, float64(32 - one)) - 1) log.Infof("内网IP范围:%s --- %s", min, max) // max 是广播地址,忽略 // i & 0x000000ff == 0 是尾段为0的IP,根据RFC的规定,忽略 for i := min; i < max; i++ { if i & 0x000000ff == 0 { continue } data = append(data, i) } return data } ``` ## 向内网广播ARP Request > ARP(Address Resolution Protocol),地址解析协议,是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址 ------百度百科 当我们要向以太网中另一台主机发送IP数据时,我们本地会根据目的主机的IP地址在**ARP高速缓存**中查询相应的以太网地址,ARP高速缓存是主机维护的一个IP地址到相应以太网地址的**映射表**。如果查询失败,ARP会广播一个询问(op字段为1)目的主机硬件地址的报文,等待目标主机的响应。 因为ARP高速缓存有时效性,读取到目标主机的硬件地址后,最好发送一个ICMP包验证目标是否在线。当然也可以选择不从高速缓存里读取数据,而是直接并发发送arp包,等待在线主机回应ARP报文。 原文地址:[https://github.com/timest/goscan/issues/1](https://github.com/timest/goscan/issues/1)

入群交流(该群和以上内容无关):Go中文网 QQ交流群:731990104 或 加微信入微信群:274768166 备注:入群; 公众号:Go语言中文网

1422 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传