- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我做了一个简单的 ping 程序,因为我创建了一个 buffer 并且只有我填充了 IP frame
和 icmp 结构
,当我运行该程序时它工作正常。
我查看了 Wireshark 中的执行情况,以太网帧已正确包含在具有正确目标 MAC 地址 的回显请求中( MAC 可能会在 arp 缓存中找到),但是即使我没有将其填充到我在 sock_raw
套接字通信中使用的缓冲区中,以太网帧也会自动创建。
另一个问题是我的 friend 尝试了相同的代码,但是当他在 ethernet header 中检查 Wireshark 时,MAC 地址是 00.00.00.00.00.00 ,这意味着它将发送到每个设备,并且具有正确 IP 的相应设备将回复,但对我来说不是这样
代码在这里
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUFFER_SIZE 100
#define DEFAULT_NUM_PACKETS 10
char buf[BUFFER_SIZE];
char *message = "\n ./output_file <sender_ip_addr> <dest_ip_addr> <no_of_reqs>\n \
<no_of_req> = is the number of requests to send and 10 is the default and mentioning 0 is infinite\n";
void set_ip_layer_fields(struct icmphdr *icmp, struct ip *ip)
{
// IP layer
ip->ip_v = 4;
ip->ip_hl = sizeof*ip >> 2;
ip->ip_tos = 0;
ip->ip_len = htons(sizeof(buf));
ip->ip_id = 0;
ip->ip_off = 0;
ip->ip_ttl = 255;
ip->ip_p = 1;
ip->ip_sum = 0;
// ICMP Layer
icmp->type = 8;
icmp->code = 0;
icmp->checksum = htons(~(ICMP_ECHO << 8));
}
int main(int argc, char *argv[])
{
int s, i ;
struct ip *ip = (struct ip *)buf;
struct icmphdr *icmp = (struct icmphdr *)(ip + 1);
struct hostent *hp, *hp2;
struct sockaddr_in dst;
int num = DEFAULT_NUM_PACKETS;
if(argc < 3)
{
fprintf(stdout, "%s\n",message);
exit(1);
}
// If enough arguments supplied
if(argc == 4)
num = atoi(argv[3]);
// Loop based on the no of requests
for(i = 1; num == 0 ? num == 0 : i <= num; i++)
{
memset(buf, 0, sizeof(buf));
if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
{
perror("socket() error");
exit(1);
}
if((hp = gethostbyname(argv[2])) == NULL)
{
if((ip->ip_dst.s_addr = inet_addr(argv[2])) == -1)
{
fprintf(stderr, "%s: unknown host.\n", argv[2]);
exit(1);
}
}
else
memcpy(&ip->ip_dst.s_addr, hp->h_addr_list[0], hp->h_length);
if((hp2 = gethostbyname(argv[1])) == NULL)
{
if((ip->ip_src.s_addr = inet_addr(argv[1])) == -1)
{
fprintf(stderr, "%s: unknown host\n", argv[1]);
exit(1);
}
}
else
memcpy(&ip->ip_src.s_addr, hp2->h_addr_list[0], hp->h_length);
set_ip_layer_fields(icmp, ip);
dst.sin_addr = ip->ip_dst;
dst.sin_family = AF_INET;
if(sendto(s, buf, sizeof(buf), 0, (struct sockaddr *)&dst, sizeof(dst)) < 0)
{
fprintf(stderr, "error while sending\n");
}
else
printf("request:%d sended successfully\n",i);
close(s);
}
return 0;
}
最佳答案
区别在于您声明套接字的方式。
使用 IPPROTO_RAW
- 为您提供以太网 header ,您提供从 IP header 开始的所有内容。
使用 htons(ETH_P_ALL)
- 您提供所有内容,包括以太网 header 。
更多信息在这里:http://www.pdbuchan.com/rawsock/rawsock.html
同时使用 IPPROTO_RAW
意味着选项 IP_HDRINCL
是隐式设置的,这意味着 IP 是从数据包中的 IP header 使用的,而不是放在 中的信息>发送到
。
通常,如果您在原始套接字中指定所有内容,您会使用 send
而不是 sendto
,因为所有要发送的信息都在 header 中可用。
在此处阅读有关 IP_HDRINCL
的更多信息:http://man7.org/linux/man-pages/man7/raw.7.html
关于c++ - 在 SOCK_RAW 通信中创建以太网帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22149452/
我正在开发类似 netcat 的工具(主要用于自学)。我想发送带有我通过 SOCK_RAW 套接字构造的 IP 和 UDP header 的数据包。我在 Debian VM 上运行以下代码以通过套接字
我是套接字编程的新手,正在Linux机器(ubuntu)上尝试使用它 我无法理解选项“SOCK_RAW”,并且想要了解它。 “套接字”系统调用中“SOCK_RAW”选项的意义是什么? 最佳答案 原始模
我想做同样的事情,在开源应用程序中将 SOCK_DGRAM 转换为 SOCK_RAW。 在 sendto 函数中,当套接字为 SOCK_DGRAM 类型时,然后仅发送 RTP 像这样的数据 这里,m-
我的问题已被here粗略地讨论过。 而tl; dr解决方案是: iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP 您可以修改此设置,以仅阻止您
我做了一个简单的 ping 程序,因为我创建了一个 buffer 并且只有我填充了 IP frame 和 icmp 结构,当我运行该程序时它工作正常。 我查看了 Wireshark 中的执行情况,以太
我正在开发一个开源软件,其中 SOCK_DGRAM 用于发送 RTP 数据包。 像这样: int sock = socket(af, SOCK_DGRAM, 0); 但我应该使用与 SOCK_RAW
我正在尝试实现一个 IPv6 UDP 客户端-服务器应用程序,它将让我获得逐跳扩展 header 的详细信息。因此,为此我想我必须使用 SOCK_RAW 来访问 IPv6 header 信息。 现在在
#include #include #include #include #include #include #include #include #include #include
如果我创建一个类型为 SOCK_RAW 的套接字仅发送一些数据而不接收任何数据,当内核继续接收网络数据包并将其数据报复制到某个缓冲区(应用程序?)时是否有任何问题。也就是说,somebuffer被填满
好吧,我意识到这种情况有点不寻常,但我需要仅使用原始套接字(在 C 中,在 Linux 中)建立 TCP 连接(3 次握手)——即我需要构造 IP header 和我自己的 TCP header 。我
所以我用 socket(AF_INET, SOCK_RAW, IPPROTO_UDP) 创建了一个套接字。然后我有一个无限循环的 recv() 。我知道它可以捕获所有数据报。但它会阻止数据报到达正确的
soc = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));在客户端,运行时,得到== -1错误 如果accept函数只能与UDP和TCP高层协议(prot
我最近一直在研究网络与 c 代码和密码学,在思考随机问题时,我偶然发现了一段用于数据包嗅探的代码,我对函数 中使用的实际套接字有疑问从()接收()。套接字通过以下 sock 函数 rawSock =
好吧,我意识到这种情况有点不寻常,但我需要仅使用原始套接字(在 C 中,在 linux 中)建立 TCP 连接(3 次握手)——即我需要构建 IP header 和我自己的 TCP header 。我
我在 Windows 上创建了一个 ping 实用程序。我正在使用带有 ICMP 协议(protocol)的原始套接字。我是我电脑的本地管理员。 由于代码很多,我不想在这里粘贴,但我找到了一个与我的非
我正在尝试发送数据包(不是 ip 数据包,而是 EAP 请求标识),但是 send() 函数返回 -1。 int sockfd = socket(AF_INET, SOCK_RAW, 0);
大家好,我有个问题,我似乎找不到关于在多播上发送原始数据包的文档,所有示例、解决方案和文档都以 UDP 用法为中心。 我以此为例:http://svn.python.org/projects/stac
在 C 中的 linux 上,设置接口(interface) PROMISC 并使用原始套接字后,我可以通过 read() 读取接口(interface)上的传入数据包。 然而,它并没有得到所有的数据
如果我使用以下参数和默认设置打印出在 RAW 套接字上发送的 IP header 的 header 字段值,我看到协议(protocol)号设置为“2”,属于 IGMP。 sock = socket
我正在尝试在 Linux (Ubuntu 18.04) 上的 C 中创建一个测试程序,该程序使用 SOCK_RAW 通过 AF_PACKET/PF_PACKET 套接字发送一个空的 UDP 数据包.在
我是一名优秀的程序员,十分优秀!