- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在这个网站上引用了 C 代码:https://gist.github.com/austinmarton/2862515
这是一张图片来解释:
我分两部分编辑,一个是ethertype(将0x0800更改为自定义协议(protocol)0x1234)
另一部分是删除 IP header 处理的代码(因为原始代码基于 IP,但我需要一个原始以太网帧)。
我使用wireshark检测数据包,我可以收到我发送的数据包(在图片左侧),我可以看到send.out正在发送数据包(图片右下角)。但是 recv.out 无法接收数据包!?(图像右上角)。
但是,如果我使用 0x0800 作为协议(protocol),recv.out 可以接收来自外部的数据包,但仍然无法接收我发送的数据包。
设置socket有没有错误
这是我的代码:
发送.c
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#define MY_DEST_MAC0 0xbc
#define MY_DEST_MAC1 0xee
#define MY_DEST_MAC2 0x7b
#define MY_DEST_MAC3 0x75
#define MY_DEST_MAC4 0x56
#define MY_DEST_MAC5 0x2a
#define DEFAULT_IF "eth0"
#define BUF_SIZ 1024
int main(int argc, char *argv[])
{
int sockfd;
struct ifreq if_idx;
struct ifreq if_mac;
int tx_len = 0;
char sendbuf[BUF_SIZ];
struct ether_header *eh = (struct ether_header *) sendbuf; /*structure*/
struct iphdr *iph = (struct iphdr *) (sendbuf + sizeof(struct ether_header));
struct sockaddr_ll socket_address;
char ifName[IFNAMSIZ];
unsigned short proto = 0x1234;
/* Get interface name *//*eth0*/
if (argc > 1)
strcpy(ifName, argv[1]);
else
strcpy(ifName, DEFAULT_IF);
/* Open RAW socket to send on *//*IPv4*/
if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(proto))) == -1) {
perror("socket");
}
/* Get the index of the interface to send on *//*0*/
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, ifName, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)/*save INDEX info into if_idx*/
perror("SIOCGIFINDEX");
/* Get the MAC address of the interface to send on *//*local*//*save MAC info into if_mac*/
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, ifName, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
perror("SIOCGIFHWADDR");
/* Construct the Ethernet header */
memset(sendbuf, 0, BUF_SIZ);
/* Ethernet header */
eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0];
eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1];
eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2];
eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3];
eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4];
eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5];
eh->ether_dhost[0] = MY_DEST_MAC0;
eh->ether_dhost[1] = MY_DEST_MAC1;
eh->ether_dhost[2] = MY_DEST_MAC2;
eh->ether_dhost[3] = MY_DEST_MAC3;
eh->ether_dhost[4] = MY_DEST_MAC4;
eh->ether_dhost[5] = MY_DEST_MAC5;
/* Ethertype field */
eh->ether_type = htons(proto);
tx_len += sizeof(struct ether_header);
/* Packet data */
sendbuf[tx_len++] = "h";
sendbuf[tx_len++] = "e";
sendbuf[tx_len++] = "l";
sendbuf[tx_len++] = "l";
sendbuf[tx_len++] = "o";
/* Index of the network device */
socket_address.sll_ifindex = if_idx.ifr_ifindex;
/* Address length*/
socket_address.sll_halen = ETH_ALEN;
/* Destination MAC */
socket_address.sll_addr[0] = MY_DEST_MAC0;
socket_address.sll_addr[1] = MY_DEST_MAC1;
socket_address.sll_addr[2] = MY_DEST_MAC2;
socket_address.sll_addr[3] = MY_DEST_MAC3;
socket_address.sll_addr[4] = MY_DEST_MAC4;
socket_address.sll_addr[5] = MY_DEST_MAC5;
/* Send packet */
int cnt=0;
while(cnt<5){
if (sendto(sockfd, sendbuf, tx_len, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0)
printf("Send failed\n");
else
printf("success!\n");
cnt++;
}
return 0;
}
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#define DEST_MAC0 0xbc
#define DEST_MAC1 0xee
#define DEST_MAC2 0x7b
#define DEST_MAC3 0x75
#define DEST_MAC4 0x56
#define DEST_MAC5 0x2a
#define ETHER_TYPE 0x1234
#define DEFAULT_IF "eth0"
#define BUF_SIZ 1024
int main(int argc, char *argv[])
{
char sender[INET6_ADDRSTRLEN];
int sockfd, ret, i;
int sockopt;
ssize_t numbytes;
struct ifreq ifopts; /* set promiscuous mode */
struct sockaddr_storage their_addr;
uint8_t buf[BUF_SIZ];
char ifName[IFNAMSIZ];
/* Get interface name *//*eth0*/
if (argc > 1)
strcpy(ifName, argv[1]);
else
strcpy(ifName, DEFAULT_IF);
/* Header structures */
struct ether_header *eh = (struct ether_header *) buf;
/* Open PF_PACKET socket, listening for EtherType ETHER_TYPE *//*0x1234*/
if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) {
perror("listener: socket");
return -1;
}
/* Set interface to promiscuous mode - do we need to do this every time? *//*cpy ifname into ifr_name*/
strncpy(ifopts.ifr_name, ifName, IFNAMSIZ-1);
ioctl(sockfd, SIOCGIFFLAGS, &ifopts); /*set promisc mode*/
ifopts.ifr_flags |= IFF_PROMISC;
ioctl(sockfd, SIOCSIFFLAGS, &ifopts);
/* Allow the socket to be reused - incase connection is closed prematurely */
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
perror("setsockopt");
close(sockfd);
exit(EXIT_FAILURE);
}
/* Bind to device */
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, IFNAMSIZ-1) == -1) {
perror("SO_BINDTODEVICE");
close(sockfd);
exit(EXIT_FAILURE);
}
repeat: printf("listener: Waiting to recvfrom...\n");
numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL);
printf("listener: got packet %lu bytes\n", numbytes);
/* Check the packet is for me */
if (eh->ether_dhost[0] == DEST_MAC0 &&
eh->ether_dhost[1] == DEST_MAC1 &&
eh->ether_dhost[2] == DEST_MAC2 &&
eh->ether_dhost[3] == DEST_MAC3 &&
eh->ether_dhost[4] == DEST_MAC4 &&
eh->ether_dhost[5] == DEST_MAC5) {
printf("Correct destination MAC address\n");
} else {
printf("Wrong destination MAC: %x:%x:%x:%x:%x:%x\n",
eh->ether_dhost[0],
eh->ether_dhost[1],
eh->ether_dhost[2],
eh->ether_dhost[3],
eh->ether_dhost[4],
eh->ether_dhost[5]);
ret = -1;
goto done;
}
/* Print packet */
printf("\tData:");
for (i=0; i<numbytes; i++) printf("%02x:", buf[i]);
printf("\n");
done: goto repeat;
close(sockfd);
return ret;
}
最佳答案
您可以通过接收代码中的以下更改从目标获取所有帧:
请更换线路:if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) {
用这条线:if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {
因为在您的原始代码中您更改了正常的以太网 header 类型,所以操作系统无法检测其进程监听器(您的程序)并将其提供给您,但是当您设置此行时,操作系统可以获得所有结果,因此您可以获得特殊答案。
关于sockets - 无法接收我刚刚发送的原始以太网帧数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23288188/
实现信息技术的自主可控,可以说是金融行业最紧迫、最重要的推进战略了。 人民银行、银保监会等主管部门密集出台文件,指导金融行业核心领域自主可控技术应用。 拿数据库来说,自主可控这事儿业内也
在methods中创建方法showtime,传入要跟当前时间要对比的时间 ?
其实这个没什么技术含量,当然就直接贴代码,不废话了, 但是在其实开发中还是蛮有用的,譬如论坛帖子,围脖等都有相关应用 复制代码代码如下: function tranTim
今天,杭州人的朋友圈都被这场晚会刷屏了 分散在全球的阿里人都回到杭州,为阿里巴巴送上20周岁的生日祝福。 阿里巴巴20周年年会,被称作“有史以来杭州规模最大的年会”,没有
在很多场合为了显示出信息的及时性,一般会将时间显示成“刚刚”,“5分钟前”,“3小时前”等,而不是直接将时间打印出来。比如微博,SNS类应用就最长用到这个功能。而一般存储在数据库中的时间格式为 Un
我是一名优秀的程序员,十分优秀!