【Linux网络编程】原始套接字实例:发送 UDP 数据包
以太网报文格式:
详细的说明,请看《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 数据包相关推荐
- 原始套接字SOCK_RAW发送UDP数据包
使用原始套接字发送udp数据包,从传输层封包到链路层(mac头+ip头+udp头).udp数据包,从传输层封包到链路层(mac头+ip头+udp头). head.h文件如下: #ifndef _HEA ...
- Linux 网络编程——原始套接字实例:MAC 地址扫描器
如果 A (192.168.1.1 )向 B (192.168.1.2 )发送一个数据包,那么需要的条件有 ip.port.使用的协议(TCP/UDP)之外还需要 MAC 地址,因为在以太网数据包中 ...
- linux串口编程实例_Linux 网络编程——原始套接字实例:发送 UDP 数据包
以太网报文格式: IP 报文格式: UDP 报文格式: 校验和函数: /*******************************************************功能:校验和函数参 ...
- Linux网络编程——原始套接字编程
Linux网络编程--原始套接字编程 转自:http://blog.csdn.net/tennysonsky/article/details/44676377 原始套接字编程和之前的 UDP 编程差不 ...
- Linux网络编程——原始套接字能干什么?
一.知识回顾: 通常情况下程序员接所接触到的套接字(Socket)为两类: (1)流式套接字(SOCK_STREAM):一种面向连接的 Socket,针对于面向连接的TCP 服务应用: (2)数据报式 ...
- Linux原始网络编程,Linux操作系统网络编程 原始套接字 (1)
Linux操作系统网络编程--原始套接字 (1) http://soft.zdnet.com.cn/software_zone/2007/1020/568223.shtml 我们在前面已经学习过了网络 ...
- Linux网络编程之套接字基础
Linux网络编程之套接字基础 1.套接字的基本结构 struct sockaddr 这个结构用来存储套接字地址. 数据定义: struct sockaddr { unsigned short sa_ ...
- 网络编程——原始套接字实现原理
目录 1. 基础知识 1.1.概述 1.2.链路层原始套接字 1.3.网络层原始套接字 2.原始套接字的实现 2.1 原始套接字报文收发流程 2.2链路层原始套接字的实现 2.2.1 套接字创建 ...
- 【Linux网络编程】套接字简介
00. 目录 文章目录 00. 目录 01. 概述 02. 套接字属性 03. socket函数 04. 套接字地址结构 05. 附录 01. 概述 Socket套接字由远景研究规划局(Advance ...
- 【Linux网络编程】套接字的介绍
套接字是一种通信机制(通信的两方的一种约定),凭借这种机制,不同主机之间的进程可以进行通信.我们可以用套接字中的相关函数来完成通信过程. 套接字的特性有三个属性确定,它们是:域(domain),类型( ...
最新文章
- web服务器是如何维护,我们如何维护Web客户端和Web服务器之间的会话?
- python如何创建模块教程_Python创建模块及模块导入的方法
- flutter image boxfit
- stark组件开发之组合搜索基本显示
- 异常:fatal: unable to access 'https://git.oschina.net/pcmpcs/library.git/': Could not resolve host...
- Oracle学习资料汇集
- web前端顶岗实习总结报告_假期web前端实习报告
- 新策略构思 dual thrust
- angular-Forms patchValue and setValue
- 用计算机绘制函数图像ppt,ppt怎么制作函数图
- 最近在上海浦东新区的租房经历
- 2018杭州云栖大会主要演讲:新杭州故事,平头哥与新制造
- 彻底禁止电脑弹出广告的方法(以2345好压为例)
- 利用Python和正则表达式验证hotmail邮箱的格式
- jsp异常 The JSP specification requires that an attribute name is preceded by whitespace
- 完美解决Mac无法写入NTFS硬盘——Mounty for NTFS
- 六个人如何运维一万台服务器?
- 【1】DICOM图像格式
- 新随笔--读书笔记《学会提问》:学习提出好问题的思维方法
- 清理qmail邮件队列
热门文章
- UU看书于今日成功上线,各大小说网站发来贺电!!
- 服务器接收消息写日志,在Ubuntu 18.04上配置Rsyslog集中式日志服务器的方法
- 启动指定参数_SpringBoot的三种启动方式
- 1.7-27编程基础之字符串 单词翻转
- C语言学习之编程实现:输入长方形的两个边长a, b和一个整数k。k=1时,输出长方形的周长 l; k=2时 ,输出长方形的面积s;当k=3时 , 输出长方形的周长1和面积s
- STL源码剖析---空间配置器
- POJ 2083 递归画分形图
- 项目第一天--ElementUI介绍
- Linux 的进程状态
- mysql-学习-7-20170517-mysql分区