博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
原始UDP封包发送
阅读量:6940 次
发布时间:2019-06-27

本文共 3882 字,大约阅读时间需要 12 分钟。

hot3.png

发送原始UDP封包时:

1 以IPPROTO_UDP 为协议类型创建一个原始套接字,打开原始套接字上的IP_HDRINCL选项

2 构建UDP封包,要先设置IP头,设置UDP头,最后UDP净荷数据。

3 初始化完整的UDP封包之后,调用sendto函数即可将他发送。

计算UDP封包校验和的过程如下:

void ComputeUdpPseudoHeaderChecksum(    IPHeader    *pIphdr,    UDPHeader *pUdphdr,    char    *payload,    int      payloadlen    ){    char buff[1024];    char *ptr = buff;    int chksumlen = 0;    ULONG zero = 0;        // 包含源IP地址和目的IP地址    memcpy(ptr, &pIphdr->ipSource, sizeof(pIphdr->ipSource));    ptr += sizeof(pIphdr->ipSource);    chksumlen += sizeof(pIphdr->ipSource);    memcpy(ptr, &pIphdr->ipDestination, sizeof(pIphdr->ipDestination));    ptr += sizeof(pIphdr->ipDestination);    chksumlen += sizeof(pIphdr->ipDestination);    // 包含8位0域    memcpy(ptr, &zero, 1);    ptr += 1;    chksumlen += 1;    // 协议    memcpy(ptr, &pIphdr->ipProtocol, sizeof(pIphdr->ipProtocol));    ptr += sizeof(pIphdr->ipProtocol);    chksumlen += sizeof(pIphdr->ipProtocol);    // UDP长度    memcpy(ptr, &pUdphdr->len, sizeof(pUdphdr->len));    ptr += sizeof(pUdphdr->len);    chksumlen += sizeof(pUdphdr->len);    // UDP源端口号    memcpy(ptr, &pUdphdr->sourcePort, sizeof(pUdphdr->sourcePort));    ptr += sizeof(pUdphdr->sourcePort);    chksumlen += sizeof(pUdphdr->sourcePort);    // UDP目的端口号    memcpy(ptr, &pUdphdr->destinationPort, sizeof(pUdphdr->destinationPort));    ptr += sizeof(pUdphdr->destinationPort);    chksumlen += sizeof(pUdphdr->destinationPort);    // 又是UDP长度    memcpy(ptr, &pUdphdr->len, sizeof(pUdphdr->len));    ptr += sizeof(pUdphdr->len);    chksumlen += sizeof(pUdphdr->len);    // 16位的UDP校验和,置为0    memcpy(ptr, &zero, sizeof(USHORT));    ptr += sizeof(USHORT);    chksumlen += sizeof(USHORT);    // 净荷    memcpy(ptr, payload, payloadlen);    ptr += payloadlen;    chksumlen += payloadlen;    // 补齐到下一个16位边界    for(int i=0; i
checksum = checksum((USHORT*)buff, chksumlen);}

发送原始UDP封包的过程如下:

int main(){    // 输入参数信息    char szDestIp[] = "10.16.115.88";      //  <<== 填写目的IP地址    char szSourceIp[] = "127.0.0.1";      //  <<== 填写您自己的IP地址    USHORT nDestPort = 4567;    USHORT nSourcePort = 8888;    char szMsg[] = "This is a test \r\n";    int nMsgLen = strlen(szMsg);    // 创建原始套节字    SOCKET sRaw = ::socket(AF_INET, SOCK_RAW, IPPROTO_UDP);    // 有效IP头包含选项    BOOL bIncl = TRUE;    ::setsockopt(sRaw, IPPROTO_IP, IP_HDRINCL, (char *)&bIncl, sizeof(bIncl));    char buff[1024] = { 0 };    // IP头    IPHeader *pIphdr = (IPHeader *)buff;    pIphdr->iphVerLen = (4<<4 | (sizeof(IPHeader)/sizeof(ULONG)));    pIphdr->ipLength = ::htons(sizeof(IPHeader) + sizeof(UDPHeader) + nMsgLen);    pIphdr->ipTTL = 128;    pIphdr->ipProtocol = IPPROTO_UDP;    pIphdr->ipSource = ::inet_addr(szSourceIp);    pIphdr->ipDestination = ::inet_addr(szDestIp);    pIphdr->ipChecksum = checksum((USHORT*)pIphdr, sizeof(IPHeader));    // UDP头    UDPHeader *pUdphdr = (UDPHeader *)&buff[sizeof(IPHeader)];    pUdphdr->sourcePort = htons(8888);    pUdphdr->destinationPort = htons(nDestPort);    pUdphdr->len = htons(sizeof(UDPHeader) + nMsgLen);    pUdphdr->checksum = 0;    char *pData = &buff[sizeof(IPHeader) + sizeof(UDPHeader)];    memcpy(pData, szMsg, nMsgLen);    ComputeUdpPseudoHeaderChecksum(pIphdr, pUdphdr, pData, nMsgLen);    // 设置目的地址    SOCKADDR_IN destAddr = { 0 };    destAddr.sin_family = AF_INET;    destAddr.sin_port = htons(nDestPort);    destAddr.sin_addr.S_un.S_addr = ::inet_addr(szDestIp);    // 发送原始UDP封包    int nRet;    for(int i=0; i<5; i++)    {        nRet = ::sendto(sRaw, buff,             sizeof(IPHeader) + sizeof(UDPHeader) + nMsgLen, 0, (sockaddr*)&destAddr, sizeof(destAddr));        if(nRet == SOCKET_ERROR)        {            printf(" sendto() failed: %d \n", ::WSAGetLastError());            break;        }        else        {            printf(" sent %d bytes \n", nRet);        }    }    ::closesocket(sRaw);    getchar();    return 0;}

转载于:https://my.oschina.net/u/204616/blog/545257

你可能感兴趣的文章
思科命令学习之第二篇
查看>>
24点运算
查看>>
高通平台信号强度和质量的log过滤
查看>>
Yii使用CPagination分页
查看>>
总结自己常用的Eclipse常用快捷键
查看>>
linux系统启动流程
查看>>
Spring MVC如何把全局异常记录到日志中?
查看>>
2015.10.10信息系统项目管理师作业
查看>>
我的友情链接
查看>>
Java8-Stream-终止操作-归约与收集
查看>>
NOSQL分类
查看>>
VUE学习遇到的问题及解决方法(一)
查看>>
Python中lambda的用法
查看>>
E036-rpmdb open failed
查看>>
基于结构化平均感知机的分词器Java实现
查看>>
IPFS是什么?
查看>>
机器学习:从入门到晋级
查看>>
安卓constraintLayout中app:srcCompat设置的图片显示不出来
查看>>
nginx 安装在ubuntu上
查看>>
iOS地图选址
查看>>