原始套接字不发送
我正在尝试编写一个示例原始套接字程序来澄清我对原始套接字的理解。 我创建一个原始 UDP 套接字,然后调用 sendto。 我的发送成功,但我从未看到对方收到的数据包。 我没有运行任何接收端,因此我依赖在发送方和接收方上运行的 Wireshark。 我将代码片段粘贴在这里。 有错误之处请指出。
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<string.h>
#include "protHeaders.x"
#include "gen.h"
U16 csum(U16* buf, S32 nwords)
{
U32 sum;
for (sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}/*csum*/
int main(int argc,char** argv)
{
U8 datagram[MAX_IPPACKET];
U8 udpPayLoad[MAX_UDPPAYLOAD];
CustIpHeader* ipH;
CustUdpHeader* udpH;
struct sockaddr_in sin;
S32 sockFd;
S32 one = 1;
const S32* val = &one;
ipH = (CustIpHeader *)datagram;
udpH = (CustUdpHeader *)(datagram + sizeof(CustIpHeader));
memset(datagram,0,sizeof(datagram));
memset(udpPayLoad,0,sizeof(udpPayLoad));
memset(&sin,0,sizeof(struct sockaddr_in));
strcpy(udpPayLoad,"<<<<Aditya>>>>");
sin.sin_family = AF_INET;
sin.sin_port = htons(atoi(argv[4]));
/* fill the Ip header */
ipH->ip_hl = 5;
ipH->ip_v = 4;
ipH->ip_tos = 0;
ipH->ip_len = sizeof(CustIpHeader) + sizeof(CustUdpHeader) + strlen(udpPayLoad);
ipH->ip_id = htonl(54321);
ipH->ip_off = 0;
ipH->ip_p = 17;
ipH->ip_ttl = 65;
ipH->ip_sum = 0;
ipH->ip_src.s_addr = inet_addr(argv[1]);
ipH->ip_dst.s_addr = inet_addr(argv[3]);
/* fill the Udp header */
udpH->uh_sport = htons(atoi(argv[2]));
udpH->uh_dport = htons(atoi(argv[4]));
udpH->uh_len = sizeof(CustUdpHeader) + strlen(udpPayLoad);
udpH->uh_check = 0;
printf("Checksum = %u\n",udpH->uh_check);
/* copy udpPayLoad */
strcpy(datagram+sizeof(CustIpHeader)+sizeof(CustUdpHeader),udpPayLoad);
#if 1
printf("Datagram %p,UdpPayload %p\n",(void *)datagram,(void *)datagram+sizeof(CustIpHeader)+sizeof(CustUdpHeader));
printf("IpHeader %p, UdpHeader %p\n",(void *)ipH,udpH);
#endif
/* fill in the checksum */
ipH->ip_sum = csum((U16 *)datagram,ipH->ip_len >> 1);
printf("Checksum = %u\n",ipH->ip_sum);
if ((sockFd = socket(PF_INET,SOCK_RAW,IPPROTO_UDP)) < 0)
{
perror("socket:create");
RETURN(RFAILED);
}
/* doing the IP_HDRINCL call */
if (setsockopt(sockFd,IPPROTO_IP,IP_HDRINCL,val,sizeof(one)) < 0)
{
perror("Client:setsockopt");
}
while(1)
{
if ( sendto(sockFd,
datagram,
ipH->ip_len,
0,
(struct sockaddr *)&sin,
sizeof (sin)) < 0)
{ perror("Client:sendto"); }
else
printf(".");
}
RETURN(ROK);
}
IP 和 UDP 标头是:
typedef struct _ipheader
{
U8 ip_hl:4,ip_v:4; /* ip_hl: the ip header length in 32bit octets.
* ip_v : ip version (always 4 for our case).
*/
U8 ip_tos; /* reliability of the service. 0x00 is Normal */
U16 ip_len; /* totoal length including ip header,icmp/tcp/udp header
* and payload size in bytes
*/
U16 ip_id; /* sequence no. used for reassembly of fragmented IP packets */
U16 ip_off; /* the fragment offset used for reassembly of fragmented packets */
U16 ip_p; /* the transport layer protocol. can be tcp (6), udp(17) */
U8 ip_ttl; /* time to live */
U16 ip_sum; /* the datagram checksum for the whole IP packet */
struct in_addr ip_src; /* the source IP address, converted to a long format */
struct in_addr ip_dst; /* the desitnation IP address, converted to a long format */
}CustIpHeader; /* total ip header length: 20 bytes */
typedef struct _udpheader
{
U16 uh_sport; /* The source port that a client bind()s to */
U16 uh_dport; /* The desination port that a server bind()s to*/
U16 uh_len; /* The length of udp header and payload data in bytes */
U16 uh_check; /* The checksum of header and data */
}CustUdpHeader; /* total udp header length: 8 bytes (=64 bits) */
我以 root 用户身份运行,因此权限不是问题。
语言:C
操作系统:Linux
I am trying to write a sample Raw socket program to clear my understanding of raw sockets. I create a Raw UDP socket and then call sendto. My sendto succeeds but I never see the packet received by the other side. I don't have any receive side running so I am relying on Wireshark running on both the sender and receiver.
I am pasting the code snippet here. Please point out any errors.
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<string.h>
#include "protHeaders.x"
#include "gen.h"
U16 csum(U16* buf, S32 nwords)
{
U32 sum;
for (sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}/*csum*/
int main(int argc,char** argv)
{
U8 datagram[MAX_IPPACKET];
U8 udpPayLoad[MAX_UDPPAYLOAD];
CustIpHeader* ipH;
CustUdpHeader* udpH;
struct sockaddr_in sin;
S32 sockFd;
S32 one = 1;
const S32* val = &one;
ipH = (CustIpHeader *)datagram;
udpH = (CustUdpHeader *)(datagram + sizeof(CustIpHeader));
memset(datagram,0,sizeof(datagram));
memset(udpPayLoad,0,sizeof(udpPayLoad));
memset(&sin,0,sizeof(struct sockaddr_in));
strcpy(udpPayLoad,"<<<<Aditya>>>>");
sin.sin_family = AF_INET;
sin.sin_port = htons(atoi(argv[4]));
/* fill the Ip header */
ipH->ip_hl = 5;
ipH->ip_v = 4;
ipH->ip_tos = 0;
ipH->ip_len = sizeof(CustIpHeader) + sizeof(CustUdpHeader) + strlen(udpPayLoad);
ipH->ip_id = htonl(54321);
ipH->ip_off = 0;
ipH->ip_p = 17;
ipH->ip_ttl = 65;
ipH->ip_sum = 0;
ipH->ip_src.s_addr = inet_addr(argv[1]);
ipH->ip_dst.s_addr = inet_addr(argv[3]);
/* fill the Udp header */
udpH->uh_sport = htons(atoi(argv[2]));
udpH->uh_dport = htons(atoi(argv[4]));
udpH->uh_len = sizeof(CustUdpHeader) + strlen(udpPayLoad);
udpH->uh_check = 0;
printf("Checksum = %u\n",udpH->uh_check);
/* copy udpPayLoad */
strcpy(datagram+sizeof(CustIpHeader)+sizeof(CustUdpHeader),udpPayLoad);
#if 1
printf("Datagram %p,UdpPayload %p\n",(void *)datagram,(void *)datagram+sizeof(CustIpHeader)+sizeof(CustUdpHeader));
printf("IpHeader %p, UdpHeader %p\n",(void *)ipH,udpH);
#endif
/* fill in the checksum */
ipH->ip_sum = csum((U16 *)datagram,ipH->ip_len >> 1);
printf("Checksum = %u\n",ipH->ip_sum);
if ((sockFd = socket(PF_INET,SOCK_RAW,IPPROTO_UDP)) < 0)
{
perror("socket:create");
RETURN(RFAILED);
}
/* doing the IP_HDRINCL call */
if (setsockopt(sockFd,IPPROTO_IP,IP_HDRINCL,val,sizeof(one)) < 0)
{
perror("Client:setsockopt");
}
while(1)
{
if ( sendto(sockFd,
datagram,
ipH->ip_len,
0,
(struct sockaddr *)&sin,
sizeof (sin)) < 0)
{ perror("Client:sendto"); }
else
printf(".");
}
RETURN(ROK);
}
The IP and UDP headers are:
typedef struct _ipheader
{
U8 ip_hl:4,ip_v:4; /* ip_hl: the ip header length in 32bit octets.
* ip_v : ip version (always 4 for our case).
*/
U8 ip_tos; /* reliability of the service. 0x00 is Normal */
U16 ip_len; /* totoal length including ip header,icmp/tcp/udp header
* and payload size in bytes
*/
U16 ip_id; /* sequence no. used for reassembly of fragmented IP packets */
U16 ip_off; /* the fragment offset used for reassembly of fragmented packets */
U16 ip_p; /* the transport layer protocol. can be tcp (6), udp(17) */
U8 ip_ttl; /* time to live */
U16 ip_sum; /* the datagram checksum for the whole IP packet */
struct in_addr ip_src; /* the source IP address, converted to a long format */
struct in_addr ip_dst; /* the desitnation IP address, converted to a long format */
}CustIpHeader; /* total ip header length: 20 bytes */
typedef struct _udpheader
{
U16 uh_sport; /* The source port that a client bind()s to */
U16 uh_dport; /* The desination port that a server bind()s to*/
U16 uh_len; /* The length of udp header and payload data in bytes */
U16 uh_check; /* The checksum of header and data */
}CustUdpHeader; /* total udp header length: 8 bytes (=64 bits) */
I am running as root user, so privileges is not a problem.
Language: C
Os: Linux
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我让wireshark在一个缓慢的系统上运行。 数据包确实正在发送,但 Wireshark 只能在 6 分钟左右的间隙后显示它们。 迁移到更快的系统很有帮助。 因此,我自己关闭这个。
I had the wireshark running on a slow system. The packets were indeed being send but the Wireshark could only show them after a gap of 6 minutes or so. Moving to a faster system helped. I am therefore closing this myself.
这可能会帮助您开始 http://www.securitytube.net /Raw-Sockets-Basics-Presentation-video.aspx。
如果您使用 libcap/wincap 我会提供帮助。 但上面的视频可以帮助您入门。
This may help you to get started http://www.securitytube.net/Raw-Sockets-Basics-Presentation-video.aspx.
if you are using libcap/wincap i would have helped. but above video help you get started.