[udp] netif_rx成功但是上层收不到数据
用的是linux3.17,我自己写了个网卡驱动,用来在mac层截获上层数据处理并按格式返回相应数据,使用的是udp。
目前host的数据网卡可以收到,处理后交给netif_rx返回值也是成功。并且使用wireshark抓包工具也可以抓到返回给上层的数据包。但是为什么上层收不到这个数据呢?
网卡ip是192.168.1.233, bcst addr是192.168.1.255
使用50000端口发往192.168.1.255的50000端口
返回的数据中
src addr:192.168.16.221(50000)(这个是网卡处理以后重新写的)
dst addr:192.168.1.233(50000)
我查了下有人也出现的这个问题,但是他重新计算udp校验和,ip校验和,以及skb->csum以后udp就通了。这里我将udp、ip已经计算,wireshark抓到的包显示正确。skb->csum是自己计算吗?我查了好像是在协议栈中处理的吧?不知道跟这个有没有关系。因为那个帖子过去久远,也联系不到贴主,各位大神帮忙分析一下。
我附以下udp的代码
目前host的数据网卡可以收到,处理后交给netif_rx返回值也是成功。并且使用wireshark抓包工具也可以抓到返回给上层的数据包。但是为什么上层收不到这个数据呢?
网卡ip是192.168.1.233, bcst addr是192.168.1.255
使用50000端口发往192.168.1.255的50000端口
返回的数据中
src addr:192.168.16.221(50000)(这个是网卡处理以后重新写的)
dst addr:192.168.1.233(50000)
我查了下有人也出现的这个问题,但是他重新计算udp校验和,ip校验和,以及skb->csum以后udp就通了。这里我将udp、ip已经计算,wireshark抓到的包显示正确。skb->csum是自己计算吗?我查了好像是在协议栈中处理的吧?不知道跟这个有没有关系。因为那个帖子过去久远,也联系不到贴主,各位大神帮忙分析一下。
我附以下udp的代码
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define DEST_PORT 50000
#define CLIENT_ADDRESS "192.168.1.233"
#define DSET_IP_ADDRESS "192.168.1.255"
int main()
{
/* socket文件描述符 */
int sock_fd_client;
/* 建立udp socket */
sock_fd_client = socket(AF_INET, SOCK_DGRAM, 0);
if(sock_fd_client < 0)
{
perror("socket");
exit(1);
}
int on = 1;
setsockopt(sock_fd_client, SOL_SOCKET, SO_REUSEADDR|SO_BROADCAST, &on, sizeof(on));
struct sockaddr_in addr_client;
addr_client.sin_family = AF_INET;
addr_client.sin_port = htons(50000);
addr_client.sin_addr.s_addr = inet_addr(CLIENT_ADDRESS);
/* 绑定socket */
if(bind(sock_fd_client, (struct sockaddr *)&addr_client, sizeof(addr_client)) < 0)
{
perror("bind error:");
exit(1);
}
/* 设置address */
struct sockaddr_in addr_serv;
int len;
memset(&addr_serv, 0, sizeof(addr_serv));
addr_serv.sin_family = AF_INET;
addr_serv.sin_port = htons(DEST_PORT);
addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
len = sizeof(addr_serv);
int send_num;
int recv_num;
char send_buf[10] = {0};
char recv_buf[4096] = {0};
printf("send the Query frame for quering wid all\n");
send_buf[0] = 'Q';
send_buf[1] = 0xAA;
send_buf[2] = 0x06;
send_buf[3] = 0x00;
send_buf[4] = 0xFE;
send_buf[5] = 0x7F;
printf("send buff len: %d\n", strlen(send_buf));
send_num = sendto(sock_fd_client, send_buf, 6, 0, (struct sockaddr *)&addr_serv, len);
if(send_num < 0)
{
perror("sendto error:");
exit(1);
}
printf("waiting for server reply...\n");
recv_num = recvfrom(sock_fd_client, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_serv, (socklen_t *)&len);
if(recv_num < 0)
{
perror("recvfrom error:");
exit(1);
}
recv_buf[recv_num] = '\0';
printf("client receive %d\n", recv_num);
int i;
for(i=0; i<recv_num; i++)
{
printf("%x ", *(recv_buf+i));
}
printf("\n");
close(sock_fd_client);
return 0;
}
...全文
相关推荐
linux网络数据包处理流程
接下来,当数据包被存储在内存中后,相应的中断服务例程会被触发,这通常会涉及到一个软中断机制,称为netif_rx()。netif_rx()函数会将接收到的数据包提交给内核的网络子系统进行进一步处理。
LwIP 之九 详解 UDP RAW 编程、示例、API 源码、数据流
在 LwIP 中,UDP RAW 编程被设计为以 struct udp_pcb 为核心的各种 API。我们通过 LWIP_UDP == 1 就可以启用 /src/core/udp.c 中的相关代码实现,对外的各 API 位于 /src/include/lwip/udp.h 中。
linux网络报文接收发送过程分析
操作设备,将设备收到的数据拷贝到这个 skb 结构对应的缓冲区中。3. 设置 skb 的协议类型 skb->protocol,该类型表明了网络协议栈的上层协议。4.
linux 网络数据流程
- tcp_v4_rcv():TCP IPv4数据包的接收函数。- udp_rcv():UDP数据包的接收函数。- netif_rx():网络接口接收到数据包时的软中断函数。
TCP、IP驱动结构介绍
-> ip_recv3. ip_recv -> net_rx_action -> netif_rx -> el3_rx -> el3_interrupt在上面的函数列表中,我们可以看到UDP通信的过程是如何被分解的


