- 浏览: 271905 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
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 1054网上很多hadoop集群搭建的文章,我这里只写下hdfs,不 ... -
网站性能优化
2013-10-25 10:43 0好久没写了,最近一直在做些互联网的一些东西。下面介绍些性能优 ... -
html5学习网站
2011-07-29 14:55 983htm5:http://www.w3school.com.cn ... -
HTTP下载
2011-02-09 15:24 1140HTTP下载的关键是修改Content-Type。 C ... -
28.sniffer程序2
2010-07-01 17:51 1809对前面27中sniffer中的一 ... -
27. sniffer程序
2010-06-30 11:51 5971网络抓包,必需从数据链路层开始抓取,至于原因之前在原始套接口中 ... -
java 和 linux c udp通信的样例
2010-05-28 11:58 2510一个简单的例子 java段(客户端) package ... -
25.cookies和session
2010-05-10 15:21 992原文出自:http://blog.csdn ... -
24.SOCKET模拟HTTP请求
2010-05-07 14:11 5392HTTP请求头部样例: GET http://www.bai ... -
23.广播
2010-04-29 16:34 978如果想发送广播到目前为止只能使用AF_INET, SOCK_D ... -
22.非阻塞connect
2010-04-28 11:36 2806connect非阻塞套接口时候,一般使用在以下几种情况: ... -
21.非阻塞I/O
2010-04-27 16:54 2105设置一个I/O成为非阻塞很简单,只需要: int val = ... -
20.辅助数据 和 传输描述字
2010-04-26 15:53 2128打开一个文件或者一个 ... -
19.unix域协议与TCP UDP不同之处
2010-04-22 13:46 2681之前说过一些区别,但基本对我们编程来说没有太多影响,但以下几个 ... -
18.unix域协议
2010-04-21 16:47 2668UNIX域协议并不是一个真正的协议族,它是用在同一台主机上进行 ... -
17.I/O函数recvmsg与sendmsg
2010-04-20 15:58 12511想对于之前的几个IO函 ... -
16.I/O函数
2010-04-20 13:51 1291最早使用的read与write函 ... -
15.服务器守护进程
2010-04-16 17:44 1434前面提到过的服务器都占有控制终端。而有些进程并不需要控制终端。 ... -
14.udp与connect
2010-04-13 16:41 3264UDP在调用sendto发送数据 ... -
13.UDP编程
2010-04-09 17:16 2328虽然UDP不保证传输的可 ...
相关推荐
### 原始套接字的创建及其应用 #### 一、引言 在计算机网络领域,原始套接字(Raw Socket)是一种特殊类型的套接字,它允许应用程序直接访问并控制网络协议栈中的底层传输协议。通过使用原始套接字,开发人员可以...
在Windows操作系统中,原始套接字(RAW Socket)是一种特殊类型的网络套接字,它允许程序员直接访问网络层,而不受传输层协议(如TCP或UDP)的限制。这种功能对于网络数据分析、网络安全检测和协议开发等场景非常...
易语言原始套接字应用源码,原始套接字应用,显示信息,窗口消息处理,数据到达,异步通讯安装,异步通讯卸载,异步选择,异步处理,异步返回,UnHOOK,HOOKFunc,HOOKAPI,GetFunc,changefunc,CallFunc,数值_无符号_短整数,内存_...
原始套接字是一种特殊的网络套接字,允许用户直接处理IP协议数据包,而不经过标准的传输层协议如TCP或UDP封装。这种套接字在Linux操作系统中广泛应用于网络编程和管理,尤其适用于需要直接操纵网络层数据的应用程序...
原始套接字是一种低级别的网络通信机制,允许程序员直接操作网络协议栈的底层,从而能够执行高级网络编程任务。在大多数常规的网络编程中,我们使用的流式套接字(SOCK_STREAM)和数据报式套接字(SOCK_DGRAM)分别...
基于Winsock原始套接字的IP数据包捕获与解析 在计算机网络课程设计中,捕获和解析IP数据包是非常重要的一步。今天,我们将使用Windows Sockets(Winsock)的原始套接字来实现IP数据包的捕获和解析。本文将详细介绍...
ICMP Ping实现-Ping客户端创建原始套接字ICMP Ping实现-Ping客户端创建原始套接字ICMP Ping实现-Ping客户端创建原始套接字ICMP Ping实现-Ping客户端创建原始套接字ICMP Ping实现-Ping客户端创建原始套接字ICMP Ping...
标题中的“利用原始套接字写的网络数据捕获”指的是在网络编程中,通过使用操作系统提供的原始套接字(Raw Sockets)来实现网络数据的捕获和分析,而不是依赖于像WinPcap这样的第三方库。这种方法对于理解网络协议...
在将原始套接字设置完毕,使其能按预期目的工作时,就可以通过recv()函数从网卡接收数据了,接收到的原始数据包存放在缓存RecvBuf[]中,缓冲区长度BUFFER_SIZE定义为65535。然后就可以根据前面对IP数据段头、TCP数据...
原始套接字(Raw Sockets)是网络编程中一种特殊类型的套接字,它允许程序员直接操作IP层的数据包,而不仅仅是应用层的协议。在操作系统中,通常只有管理员权限的用户才能使用原始套接字,因为它们可以用来构建、...
原始套接字(Raw Sockets)是网络编程中一种特殊类型的套接字,允许程序员直接操作网络协议的底层,而不依赖于操作系统提供的更高层次的服务。它们通常用于网络诊断、网络测试以及开发自定义的网络协议。在C#中,...
尽做为想了解原始套接字或研究sniffer的朋友做示范操作 只要你具备相应的权限 只要在本机上运行本demo附带的exe 当你操作网络的时候就会把通过本机网卡的数据 给截获下来再gridlist中展示出来 目前只截获tcp udp ...
原始套接字监听是一种高级网络编程技术,它允许程序员直接操作网络层的数据包,而不仅仅是应用层的协议。在标题“原始套接字监听”中,我们关注的是使用原始套接字来监听和分析网络流量,这在网络安全、监控、故障...
使用C语言实现原始套接字从数据链路层到应用层的操作,Linux系统
原始套接字
原始套接字(Raw Socket)是网络编程中的一个重要概念,它允许程序员直接操作TCP/IP协议栈,而不必受限于标准的TCP、UDP等高层协议。在这个主题中,“原始套接字发送iCMP自定义头部版本”指的是利用原始套接字来创建...
Linux操作系统中的网络编程涉及到各种类型的套接字,包括TCP套接字、UDP套接字以及原始套接字。原始套接字(SOCK_RAW)是一种特殊的套接字类型,允许程序员对网络协议栈进行更底层的控制。在这个场景下,我们将深入...
原始套接字(Raw Sockets)是网络编程中一种特殊类型的套接字,它允许程序员直接操作网络协议的底层细节,如IP头、TCP头或UDP头等。在大多数操作系统中,原始套接字通常与低级别的网络协议交互,如IPv4(IPPROTO_IP...
采用C++语言,基于原始套接字实现了Ping和Tracert命令。发送主机通过ping程序给目标主机发送ICMP的回声请求报文,并根据收到的ICMP回声应答报文来确定网络的连通性。Tracert(跟踪路由)是路由跟踪实用程序,用于...
syn flood c的简易实现,编译即可