golang监听ip数据包的实现步骤(golang纯享版)

 更新时间:2024年02月25日 09:45:38   作者:docker真的爽爆了  
这篇文章主要给大家介绍了golang监听ip数据包的实现步骤,本文以ip4 作为案例进行包抓取示范,ip6抓取与ip4方式异曲同工,可自行举一反三得出,文中通过图文结合给大家介绍的非常详细,需要的朋友可以参考下

golang 监听ip数据包(golang纯享版)

【注】本机编译运行平台为linux,如需测试代码请移至linux平台进行代码测试

本文以ip4 作为案例进行包抓取示范,ip6抓取与ip4方式异曲同工,可自行举一反三得出

第一步,通过wireshark抓包拿到ip4下的tcp/udp包,通过wireshark可视化我们可以很容易找到我们需要的源/目的地址信息所在ip包字节数. 这里两张截图,一张ip4,一张ip6的

请添加图片描述

请添加图片描述

第二步,编写我们秘制的简易抓包工具,此处以直接输出来源和去向地址为例,自己可以根据需求做更改

package inet

import (
	"encoding/binary"
	"fmt"
	"strconv"
	"syscall"
	"unsafe"
)

func reverse(b []byte) {
	var (
		mid  uint8
		blen = len(b)
	)
	if blen > 1 {
		for i := 0; i < blen/2; i++ {
			mid = b[i]
			b[i] = b[blen-i-1]
			b[blen-i-1] = mid
		}
	}
}
//主机字节序变网络字节序
func Htons[T uint | uint16 | uint32 | uint64](t T) T {
	var (
		b   []byte = make([]byte, unsafe.Sizeof(t))
		ptr *T     = (*T)(unsafe.Pointer(&b[0]))
	)
	*ptr = t
	reverse(b)
	return *ptr
}

//ip包必选,ip6自行根据wireshark进行编写,此处ip4为例
type IPHeader struct {
	Version_And_Len        uint8//前4个bit为version(4 ip4,6 ip6),后bit个字节为首部length xxxx xxxx
	DiffernetialtedService uint8
	Tot_Len                uint16
	Id                     uint16
	Flag_And_Seek          uint16//前3bit 为flag后面13bit为seek
	TTL                    uint8
	Protocol               uint8
	CheckSum               uint16
	Source                 uint32
	Dest                   uint32
}
type PortInfo struct {
	Source uint16
	Dest   uint16
}

var (
	__IP_DEFAULT  IPHeader
	IPHEADER_SIZE = int(unsafe.Sizeof(__IP_DEFAULT))
)

func Watch(watcher func([]byte, int)) error {
  //socket af_packet 会抓取全部网卡的IP数据包,如需监听特定的网卡请自行判断
	fd, _, err_ := syscall.Syscall(syscall.SYS_SOCKET, syscall.AF_PACKET, syscall.SOCK_DGRAM, uintptr(Htons[uint16](syscall.ETH_P_IP)))
	if int(fd) < 0 {
		return err_
	}
	ifd := int(fd)
	var (
		buff []byte = make([]byte, 512)
		lang int
		err error
	)
	defer syscall.Close(ifd)
	fmt.Println("start watch raw stream", ifd)
	for {
		lang, _, err = syscall.Recvfrom(ifd, buff, 0)
		if lang <= 0 {
			break
		}
		watcher(buff, lang)
	}
	return err
}
//输出所有来源去向
func print_info(info []byte, size int) {
	if size <= IPHEADER_SIZE {
		return
	}
	var (
		ipheader *IPHeader = (*IPHeader)(unsafe.Pointer(&info[0]))
		portinfo *PortInfo
	)
	if size > IPHEADER_SIZE+4 {
		portinfo = (*PortInfo)(unsafe.Pointer(&info[IPHEADER_SIZE]))
		fmt.Printf("src %s:%d dst %s:%d\n", Raw2String(ipheader.Source), portinfo.Source, Raw2String(ipheader.Dest), portinfo.Dest)
	} else {
		fmt.Printf("src %s dst %s\n", Raw2String(ipheader.Source), Raw2String(ipheader.Dest))
	}

}
func Raw2String(src uint32) string {
	raw := make([]byte, 4)
	binary.LittleEndian.PutUint32(raw, src)
	return strconv.FormatUint(uint64(raw[0]), 10) + "." + strconv.FormatUint(uint64(raw[1]), 10) + "." + strconv.FormatUint(uint64(raw[2]), 10) + "." + strconv.FormatUint(uint64(raw[3]), 10)
}
func Print_Info() func([]byte, int) {
	return print_info
}

测试主函数

func main() {
	fmt.Fprintln(os.Stderr, inet.Watch(inet.Print_Info()))
}

效果

请添加图片描述

以上就是golang监听ip数据包的实现步骤(golang纯享版)的详细内容,更多关于golang监听ip数据包的资料请关注脚本之家其它相关文章!

相关文章

  • Go语言实现遍历文件夹

    Go语言实现遍历文件夹

    这篇文章主要为大家详细介绍了Go语言实现遍历文件夹的相关方法,文中的示例代码讲解详细,具有一定的参考价值,感兴趣的小伙伴可以了解一下
    2023-05-05
  • Go语言压缩和解压缩tar.gz文件的方法

    Go语言压缩和解压缩tar.gz文件的方法

    这篇文章主要介绍了Go语言压缩和解压缩tar.gz文件的方法,实例分析了使用Go语言压缩文件与解压文件的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • golang中xorm的基本使用说明

    golang中xorm的基本使用说明

    这篇文章主要介绍了golang中xorm的基本使用说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • GoFrame框架garray并发安全数组使用开箱体验

    GoFrame框架garray并发安全数组使用开箱体验

    这篇文章主要介绍了GoFrame框架garray并发安全数组使用开箱体验,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Golang通过包长协议处理TCP粘包的问题解决

    Golang通过包长协议处理TCP粘包的问题解决

    本文主要介绍了Golang通过包长协议处理TCP粘包的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Go语言单元测试基础从入门到放弃

    Go语言单元测试基础从入门到放弃

    这篇文章主要介绍了Go单元测试基础从入门到放弃为大家开启Go语言单元测试第一篇章,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Go语言学习之操作MYSQL实现CRUD

    Go语言学习之操作MYSQL实现CRUD

    Go官方提供了database包,database包下有sql/driver。该包用来定义操作数据库的接口,这保证了无论使用哪种数据库,操作方式都是相同的。本文就来和大家聊聊Go语言如何操作MYSQL实现CRUD,希望对大家有所帮助
    2023-02-02
  • 浅析Go常量为什么只支持基本数据类型

    浅析Go常量为什么只支持基本数据类型

    这篇文章主要来和大家一起讨论一下Golang中常量为什么只支持基本数据类型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-09-09
  • go xorm框架的使用

    go xorm框架的使用

    xorm框架和Spring Data Jpa有点相似,可以对比学习,对于这个框架感觉还不错,闲暇时间学习一下
    2021-05-05
  • golang xorm 自定义日志记录器之使用zap实现日志输出、切割日志(最新)

    golang xorm 自定义日志记录器之使用zap实现日志输出、切割日志(最新)

    这篇文章主要介绍了golang xorm 自定义日志记录器,使用zap实现日志输出、切割日志,包括连接postgresql数据库的操作方法及 zap日志工具 ,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10

最新评论