- 浏览: 266330 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
AndMacLinuXp:
试了下,不错!
printk内核调试 -
klose:
我引用你的文章,并做了简单的分析:这里贴出url:http:/ ...
linux系统调用fork, vfork, clone -
klose:
你上面提到的问题:free的问题。首先你可能疏忽了,stack ...
linux系统调用fork, vfork, clone -
qwe_rt:
HI ,非常nice的文章,在阅读过程中,我发现我的ubunt ...
linux手动添加开机启动的服务 -
suifeng:
谢谢分享, 受用中.
shell编程分支,循环
一个小程序:
//发送方
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <time.h>
#include <sys/select.h>
struct mydata {
char data[12];
};
int main(int argc, char ** argv) {
struct mydata senddata;
strcpy(senddata.data, "hello world");
int sockfd;
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
bzero(&addr, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
inet_pton(AF_INET, argv[1], &addr.sin_addr);
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
char sendbuf[] = "hello world";
int sendbuf_len = sendto(sockfd, (void *)&senddata, sizeof(struct mydata), 0, (struct sockaddr *)&addr, addr_len);
printf("send len = %d\n", sendbuf_len);
close(sockfd);
}
//接受方
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <time.h>
#include <sys/select.h>
void proc_v4(char *);
struct mydata {
char data[12];
};
int main(int argc, char ** argv) {
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
char readbuf[100];
int ipv = atoi(argv[1]);
int len = read(sockfd, readbuf, ipv);
printf("len = %d\n", len);
proc_v4(readbuf);
close(sockfd);
}
void proc_v4(char * package) {
struct mydata * content;
struct ip * ip = (struct ip *)package;
struct in_addr from= ip->ip_src;
printf("from %s: ", inet_ntoa(from));
content = (struct mydata *)(package + sizeof(struct ip));
printf("%s\n", content->data);
}
原本网上有一些用原始套接字的例子,但我找了很久只有2个版本,一个是用原始套接字发送ICMP包,另一个则是发送TCP包(带有攻击性质)。发送ICMP包,指定的服务类型为ECHO回显服务,而这是由内核提供的,也就是说我们必须要自己来写接受方,只要发送出去即可。TCP例子则是不停的向同一台机器发送请求连接的SYN包。缺点是:本来学习的主题是原始套接口,而这2个例子还要带上对TCP和ICMP的学习。(笔者太笨了,写了很久也没有让ICMP回显,可能是ICMP头部写的有问题,包被主机忽略了)。
我这里依然采用的是ICMP协议,但我没有自己写ICMP包头,只是简单把要传递的信息放入了ICMP包中,内核依然会将其送入接受的套接口中。
1.原始套接口创建
sockfd = socket(AF_INET, SOCK_RAW, 86);
第一个参数很熟悉了,表示IPV4,SOCK_RAW表示原始套接字,最后的86是我乱写。第3个参数可选值很多IPPROTO_ICMP或者IPPROTO_TCP。如果是IPPROTO_ICMP表示通过这个原始套接字发送的IP包中带的数据将会是ICMP包,依次理解IPPROTO_TCP则表示带为TCP包。而86则是内核没有支持的协议或者说内核不认识的协议。这些将会影响接受方内核对IP数据包的处理。
2.原始套接口输出
端口对原始套接口是没有意义的,一般使用sendto或者sendmsg发送,当然可以调用connect的原始套接字,则可以直接使用write。超过MTU的会被分片。
3.原始套接口的输入
回忆一下TCP和UDP,他们都是通过端口号和地址来找到接受进程。而原始套接口则不同。它遵循以下几个规则:
a.如果发送方创建时候使用的socket(AF_INET,SOCK_RAW, IPPROTO_TCP),也就是从这个套接口出来的为TCP包,或者UDP包不会传递给任何原始套接口,他们将直接递交给TCP或者UDP协议处理。所以要想抓TCP或者UDP包,用原始套接口无法实现。
b.如果发送的是ICMP数据,除了回射,时间戳,地址掩码请求完全有内核处理,所有接受到的都将传递给某个原始套接口。(我理解是只要你创建了原始套接字,则这个套接字就会收到这个包的一个拷贝)。
c.如果是IGMP数据,所有IGMP分组将会传递某个原始套接口。
d.不能识别的协议字段,例如我上面的86,都将传递某个原始套接口。
e.被分片的包会重组再按照abcd处理。
f.ip包会进行版本,头部校验和,头部长度以及目的地址检查。检查不合格者会丢弃。
4.套接口选项IP_HDRINCL
上面程序比较简单,我没有打开这个选项,如果打开这个选项,则你写入的数据会从IP包头部开始,也就是说你需要写IP头部。
一个打开了IP_HDRINCL的原始套接字样例,接受方仍然可以采用原来的程序,这个程序修改了发送者的IP
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <time.h>
#include <sys/select.h>
//计算IP头部校验和的算法
unsigned short csum(unsigned short * buf, int nwords) {
unsigned long sum;
for(sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (unsigned short)(~sum);
}
struct mydata {
char data[12];
};
int main(int argc, char ** argv) {
char buf[400];
struct ip * ip_head = (struct ip *)buf;
struct mydata * senddata = (struct mydata *)(buf + sizeof(struct ip));
int one = 1;
const int * val = &one;
memset(buf, 0, 400);
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
bzero(&addr, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
inet_pton(AF_INET, argv[1], &addr.sin_addr);
//init ip head
ip_head->ip_hl = 5; //头部长度
ip_head->ip_v = 4;//ip版本号
ip_head->ip_tos = 16;
ip_head->ip_p = IPPROTO_ICMP; //服务类型
inet_pton(AF_INET, argv[1], &ip_head->ip_dst); //指定目的IP地址
inet_pton(AF_INET, "192.168.1.23", &ip_head->ip_src); //指定源IP地址,这里可以随便指定,不一定要是本机IP地址,当然如果不是本机地址,对方获得的就是错误地址,原始套接口没有确认包返回,所以不会有影响,但如果期望对方返回信息的话,就要填自己的IP地址。
strcpy(senddata->data, "hello world");
setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one));
ip_head->ip_sum = csum((unsigned short *) buf, sizeof(struct ip) + sizeof(struct mydata));//计算校验和
sendto(sockfd, buf, ip_head->ip_len, 0, (struct sockaddr *)&addr, sizeof(addr));
close(sockfd);
exit(0);
}
发表评论
-
hdfs集群搭建
2014-05-11 17:19 998网上很多hadoop集群搭建的文章,我这里只写下hdfs,不 ... -
网站性能优化
2013-10-25 10:43 0好久没写了,最近一直在做些互联网的一些东西。下面介绍些性能优 ... -
html5学习网站
2011-07-29 14:55 902htm5:http://www.w3school.com.cn ... -
HTTP下载
2011-02-09 15:24 1082HTTP下载的关键是修改Content-Type。 C ... -
28.sniffer程序2
2010-07-01 17:51 1767对前面27中sniffer中的一 ... -
27. sniffer程序
2010-06-30 11:51 5909网络抓包,必需从数据链路层开始抓取,至于原因之前在原始套接口中 ... -
java 和 linux c udp通信的样例
2010-05-28 11:58 2463一个简单的例子 java段(客户端) package ... -
25.cookies和session
2010-05-10 15:21 893原文出自:http://blog.csdn ... -
24.SOCKET模拟HTTP请求
2010-05-07 14:11 5318HTTP请求头部样例: GET http://www.bai ... -
23.广播
2010-04-29 16:34 940如果想发送广播到目前为止只能使用AF_INET, SOCK_D ... -
22.非阻塞connect
2010-04-28 11:36 2714connect非阻塞套接口时候,一般使用在以下几种情况: ... -
21.非阻塞I/O
2010-04-27 16:54 2071设置一个I/O成为非阻塞很简单,只需要: int val = ... -
20.辅助数据 和 传输描述字
2010-04-26 15:53 2063打开一个文件或者一个 ... -
19.unix域协议与TCP UDP不同之处
2010-04-22 13:46 2613之前说过一些区别,但基本对我们编程来说没有太多影响,但以下几个 ... -
18.unix域协议
2010-04-21 16:47 2621UNIX域协议并不是一个真正的协议族,它是用在同一台主机上进行 ... -
17.I/O函数recvmsg与sendmsg
2010-04-20 15:58 12420想对于之前的几个IO函 ... -
16.I/O函数
2010-04-20 13:51 1240最早使用的read与write函 ... -
15.服务器守护进程
2010-04-16 17:44 1394前面提到过的服务器都占有控制终端。而有些进程并不需要控制终端。 ... -
14.udp与connect
2010-04-13 16:41 3210UDP在调用sendto发送数据 ... -
13.UDP编程
2010-04-09 17:16 2255虽然UDP不保证传输的可 ...
相关推荐
易语言原始套接字应用源码,原始套接字应用,显示信息,窗口消息处理,数据到达,异步通讯安装,异步通讯卸载,异步选择,异步处理,异步返回,UnHOOK,HOOKFunc,HOOKAPI,GetFunc,changefunc,CallFunc,数值_无符号_短整数,内存_...
原始套接字 这里有原始套接字的创建、使用等
ICMP Ping实现-Ping客户端创建原始套接字ICMP Ping实现-Ping客户端创建原始套接字ICMP Ping实现-Ping客户端创建原始套接字ICMP Ping实现-Ping客户端创建原始套接字ICMP Ping实现-Ping客户端创建原始套接字ICMP Ping...
原始套接字概述 原始套接字的创建 通过原始套接字发送数据 通过原始套接字接收数据
在将原始套接字设置完毕,使其能按预期目的工作时,就可以通过recv()函数从网卡接收数据了,接收到的原始数据包存放在缓存RecvBuf[]中,缓冲区长度BUFFER_SIZE定义为65535。然后就可以根据前面对IP数据段头、TCP数据...
尽做为想了解原始套接字或研究sniffer的朋友做示范操作 只要你具备相应的权限 只要在本机上运行本demo附带的exe 当你操作网络的时候就会把通过本机网卡的数据 给截获下来再gridlist中展示出来 目前只截获tcp udp ...
使用C语言实现原始套接字从数据链路层到应用层的操作,Linux系统
原始套接字
原始套接字 主要是linux 网络方面 原始套接字 主要是linux 网络方面
syn flood c的简易实现,编译即可
易语言源码易语言原始套接字应用源码.rar
原始套接字编程源码 SOCKET编程 AnalyzeETH_WinPcap
本文使用windows sockets 的原始套接字实现IP数据包的捕获与解析,有详细的设计过程,并附有源代码,源代码中有注释。
非利用WINPCAP,而是直接利用WINDOWS的原始套接字,可以把网卡改为混杂模式!是新手学习好好例子!
linux原始套接字编程,利用原始套接字实现arp请求和接收源代码
采用C++语言,基于原始套接字实现了Ping和Tracert命令。发送主机通过ping程序给目标主机发送ICMP的回声请求报文,并根据收到的ICMP回声应答报文来确定网络的连通性。Tracert(跟踪路由)是路由跟踪实用程序,用于...
原始套接字测试程序
实验3_使用原始套接字实现ping的工作原理.docx实验3_使用原始套接字实现ping的工作原理.docx实验3_使用原始套接字实现ping的工作原理.docx实验3_使用原始套接字实现ping的工作原理.docx实验3_使用原始套接字实现ping...
windows原始套接字,利用RAW Socket实现网络数据包抓包分析,读取网络数据
网络编程,原始套接字编程实验实验。具体功能如下: IP首部的构造;基于原始套接字的分片ICMP ECHO请求发送功能;基于原始套接字的ICMP ECHO响应接收功能;重叠分片的发送功能; 可以用来测试windows系统和Linux系统...