以太网报文格式:

详细的说明,请看《MAC 头部报文分析》。

IP 报文格式:

详细的说明,请看《IP 数据报格式详解》。

UDP 报文格式:

详细的说明,请看《UDP 数据报格式详解》。

校验和函数:

/*******************************************************
功能:校验和函数
参数:buf: 需要校验数据的首地址nword: 需要校验数据长度的一半
返回值:校验和
*******************************************************/
unsigned short checksum(unsigned short *buf, int nword)
{unsigned long sum;for(sum = 0; nword > 0; nword--){sum += htons(*buf);buf++;}sum = (sum>>16) + (sum&0xffff);sum += (sum>>16);return ~sum;
}

这里是在 ubuntu 下通过原始套接字组一个 udp 数据包,给 PC 机的网络调试助手发送信息:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <net/if.h>               //struct ifreq
#include <sys/ioctl.h>            //ioctl、SIOCGIFADDR
#include <sys/socket.h>
#include <netinet/ether.h>        //ETH_P_ALL
#include <netpacket/packet.h> //struct sockaddr_llunsigned short checksum(unsigned short *buf, int nword);//校验和函数
int main(int argc, char *argv[])
{//1.创建通信用的原始套接字int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));//2.根据各种协议首部格式构建发送数据报unsigned char send_msg[1024] = {//--------------组MAC--------14------0x74, 0x27, 0xea, 0xb5, 0xef, 0xd8, //dst_mac: 74-27-EA-B5-FF-D80xc8, 0x9c, 0xdc, 0xb7, 0x0f, 0x19, //src_mac: c8:9c:dc:b7:0f:190x08, 0x00,                         //类型:0x0800 IP协议//--------------组IP---------20------0x45, 0x00, 0x00, 0x00,             //版本号:4, 首部长度:20字节, TOS:0, --总长度--:0x00, 0x00, 0x00, 0x00,               //16位标识、3位标志、13位片偏移都设置00x80, 17,   0x00, 0x00,              //TTL:128、协议:UDP(17)、16位首部校验和10,  221,   20,  11,               //src_ip: 10.221.20.1110,  221,   20,  10,              //dst_ip: 10.221.20.10//--------------组UDP--------8+78=86------0x1f, 0x90, 0x1f, 0x90,             //src_port:0x1f90(8080), dst_port:0x1f90(8080)0x00, 0x00, 0x00, 0x00,               //#--16位UDP长度--30个字节、#16位校验和};int len = sprintf(send_msg+42, "%s", "this is for the udp test");if(len % 2 == 1)//判断len是否为奇数{len++;//如果是奇数,len就应该加1(因为UDP的数据部分如果不为偶数需要用0填补)}*((unsigned short *)&send_msg[16]) = htons(20+8+len);//IP总长度 = 20 + 8 + len*((unsigned short *)&send_msg[14+20+4]) = htons(8+len);//udp总长度 = 8 + len//3.UDP伪头部unsigned char pseudo_head[1024] = {//------------UDP伪头部--------12--10,  221,   20,  11,             //src_ip: 10.221.20.1110,  221,   20,  10,              //dst_ip: 10.221.20.100x00, 17,   0x00, 0x00,               //0,17,#--16位UDP长度--20个字节};*((unsigned short *)&pseudo_head[10]) = htons(8 + len);//为头部中的udp长度(和真实udp长度是同一个值)//4.构建udp校验和需要的数据报 = udp伪头部 + udp数据报memcpy(pseudo_head+12, send_msg+34, 8+len);//--计算udp校验和时需要加上伪头部--//5.对IP首部进行校验*((unsigned short *)&send_msg[24]) = htons(checksum((unsigned short *)(send_msg+14),20/2));//6.--对UDP数据进行校验--*((unsigned short *)&send_msg[40]) = htons(checksum((unsigned short *)pseudo_head,(12+8+len)/2));//6.发送数据struct sockaddr_ll sll;                  //原始套接字地址结构struct ifreq req;                    //网络接口地址strncpy(req.ifr_name, "eth0", IFNAMSIZ);          //指定网卡名称if(-1 == ioctl(sock_raw_fd, SIOCGIFINDEX, &req))  //获取网络接口{perror("ioctl");close(sock_raw_fd);exit(-1);}/*将网络接口赋值给原始套接字地址结构*/bzero(&sll, sizeof(sll));sll.sll_ifindex = req.ifr_ifindex;len = sendto(sock_raw_fd, send_msg, 14+20+8+len, 0 , (struct sockaddr *)&sll, sizeof(sll));if(len == -1){perror("sendto");}return 0;
}unsigned short checksum(unsigned short *buf, int nword)
{unsigned long sum;for(sum = 0; nword > 0; nword--){sum += htons(*buf);buf++;}sum = (sum>>16) + (sum&0xffff);sum += (sum>>16);return ~sum;
}

运行结果如下:

【Linux网络编程】原始套接字实例:发送 UDP 数据包相关推荐

  1. 原始套接字SOCK_RAW发送UDP数据包

    使用原始套接字发送udp数据包,从传输层封包到链路层(mac头+ip头+udp头).udp数据包,从传输层封包到链路层(mac头+ip头+udp头). head.h文件如下: #ifndef _HEA ...

  2. Linux 网络编程——原始套接字实例:MAC 地址扫描器

    如果 A (192.168.1.1 )向 B (192.168.1.2 )发送一个数据包,那么需要的条件有 ip.port.使用的协议(TCP/UDP)之外还需要 MAC 地址,因为在以太网数据包中 ...

  3. linux串口编程实例_Linux 网络编程——原始套接字实例:发送 UDP 数据包

    以太网报文格式: IP 报文格式: UDP 报文格式: 校验和函数: /*******************************************************功能:校验和函数参 ...

  4. Linux网络编程——原始套接字编程

    Linux网络编程--原始套接字编程 转自:http://blog.csdn.net/tennysonsky/article/details/44676377 原始套接字编程和之前的 UDP 编程差不 ...

  5. Linux网络编程——原始套接字能干什么?

    一.知识回顾: 通常情况下程序员接所接触到的套接字(Socket)为两类: (1)流式套接字(SOCK_STREAM):一种面向连接的 Socket,针对于面向连接的TCP 服务应用: (2)数据报式 ...

  6. Linux原始网络编程,Linux操作系统网络编程 原始套接字 (1)

    Linux操作系统网络编程--原始套接字 (1) http://soft.zdnet.com.cn/software_zone/2007/1020/568223.shtml 我们在前面已经学习过了网络 ...

  7. Linux网络编程之套接字基础

    Linux网络编程之套接字基础 1.套接字的基本结构 struct sockaddr 这个结构用来存储套接字地址. 数据定义: struct sockaddr { unsigned short sa_ ...

  8. 网络编程——原始套接字实现原理

    目录 1. 基础知识 1.1.概述 1.2.链路层原始套接字 1.3.网络层原始套接字 2.原始套接字的实现 2.1  原始套接字报文收发流程 2.2链路层原始套接字的实现 2.2.1  套接字创建 ...

  9. 【Linux网络编程】套接字简介

    00. 目录 文章目录 00. 目录 01. 概述 02. 套接字属性 03. socket函数 04. 套接字地址结构 05. 附录 01. 概述 Socket套接字由远景研究规划局(Advance ...

  10. 【Linux网络编程】套接字的介绍

    套接字是一种通信机制(通信的两方的一种约定),凭借这种机制,不同主机之间的进程可以进行通信.我们可以用套接字中的相关函数来完成通信过程. 套接字的特性有三个属性确定,它们是:域(domain),类型( ...

最新文章

  1. web服务器是如何维护,我们如何维护Web客户端和Web服务器之间的会话?
  2. python如何创建模块教程_Python创建模块及模块导入的方法
  3. flutter image boxfit
  4. stark组件开发之组合搜索基本显示
  5. 异常:fatal: unable to access 'https://git.oschina.net/pcmpcs/library.git/': Could not resolve host...
  6. Oracle学习资料汇集
  7. web前端顶岗实习总结报告_假期web前端实习报告
  8. 新策略构思 dual thrust
  9. angular-Forms patchValue and setValue
  10. 用计算机绘制函数图像ppt,ppt怎么制作函数图
  11. 最近在上海浦东新区的租房经历
  12. 2018杭州云栖大会主要演讲:新杭州故事,平头哥与新制造
  13. 彻底禁止电脑弹出广告的方法(以2345好压为例)
  14. 利用Python和正则表达式验证hotmail邮箱的格式
  15. jsp异常 The JSP specification requires that an attribute name is preceded by whitespace
  16. 完美解决Mac无法写入NTFS硬盘——Mounty for NTFS
  17. 六个人如何运维一万台服务器?
  18. 【1】DICOM图像格式
  19. 新随笔--读书笔记《学会提问》:学习提出好问题的思维方法
  20. 清理qmail邮件队列

热门文章

  1. UU看书于今日成功上线,各大小说网站发来贺电!!
  2. 服务器接收消息写日志,在Ubuntu 18.04上配置Rsyslog集中式日志服务器的方法
  3. 启动指定参数_SpringBoot的三种启动方式
  4. 1.7-27编程基础之字符串 单词翻转
  5. C语言学习之编程实现:输入长方形的两个边长a, b和一个整数k。k=1时,输出长方形的周长 l; k=2时 ,输出长方形的面积s;当k=3时 , 输出长方形的周长1和面积s
  6. STL源码剖析---空间配置器
  7. POJ 2083 递归画分形图
  8. 项目第一天--ElementUI介绍
  9. Linux 的进程状态
  10. mysql-学习-7-20170517-mysql分区