栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

135

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

135

动图:

什么是UDP协议:

点击

#include
#include
#include//memcpy
#include 
#include 
#include 
#include 
#include //MAC
#include //IP
#include //UDP

#if 1 //---------------发送UDP-------------//
typedef struct{
    //伪UDP的首部数据类型
	u_int32_t saddr;
	u_int32_t daddr;
	u_int8_t flag;
	u_int8_t type;
	u_int16_t len;

}FALSE_HEAD;

//数据包校验计算
//接收传递的数据地址、长度
unsigned short checksum(unsigned short *buf, int len)
{
	int nword = len/2;
	unsigned long sum;

	if(len%2 == 1)
		nword++;
	for(sum = 0; nword > 0; nword--)
	{
		sum += *buf;
		buf++;
	}
	sum = (sum>>16) + (sum&0xffff);
	sum += (sum>>16);
	return ~sum;
}

int main(int argc,char *argv[])
{
	//创建原始套接字
	int sockfd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));

//-----------------------------【-明确发送对象--】-----------------------//    
	//网卡结构体
	struct ifreq ethreq;
	strncpy(ethreq.ifr_name,"eth0",IFNAMSIZ);//指定网卡名字eth0
	if(ioctl(sockfd, SIOCGIFINDEX, ðreq)==-1){
        //获得eth0的接口类型
		return 0;
	}
	//发送接口的结构体
	struct sockaddr_ll sll;
	bzero(&sll,sizeof(sll));
	sll.sll_ifindex = ethreq.ifr_ifindex;//将网卡的接口类型赋值给发送接口

	unsigned char udp_buf[1500]="";//一个完整的MTU数据包最大1500
	

	
	unsigned char buf[1024] = "";
	fgets(buf,sizeof(buf),stdin);//获得键盘输入
	buf[strlen(buf) - 1]='';
	int date_len = strlen(buf) + strlen(buf) % 2;//整数补齐偶数位,strlen(buf)%2:偶数+0,奇数+1
	printf("%d---%sn",date_len, buf);
	
//-----开始组包------//
//----------------------组udp数据包的MAC----------------------------//
	struct ether_header *mac_head=(struct ether_header *)udp_buf;
    //先给定MAC地址
	unsigned char dst_mac[8]={0x2C,0x4D,0x54,0x57,0x04,0x7F};//主机MAC--目的:串口工具所在地的MAC
	unsigned char src_mac[8]={0x00,0x0c,0x29,0xfa,0x7c,0x9e};//虚拟机MAC--源MAC
	memcpy(mac_head->ether_dhost,dst_mac,6);
	memcpy(mac_head->ether_shost,src_mac,6);
    //数据类型IP包
	mac_head->ether_type=htons(0x0800);

    //MAC的数据是IP包
	//组udp数据包的IP
	struct  iphdr *ip_head=(struct  iphdr *)(udp_buf+14);//跳过MAC包的首部
	ip_head->version = 4;
	ip_head->ihl =5;
	ip_head->tos =0;
	ip_head->tot_len =htons(20+8+date_len);//当前数据包长度,IP首部长度+IP数据,IP数据包含【UDP首部长度+键盘输入(UDP数据)】
	ip_head->id =htons(0);
	ip_head->frag_off=htons(0);
	ip_head->ttl=128;
	ip_head->protocol=17;//UDP协议类型
	ip_head->check=htons(0);//暂时未知,赋值0
	ip_head->saddr=inet_addr("10.36.145.56");//IP包中需要给定源IP
	ip_head->daddr=inet_addr("10.36.145.91");
	//当填充完ip所有数据重新计算校验和
    //校验IP包首部长度以内的成员,不带IP的数据
    //IP的数据是UDP
	ip_head->check=checksum((unsigned short *)(udp_buf+14), 20);


//------------------------------组udp数据包的UDP-----------------------------//
    //先对官方给定的UDP首部,赋值
	struct udphdr *udp_head=(struct  udphdr *)(udp_buf+14+20);//跳过MAC+IP的首部
	udp_head->source=htons(8000);//源(虚拟机)端口
	udp_head->dest=htons(8000);//目的(串口工具)端口
	udp_head->len=htons(8+date_len);//UDP包长度
	udp_head->check=htons(0);//暂时未知,赋值0
	
    //对伪UDP首部,人为设定一个结构体
    //内涵5个成员
    //udp检验和校验的是udp伪头部+其余内容,其余内容包含:(UDP首部+数据)
	//当填充完UDP所有数据重新计算检验和    
	unsigned char false_buf[1056] = "";
	 FALSE_HEAD *false_head = ( FALSE_HEAD *)false_buf;
	 false_head->saddr = inet_addr("10.36.145.56");
	 false_head->daddr = inet_addr("10.36.145.91");
	 false_head->flag = 0;
	 false_head->type = 17;
	 false_head->len = htons(8 + date_len);//UDP首部长度+键盘输入(UDP数据)

     //指针+,和数组名+不一样
     //将上面赋值过的UDP首部,拷贝给一个新整体中的UDP首部(新的整体包含【伪首部+UDP首部+数据】)
     //新的UDP首部是没有数据的,拷贝一下
	 memcpy(false_buf+12,udp_head,8);//false_buf+
	 memcpy(false_buf+12+8,buf,date_len);
    //UDP校验,校验全部,发送伪首部+UDP首部+数据
	udp_head->check=checksum((unsigned short *)false_buf,12+8+date_len);
	
	
	//组udp数据包的UDP数据部分
	memcpy(udp_buf+14+20+8,buf,date_len);
	
	
//-----------------------发送数据------------------------------//
//---发送MAC首部长度+IP首部长度+UDP首部长度+UDP数据----//
	int send_len=sendto(sockfd, udp_buf, 14+20+8+date_len, 0, (struct sockaddr *)&sll,sizeof(sll));
	printf("send_len=%dn",send_len);
	
	
	return 0;
}
#endif

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/277044.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号