c#用winpcap发送需要用到的函数

只需要5个

一般步骤是

        [DllImport("wpcap.dll")]
        private static extern int pcap_findalldevs(ref IntPtr devicelist, StringBuilder errbuf);
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        private struct pcap_if
        {
            public IntPtr next;
            public string name;
            public string description;
            public IntPtr addresses;
            public uint flags;
        }

pcap_findalldevs找到所有的网络接口

自己找到正确的那个

然后

        [DllImport("wpcap.dll")]
        private static extern void pcap_freealldevs(IntPtr devicelist);

调用这种非托管的dll,包括winapi,弄完一样几乎都要相应的free一下,也几乎都有一个相应的free方法,这是c#不太习惯的


为什么要用pcap_findalldevs?虽然用System.Net.NetworkInformation命名空间里面的玩意可以多快好省的搞到一切信息吧,但是却不能保证winpcap可以打开这个设备啊,用winpcap的函数就相当于测试一下工作是否正常。


然后通过pcap_findalldevs找到相应的网络接口后

要pcap_if结构中的name

然后open

        [DllImport("wpcap.dll")]
        private static extern IntPtr pcap_open(string source, int snaplen,int flags, int read_timeout, IntPtr auth, StringBuilder errbuf);

这个source就是上面那个name


打开后

        [DllImport("wpcap.dll")]
        private static extern int pcap_sendpacket(IntPtr p, byte[] buff, int size);


pcap_sendpacket,这里发送的是以太网的数据包

其实以太网数据包和ip数据包相比,仅仅是在ip数据包前面多了14个字节

这里可能是个误区,好像以太网数据包在mac前面还有点东西,最后还有crc校验,但是对于用winpcap的pcap_sendpacket来说就等于ip包前多了14个字节而已

前6个是目标mac地址,接下来6个是本机网卡的mac地址,最后2个是协议类型,ip协议就是08 00


目标mac如何获得?

其实你用sniffer工具看一下就知道,就是网关的mac

比如我的机器是通过路由器上网的(路由器进行的PPPoE拨号)

那么发送时的以太网数据格式为

路由器mac(6字节)+网卡mac(6字节)+协议2字节+协议内容

这是我用ie连接时捕获的结果,返回的比如syn+ack就是网卡mac在前和路由mac在后仅此而已

自己构造好发出去就行了

于是就可以突破windows对于rawsocket的限制进行syn扫描或者攻击什么的了,只要能装winpcap的windows系统都可以。


最后

        [DllImport("wpcap.dll")]
        private static extern void pcap_close(IntPtr p);


===========

补充一句,winpcap是不管矫正你的数据包的,像ip头的checksum你得算对了才能发出去呢。而rawsocket,系统会帮你矫正checksum的,不信你可以试试,用rawsocket即使不计算checksum把那俩字节全用0,系统照样给你算出checksum发出去,比如说我用rawsocket发出去了syn也收到了syn+ack,但是用winpcap发出去结果就收不到,我就奇怪了同样一个程序啊,结果用sniffer工具一看,用winpcap的ip checksum不对,我就更奇怪了,同样一个程序生成的Ip包,怎么checksum会不一样呢?折腾了半天发现,原来用rawsocket发送的ip包的checksum也是错误的,但是却被系统自己给改成了正确的,合着之前一直算错了,但rawsocket每次都给矫正发出去了,而winpcap是不给矫正的,算错了就发不出去,于是改对了checksum后,用winpcap发送syn也就可以正常接收到syn+ack了。



你可能感兴趣的:(C#)