网络层代码实现

网络层代码

         针对IP协议以及网络层其他协议的攻击繁多。由于属于无连接协议,不提供认证功能,因此比较容易受到攻击。IP不是唯一受攻击目标,ICMP是另一个潜在的攻击目标。

winpcap发送syn数据包

 

 

 

函数说明

Mktcphrd函数用于构造TCP头。

入参为发送数据的结构体,源IP,目的IP,源端口和目的端口。

构造tcp报头中的相关参数。和ip报头中的相关值。

Mkiphrd函数用于构造IP头。入参为IP头结构,源IP和目的IP。

Checksum函数用于生成校验和。把IP头自己都加起来,然后右移16位, 与0xffff得到计算值后再加上右移16位。

         主函数逻辑过程

         创建一个素组大小1024个字节,创建一个结构体SYN_DATA,包含TCP和IP头。

         (在以太网发送,所以必须有以太网头的,结构体为ETHER_HEADER

         发送端IP为 192.168.1.4,接收端IP为192.168.1.5

         通过pcap_findalldevs函数来寻找网卡。

         然后将以太网头加入到要发送的字符串中,

         接着将SYN_DATA(TCP和IP头)加入到要发送的字符串中。

         最后将一个字符串“Just a Test!”复制到要发送的字符串中。

         答应要发送的总字节数量为66.

         以太网头:14自己

         IP头: 20字节

         TCP头:20字节

         字符串:12字节

         合计刚好是66个字节。

源码

如下:

#include<stdlib.h>

#include<stdio.h>

#include<winsock2.h>

#include<pcap.h>

#pragmacomment(lib,"wpcap.lib")

#pragmacomment(lib,"ws2_32.lib")

 

 

typedefstruct   _ETHER_HEADER{

    u_char  ether_dhost[6];

    u_char  ether_shost[6];

    u_short  ether_type;  //如果上一层为IP协议。则ether_type的值就是0x0800

} ETHER_HEADER;

 

 

//IP报头格式 ,20个字节

typedefstruct_IP_HEADER

{

    unsignedchar   h_lenver;

    unsignedchar   tos;

    unsignedshort  total_len;

    unsignedshort  ident;

    unsignedshort  frag_and_flags;

    unsignedchar   ttl;

    unsignedchar   proto;

    unsignedshort  checksum;

    unsignedint    sourceIP;

    unsignedint    destIP;

} IP_HEADER;

 

 

//TCP报头格式

typedefstruct_TCP_HEADER

{

    USHORT th_sport;

    USHORT th_dport;

    unsignedintth_seq;

    unsignedintth_ack;

    unsignedcharth_lenres;

    unsignedcharth_flag;

    USHORT th_win;

    USHORT th_sum;

    USHORT th_urp;

} TCP_HEADER;

 

 

//发送数据格式

typedefstruct_SYN_DATA

{

    IP_HEADER iphrd;

    TCP_HEADER tcphrd;

}SYN_DATA;

 

 

//校验和算法

USHORTchecksum(USHORT *buffer, intsize)

{

    unsignedlongcksum = 0;

 

 

    while (size > 1)

    {

        cksum+= *buffer++;

        size -= sizeof(USHORT);

    }

 

 

    if (size)

    {

        cksum+= *(UCHAR*)buffer;

    }

    cksum= (cksum >> 16) + (cksum & 0xffff);

    cksum+= (cksum >>16);

 

 

    return (USHORT)(~cksum);

}

 

 

//构造IP

intmkiphrd(IP_HEADER*ip, unsignedlongsip, unsignedlongdip)

{

    ip->h_lenver = (4<<4|5);

    ip->tos = 0;

    ip->total_len = sizeof(SYN_DATA);

    ip->ident = 0;

    ip->frag_and_flags = 0;

    ip->ttl = 64;

    ip->proto = 6;

    ip->checksum = 0;

    ip->destIP = dip;

    ip->sourceIP = sip;

    ip->checksum = checksum((USHORT *)&ip, sizeof(IP_HEADER));

    return 1;

}

 

 

//构造TCP

intmktcphrd(SYN_DATA*syndata, unsignedlongsip, unsignedlongdip, intsport, intdport)

{

    syndata->tcphrd.th_sport = sport;

    syndata->tcphrd.th_dport = dport;

    syndata->tcphrd.th_seq = 1001;

    syndata->tcphrd.th_ack = 0;

    syndata->tcphrd.th_lenres = 5<<4;

    syndata->tcphrd.th_flag = 2;

    syndata->tcphrd.th_win = htons(16384);

    syndata->tcphrd.th_sum = 0;

    syndata->tcphrd.th_urp = 0;

 

 

    //构造伪报头---关键,以此生成TCP校验和

    syndata->iphrd.ttl = 0;

    syndata->iphrd.proto =6;

    syndata->iphrd.sourceIP = sip;

    syndata->iphrd.destIP = dip;

    syndata->iphrd.checksum = htons(sizeof(TCP_HEADER));

    syndata->tcphrd.th_sum = checksum((USHORT *)(&(syndata->iphrd.ttl)), sizeof(TCP_HEADER)+12);

    return 1;

}

 

 

intmain(intargc, char **argv)

{

    pcap_t *fp;

    char errbuf[1024] = {0};

    u_char packet[1024];

   

 

    SYN_DATA sendbuf;   //将要发送的数据包(TCP\IP)

    ETHER_HEADER ethbuf;

 

    int sendsize=0;

    int iSendNum ;

    char data[20] = "Just a Test!";

 

    pcap_if_t *alldevs;

    pcap_if_t *d;

    int nSendByte;

    char *destip = "192.168.1.5";

    int destport = 2988;

 

    char *sourceip = "192.168.1.4";

    int sourceport = 2987;

 

    memset(&packet, 0, sizeofpacket );

    //构造发送数据

    memset((void *)&sendbuf, 0, sizeof sendbuf);

    mktcphrd(&sendbuf, inet_addr(sourceip), inet_addr(destip), htons(sourceport), htons(destport));

    mkiphrd(&(sendbuf.iphrd), inet_addr(sourceip), inet_addr(destip));

    sendbuf.iphrd.checksum= checksum((USHORT *)&sendbuf, sizeof(IP_HEADER)+sizeof(TCP_HEADER));

 

    /* Retrieve the device list */

    if(pcap_findalldevs(&alldevs, errbuf) == -1)

    {

        fprintf(stderr,"Error in pcap_findalldevs:%s\n", errbuf);

        exit(1);

    }

    /* Scan the list printing every entry */

    //每个网卡都发送

    for(d=alldevs;d;d=d->next)

    {

        /* Open the adapter */

        if ((fp = pcap_open_live(d->name, // name of the device

            65536,// portion of the packet to capture. It doesn't matter in this case

            1,// promiscuous mode (nonzero means promiscuous)

            1000,// read timeout

            errbuf// error buffer

            ))== NULL)

        {

            fprintf(stderr,"\nUnable to open theadapter. %s is not supported by WinPcap\n",sourceip);

            break;

        }

 

 

        //目的主机Mac地址,是我本机MAC

        ethbuf.ether_dhost[0]= 0x00;

        ethbuf.ether_dhost[1]= 0xff;

        ethbuf.ether_dhost[2]= 0xde;

        ethbuf.ether_dhost[3]= 0x28;

        ethbuf.ether_dhost[4]= 0x57;

        ethbuf.ether_dhost[5]= 0x6d;

 

 

        //源主机Mac,也是我本机mac

        ethbuf.ether_shost[0]= 0x00;

        ethbuf.ether_shost[1]= 0xff;

        ethbuf.ether_shost[2]= 0xde;

        ethbuf.ether_shost[3]= 0x28;

        ethbuf.ether_shost[4]= 0x57;

        ethbuf.ether_shost[5]= 0x6d;

 

        ethbuf.ether_type= htons(0x0800);

 

        memcpy(packet,&ethbuf, sizeof(ethbuf)) ;

        sendsize+= sizeof(ethbuf) ;

        memcpy(packet+sendsize,&sendbuf, sizeof(sendbuf)) ;

        sendsize+= sizeof(sendbuf) ;

        memcpy(packet+sendsize,data, sizeof(data)) ;

 

        /* Send down the packet */

 

        nSendByte= sendsize + strlen( data );

        printf("%d\n", nSendByte );

 

        for(iSendNum = 0; iSendNum <1; ++iSendNum)

        {

            if (pcap_sendpacket(fp, //Adapter

                packet,// buffer with the packet

                100// size

                )!= 0)

            {

                pcap_close(fp);

                break;

            }

        }

        printf("send sucess!\n");

        pcap_close(fp);

    }

    system("pause");

    return 0;

}

抓包 

使用Wireshark抓包内容如下:

         发现直接数据其实是46个字节,这是因为归档至少46个字节。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值