linux原始套接字(4)-构造IP_UDP
一.概述
同上一篇tcp一样,udp也是封装在ip报文里面。创建UDP的原始套接字如下:
(sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);
同样,如果要构造udp的ip首部,要开启IP_HDRINCL选项!
udp首部格式:

udp的不可靠性,比tcp报文简单很多。上面的16位UDP长度是UDP首部+普通数据的总长度,这点跟ip首部的16位总长度一样!
udp结构定义在netinet/udp.h
struct udphdr
{
__extension__ union
{
struct
{
u_int16_t uh_sport; /* source port */
u_int16_t uh_dport; /* destination port */
u_int16_t uh_ulen; /* udp length */
u_int16_t uh_sum; /* udp checksum */
};
struct
{
u_int16_t source;
u_int16_t dest;
u_int16_t len;
u_int16_t check;
};
};
};
二.构造IP_UDP报文发送
/**
* @file ip_udp_send.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
/* ip首部长度 */
#define IP_HEADER_LEN sizeof(struct ip)
/* udp首部长度 */
#define UDP_HEADER_LEN sizeof(struct udphdr)
/* ip首部 + udp首部长度 */
#define IP_UDP_HEADER_LEN IP_HEADER_LEN + UDP_HEADER_LEN
void err_exit(const char *err_msg)
{
perror(err_msg);
exit();
}
/* 填充ip首部 */
struct ip *fill_ip_header(const char *src_ip, const char *dst_ip, int ip_packet_len)
{
struct ip *ip_header;
ip_header = (struct ip *)malloc(IP_HEADER_LEN);
ip_header->ip_v = IPVERSION;
ip_header->ip_hl = IP_HEADER_LEN / ;
ip_header->ip_tos = ;
ip_header->ip_len = htons(ip_packet_len);
ip_header->ip_id = ;
ip_header->ip_off = ;
ip_header->ip_ttl = MAXTTL;
ip_header->ip_p = IPPROTO_UDP; /* 这里是UDP */
ip_header->ip_sum = ;
ip_header->ip_src.s_addr = inet_addr(src_ip);
ip_header->ip_dst.s_addr = inet_addr(dst_ip);
return ip_header;
}
/* 填充udp首部 */
struct udphdr *fill_udp_header(int src_port, int dst_port, int udp_packet_len)
{
struct udphdr *udp_header;
udp_header = (struct udphdr *)malloc(UDP_HEADER_LEN);
udp_header->source = htons(src_port);
udp_header->dest = htons(dst_port);
/* 这里的长度是整个UDP报文 */
udp_header->len = htons(udp_packet_len);
udp_header->check = ;
return udp_header;
}
/* 发送ip_udp报文 */
void ip_udp_send(const char *src_ip, int src_port, const char *dst_ip, int dst_port, const char *data)
{
struct ip *ip_header;
struct udphdr *udp_header;
struct sockaddr_in dst_addr;
socklen_t sock_addrlen = sizeof(struct sockaddr_in);
int data_len = strlen(data);
int ip_packet_len = IP_UDP_HEADER_LEN + data_len;
int udp_packet_len = UDP_HEADER_LEN + data_len;
char buf[ip_packet_len];
;
bzero(&dst_addr, sock_addrlen);
dst_addr.sin_family = PF_INET;
dst_addr.sin_addr.s_addr = inet_addr(dst_ip);
dst_addr.sin_port = htons(dst_port);
/* 创建udp原始套接字 */
)
err_exit("socket()");
/* 开启IP_HDRINCL,自定义IP首部 */
)
err_exit("setsockopt()");
/* ip首部 */
ip_header = fill_ip_header(src_ip, dst_ip, ip_packet_len);
/* udp首部 */
udp_header = fill_udp_header(src_port, dst_port, udp_packet_len);
bzero(buf, ip_packet_len);
memcpy(buf, ip_header, IP_HEADER_LEN);
memcpy(buf + IP_HEADER_LEN, udp_header, UDP_HEADER_LEN);
memcpy(buf + IP_UDP_HEADER_LEN, data, data_len);
/* 发送报文 */
ret_len = sendto(sockfd, buf, ip_packet_len, , (struct sockaddr *)&dst_addr, sock_addrlen);
)
printf("sendto() ok!!!\n");
else printf("sendto() failed\n");
close(sockfd);
free(ip_header);
free(udp_header);
}
int main(int argc, const char *argv[])
{
)
{
printf(]);
exit();
}
/* 发送ip_udp报文 */
ip_udp_send(argv[], atoi(argv[]), argv[], atoi(argv[]), argv[]);
;
}
上面的大部分代码都跟上一篇差不多。不同的是这次是填充udp首部,创建原始套接字的类型是UDP。
linux原始套接字(4)-构造IP_UDP的更多相关文章
- linux原始套接字(3)-构造IP_TCP发送与接收
一.概述 tcp报文封装在ip报文中,创建tcp的原始套接字如下: sockfd = socket ...
- Linux原始套接字实现分析---转
http://blog.chinaunix.net/uid-27074062-id-3388166.html 本文从IPV4协议栈原始套接字的分类入手,详细介绍了链路层和网络层原始套接字的特点及其内核 ...
- Linux原始套接字抓取底层报文
1.原始套接字使用场景 我们平常所用到的网络编程都是在应用层收发数据,每个程序只能收到发给自己的数据,即每个程序只能收到来自该程序绑定的端口的数据.收到的数据往往只包括应用层数据,原有的头部信息在传递 ...
- 关于linux 原始套接字编程
关于linux 网络编程最权威的书是<<unix网络编程>>,但是看这本书时有些内容你可能理解的不是很深刻,或者说只知其然而不知其所以然,那么如果你想搞懂的话那么我建议你可以看 ...
- linux原始套接字(2)-icmp请求与接收
一.概述 上一篇arp请求使用的是链路层的原始套接字.icmp封装在ip数据报里面,所以icmp请 ...
- linux原始套接字(1)-arp请求与接收
一.概述 以太网的arp数据包结构: arp结构op操作参数:1为请求,2为应答. 常用的数据结构如 ...
- UNP——原始套接字
1.原始套接字的用处 使用原始套接字可以构造或读取网际层及其以上报文. 具体来说,可以构造 ICMP, IGMP 协议报文,通过开启 IP_HDRINCL 套接字选项,进而自定义 IPv4首部. 2. ...
- Linux基础(11)原始套接字
一边接收函数返回一边判断返回值时一定要把接收的优先级加()提高再去判断 例 if((sockfd = socket()) < 0) 问题: 如何实现SYN扫描器扫描端口 , 比如AB两个设备要进 ...
- Linux Socket 原始套接字编程
对于linux网络编程来说,可以简单的分为标准套接字编程和原始套接字编程,标准套接字主要就是应用层数据的传输,原始套接字则是可以获得不止是应用层的其他层不同协议的数据.与标准套接字相区别的主要是要开发 ...
随机推荐
- 基于 jQuery 实现垂直滑动的手风琴效果
今天我们要与大家分享一个漂亮而灵活的垂直 jQuery 手风琴效果.其主要思想是扩大手风琴片上的点击和显示更多的信息.其他内容片段将变得不那么透明.当使用一个导航箭头导航下一个片段,新的片会从顶部或底 ...
- Office 365 - SharePoint 2013 Online 在应用商店中添加应用
1.在使用应用程序商店的时候,先点击配置应用商店设置,如下图: 2.发现SharePoint要求我们创建应用程序目录,用来分发SharePoint App的一个网站,不过不创建的话,依然可以在应用商店 ...
- Vault 不同版本的API的异同
大家知道,Autodesk Vault 2014有几个版本,依次为( Basic, Workgroup, Professional),不同版本的功能不相同,关于Vault产品功能的不同之处可以在Vau ...
- SharePoint 2010 人员选择器搜索范围的限定
客户AD中用户信息过多,而当前的SharePoint应用中不需要针对所有AD进行筛选,则需要通过STSADM来设置搜索范围: stsadm -o setsiteuseraccountdirectory ...
- mysql innodb 奔溃问题
ps -A | grep -i mysql kill 列出来的进程 service mysql start 我的问题就解决了 ------------------------------------- ...
- IDA调试android so文件.init_array和JNI_OnLoad
我们知道so文件在被加载的时候会首先执行.init_array中的函数,然后再执行JNI_OnLoad()函数.JNI_Onload()函数因为有符号表所以非常容易找到,但是.init_array里的 ...
- iOS 跳转到系统的设置界面
跳到健康设置 上网找了一下 你会发现很难找到.代码如下 不信你试试 . NSURL *url = [NSURL URLWithString:@"prefs:root=Privacy& ...
- 电脑公司最新GHOST WIN7系统32,64位优化精简版下载
系统来自系统妈:http://www.xitongma.com 电脑公司最新GHOST win7系统32位优化精简版V2016年3月 系统概述 电脑公司ghost win7 x86(32位)万能装机版 ...
- 小结RunLoop
Core Foundation中关于RunLoop的5个类 CFRunLoopRef CFRunLoopModeRef CFRunLoopSourceRef CFRunLoopTimerRef CFR ...
- 用GCD线程组与GCD信号量将异步线程转换为同步线程
有时候我们会碰到这样子的一种情形: 同时获取两个网络请求的数据,但是网络请求是异步的,我们需要获取到两个网络请求的数据之后才能够进行下一步的操作,这个时候,就是线程组与信号量的用武之地了. #impo ...