原始套接字-自定义IP首部和TCP首部
/* =====================================================================================
*
* Filename: raw.c
* Description: 使用原始套接字发送TCP协议,并外带自己的数据。
*
* ====================================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#define DATA "hello"
#define PACKET_SIZE sizeof(struct iphdr) + sizeof(struct tcphdr) + sizeof(DATA) /*---------------------------------------------------------
Function Name : check_sum()
Descrypthon : 校验和计算,摘自UNP源码
------------------------------------------------------------*/
unsigned short check_sum(unsigned short *addr, int len)
{
int nleft = len;
int sum = ;
unsigned short *w = addr;
short answer = ;
while (nleft > )
{
sum += *w++;
nleft -=;
}
if (nleft == )
{
*(unsigned char *)(&answer) = *(unsigned char *)w;
sum += answer;
}
sum = (sum >> ) + (sum & 0xffff);
sum += (sum >> );
answer = ~sum;
return answer;
} /*---------------------------------------------------------
Function Name : init_socket()
Descrypthon : 初始化socket,使用原始套接字
parameter : P1 一个待初始化的原始套接字,P2 待初始化的目标地址结构,P3 目标地址,P4 目标端口
return : 返回一个原始套接字,在函数体内将目标地址结构进行初始
------------------------------------------------------------*/
int init_socket(int sockfd, struct sockaddr_in *target,const char *dst_addr, const char *dst_port)
{
const int flag = ;
//目标协议簇
target->sin_family = AF_INET;
//目标端口
target->sin_port = htons(atoi(dst_port)); //将dst_addr中的ASCII-IP地址更新到target->sin_addr结构中
if (inet_aton(dst_addr, &target->sin_addr) == )
{
perror("inet_aton fail\n");
exit(-);
}
//初始化原始套接字
if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < )
{
perror("error");
exit(-);
}
//设置套接字×××
if (setsockopt(sockfd,IPPROTO_IP, IP_HDRINCL, &flag, sizeof(flag)) < )
{
perror("setsockopt fail \n");
exit(-);
}
return sockfd;
} /*---------------------------------------------------------------
Function Name : buile_iphdr()
Descrypthon : 构建IP头部数据, 源地址使用伪随机地址
-----------------------------------------------------------------*/
void buile_iphdr(struct sockaddr_in *target, char *buffer)
{
struct iphdr *ip = (struct iphdr *)(buffer);
ip->version = ;//版本
ip->ihl = ;//首部长度 5*4 = 20
ip->tos = ;//8位服务类型
ip->tot_len = htons(PACKET_SIZE);//16位总长度
ip->id = ;//16位标识符
ip->frag_off = ;//3位标志
ip->ttl = ;//生存时间
ip->protocol = IPPROTO_TCP;//协议
ip->check = check_sum((unsigned short *)ip, sizeof(struct iphdr) + sizeof(DATA));//16位首部校验和
ip->saddr = random();//源ip地址
ip->daddr = target->sin_addr.s_addr;//目标ip地址
} /*---------------------------------------------------------------
Function Name : buile_tcphdr()
Descrypthon : 构建TCP头部信息,并加入一些自己的数据,然后进行
校验计算。
-----------------------------------------------------------------*/
void buile_tcphdr(struct sockaddr_in *target, const char *src_port, char *buffer)
{
struct tcphdr *tcp = (struct tcphdr *)(buffer);
tcp->source = htons(atoi(src_port));//16位源端口号
tcp->dest = target->sin_port;//16位目的端口号
tcp->seq = random();//32位序号
tcp->doff = ;//
tcp->syn = ;//同步序号
buffer += sizeof(struct tcphdr);
tcp->check = check_sum((unsigned short *)tcp, sizeof(struct tcphdr) + sizeof(DATA));//16位检验和
memcpy(buffer, DATA, sizeof(DATA));//将DATA中的数据拷贝sizeof(DATA)字节到buffer所指的地址中
}
int main(int argc, const char *argv[])
{
char *buffer;
char *buffer_head = NULL;
int sockfd = ;
struct sockaddr_in *target;
if (argc != )
{
printf("usage: destination addresss, destination port, source port \n");
exit(-);
}
const char *dst_addr = argv[];
const char *dst_port = argv[];
const char *src_port = argv[]; target = calloc(sizeof(struct sockaddr_in),);
//calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。
buffer = calloc(PACKET_SIZE, );
buffer_head = buffer; //初始化套接字
sockfd = init_socket(sockfd, target, dst_addr, dst_port);
//创建IP首部
buile_iphdr(target, buffer);
buffer += sizeof(struct iphdr);//指针下移
//创建TCP首部
buile_tcphdr(target, src_port, buffer);
//发送
sendto(sockfd, buffer_head, PACKET_SIZE, ,(struct sockaddr *)target, sizeof(struct sockaddr_in)); //下两行是对calloc申请的释放
free(buffer_head);
free(target);
return ;
}
原始套接字-自定义IP首部和TCP首部的更多相关文章
- UNP——原始套接字
1.原始套接字的用处 使用原始套接字可以构造或读取网际层及其以上报文. 具体来说,可以构造 ICMP, IGMP 协议报文,通过开启 IP_HDRINCL 套接字选项,进而自定义 IPv4首部. 2. ...
- Linux系统编程(37)—— socket编程之原始套接字
原始套接字的特点 原始套接字(SOCK_RAW)可以用来自行组装IP数据包,然后将数据包发送到其他终端.也就是说原始套接字是基于IP数据包的编程(SOCK_PACKET是基于数据链路层的编程).另外, ...
- UNIX网络编程——原始套接字SOCK_RAW
实际上,我们常用的网络编程都是在应用层的报文的收发操作,也就是大多数程序员接触到的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM).而这些数据包都是由系统提供的协议栈实现, ...
- raw_socket(原始套接字)以及普通socket使用终极总结
一.传输层socket(四层socket,普通socket) 可参考本人以下博客: Windows Socket编程之UDP实现大文件的传输:http://blog.csdn.net/luchen ...
- 005.TCP--拼接TCP头部IP头部,实现TCP三次握手的第一步(Linux,原始套接字)
一.目的: 自己拼接IP头,TCP头,计算效验和,将生成的报文用原始套接字发送出去. 若使用tcpdump能监听有对方服务器的包回应,则证明TCP报文是正确的! 二.数据结构: TCP首部结构图: s ...
- 004.UDP--拼接UDP数据包,构造ip头和udp头通信(使用原始套接字)
一.大致流程: 建立一个client端,一个server端,自己构建IP头和UDP头,写入数据(hello,world!)后通过原始套接字(SOCK_RAW)将包发出去. server端收到数据后,打 ...
- python使用原始套接字 解析原始ip头数据
使用底层套接字解码底层流量,是这次做的重点工作. 首先来捕获第一个包 # coding:utf-8import socket # 监听的主机IP host = "192.168.1.100& ...
- C++ Win 32 使用原始套接字获取所有ip数据包并分析(包括ping包)
/*页面编码:GBK 开发环境 VS2019 */ #define _WINSOCK_DEPRECATED_NO_WARNINGS#include <iostream>#include&l ...
- linux原始套接字(4)-构造IP_UDP
一.概述 同上一篇tcp一样,udp也是封装在ip报文里面.创建UDP的原始套接字如下: (soc ...
随机推荐
- linux AB web 性能测试工具
ab(选项)(参数) 选项 -A:指定连接服务器的基本的认证凭据: -c:指定一次向服务器发出请求数: -C:添加cookie: -g:将测试结果输出为“gnuolot”文件: -h:显示帮助信息: ...
- ERP条码解决方案,金蝶盘点机条码解决方案,应用PDA的信息化管理能给我们的生产管理带来怎么样的变化的探讨
ERP条码解决方案,金蝶盘点机条码解决方案,应用PDA的信息化管理能给我们的生产管理带来怎么样的变化的探讨. 当前越来越多的大大小小的中国企业已经接受了ERP的思想,大多数的商店,企业,工厂都会上一套 ...
- MAC下搭建Hexo博客
一.前言 Hexo是一款快速.简洁,基于node.js的强力框架. (1)超快速度:Node.js 所带来的超快生成速度,让上百个页面在几秒内瞬间完成渲染. (2)支持markdown:Hexo 支持 ...
- 笛卡尔遗传规划Cartesian Genetic Programming (CGP)简单理解(1)
初识遗传算法Genetic Algorithm(GA) 遗传算法是计算数学中用于解决最优化的搜索算法,是进化算法的一种.进化算法借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传.突变.自然选 ...
- LeetCode 88. 合并两个有序数组
题目: 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 m ...
- Daily Scrum - 12/01
Meeting Minutes 今天重阳去和UI设计团队的人去讨论UI方面的事宜了,剩下的人主要还是在讨论文件输入输出的事.目前总算是能实现文件存取了,尽量在明天前把文件的格式内容都弄好. Burnd ...
- redis 事务,持久化,日志,主从,VM
redis目前对事务的支持比较简单,只能保证一个客户端连接发起事务中的命令可以连续执行,而中间不会插入其他客户端的命令. 1.事务 一般情况下,redis接收到一个客户端发送的命令,立刻执行并返回结果 ...
- Exchange2010批量删除邮件
在Exchange2010里若要删除某个用户发出的邮件,可以通过EMC控制台授予管理员“管理完全访问权限”,通过OWA登录到用户邮箱删除.另外,更简便的方法为使用Exchange2010的命令来处理, ...
- Threadlocal 传递参数(百度二面)
去百度面试,二面的时候 面试官问 如果我想跟踪一个请求,从接收请求,处理到返回的整个流程,有没有好的办法,后来面试官说了 Threadlocal 可以做到传递参数. 这是ThreadLocal的一个功 ...
- ehcache、redis应用场景比较
应用场景: ehcache是Hibernate中默认的CacheProvider,直接在jvm虚拟机中缓存,速度快,效率高:但是缓存共享麻烦,集群分布式应用不方便. . 缓存数据有两级:内存和磁盘, ...