什么是BSD(或便携式)方式来获取ToS字节(如linux中的IP_RECVTOS)?
获取接收到的数据包的ToS字节的正确(便携、稳定)方法是什么?我正在使用recvmsg()进行UDP,在linux上,如果我设置了sockopt()IP_RECVTOS/IPV6_RECVTOS类,我就可以获得ToS,但我的BSD系统上似乎没有IP_RECVTOS。正确的方法是什么 我主要希望它能在BSD和Solaris上工作 编辑: 澄清: 我目前使用recvmsg(),在Linux上的msg_控制字段中获取TTL和TOS,但为了获取TTL和TOS,我需要设置sockopt()-启用IP_RECVTTL和IP_RECVTOS。而且,由于Solaris和BSD(目前正在使用FreeBSD)没有IP_RECVTOS,从我所看到的情况来看,在循环CMSG数据时,我没有得到TOS 我尝试启用IP_RECVOPTS和IP_recvretops,但仍然没有任何IP_TOS类型的CMSG 编辑2: 我希望ToS能够验证(尽可能多地)它在传输过程中没有被覆盖。例如,如果一个VoIP应用程序突然发现它没有得到EF标记的数据包,那么一定是出了问题,应该会出现警报。(不,我不希望EF在公共互联网上受到尊重或保留)什么是BSD(或便携式)方式来获取ToS字节(如linux中的IP_RECVTOS)?,c,unix,sockets,network-programming,C,Unix,Sockets,Network Programming,获取接收到的数据包的ToS字节的正确(便携、稳定)方法是什么?我正在使用recvmsg()进行UDP,在linux上,如果我设置了sockopt()IP_RECVTOS/IPV6_RECVTOS类,我就可以获得ToS,但我的BSD系统上似乎没有IP_RECVTOS。正确的方法是什么 我主要希望它能在BSD和Solaris上工作 编辑: 澄清: 我目前使用recvmsg(),在Linux上的msg_控制字段中获取TTL和TOS,但为了获取TTL和TOS,我需要设置sockopt()-启用IP_RE
我想要TTL基本上就是因为我能。假设这可以用来触发“我和对方之间的网络发生了变化”警报,这有助于了解某些东西是否同时停止工作。不幸的是,这类事情通常在不同的*IX之间有所不同。在Solaris上,您希望将
getsockopt
与IP_-TOS
一起使用;我不知道BSD
有关详细信息,请参阅。正确的标准解决方案可能是使用cmsg(3)
。您将在“Unix网络编程”一书中找到完整的描述,这是一本必读的书
谷歌代码搜索找到了这个。我在想是否可以创建两个套接字
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<arpa/inet.h>
#include<string.h>
#include "protHeaders.x"
#include "gen.h"
int main(void)
{
S32 rawSockFd;
S32 udpSockFd;
struct sockaddr_in rsin;
struct sockaddr_in usin;
S32 one = 1;
const S32* val = &one;
struct timeval tv;
fd_set rfds;
S32 maxFd;
S16 ret;
S8 rawBuffer[2048];
S8 udpBuffer[2048];
struct sockaddr udpFrom,rawFrom;
socklen_t rLen,uLen;
memset(rawBuffer,0,sizeof(rawBuffer));
memset(udpBuffer,0,sizeof(udpBuffer));
memset(udpFrom,0,sizeof(udpFrom));
memset(rawFrom,0,sizeof(rawFrom));
if ((rawSockFd = socket(PF_INET,SOCK_RAW,IPPROTO_UDP)) < 0)
{
perror("socket:create");
RETVALUE(RFAILED);
}
/* doing the IP_HDRINCL call */
if (setsockopt(rawSockFd,IPPROTO_IP,IP_HDRINCL,val,sizeof(one)) < 0)
{
perror("Server:setsockopt");
RETVALUE(RFAILED);
}
rsin.sin_family = AF_INET;
rsin.sin_addr.s_addr = htonl(INADDR_ANY);
rsin.sin_port = htons(0);
usin.sin_family = AF_INET;
usin.sin_addr.s_addr = htons(INADDR_ANY);
usin.sin_port = htons(2905);
if(bind(rawSockFd,(struct sockaddr *)&rsin, sizeof(rsin)) < 0 )
{
perror("Server: bind failed");
RETVALUE(RFAILED);
}
if ((udpSockFd = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0)
{
perror("socket:create");
RETVALUE(RFAILED);
}
if(bind(udpSockFd,(struct sockaddr *)&usin, sizeof(usin)) < 0 )
{
perror("Server: bind failed on udpsocket");
RETVALUE(RFAILED);
}
/*set upd socket receive buffer to 0 */
one = 0;
if (setsockopt(udpSockFd,SOL_SOCKET,SO_RCVBUF,(char *)&one,sizeof(one)) < 0)
{
perror("Server:setsockopt on udpsocket failed");
RETVALUE(RFAILED);
}
tv.tv_sec = 0;
tv.tv_usec = 0;
maxFd = (rawSockFd > udpSockFd)? rawSockFd:udpSockFd;
while(1)
{
FD_ZERO(&rfds);
FD_SET(rawSockFd,&rfds);
FD_SET(udpSockFd,&rfds);
ret = select(maxFd+1,&rfds,0,0,&tv);
if ( ret == -1)
{
perror("Select Failed");
RETVALUE(RFAILED);
}
if(FD_ISSET(rawSockFd,&rfds))
{
printf("Raw Socked Received Message\n");
if(recvfrom(rawSockFd,rawBuffer,sizeof(rawBuffer),0,&rawFrom,&rLen) == -1)
{
perror("Raw socket recvfrom failed");
RETVALUE(RFAILED);
}
/*print the tos */
printf("TOS:%x\n",*(rawBuffer+1));
printf("TTL:%x\n",*(rawBuffer+8));
}
if(FD_ISSET(udpSockFd,&rfds))
{
printf("UDP Socked Received Message\n");
if(recvfrom(udpSockFd,udpBuffer,sizeof(udpBuffer),0,&udpFrom,&uLen) == -1)
{
perror("Udp socket recvfrom failed");
RETVALUE(RFAILED);
}
printf("%s\n",udpBuffer);
}
}
RETVALUE(ROK);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“protHeaders.x”
#包括“gen.h”
内部主(空)
{
S32-rawSockFd;
S32-udpSockFd;
rsin中的结构sockaddr_;
usin中的结构sockaddr_;
S32一=1;
常量S32*val=&one;
结构时间值电视;
fd_集rfds;
S32-maxFd;
S16-ret;
S8 rawBuffer[2048];
S8 udpBuffer[2048];
结构sockaddr udpFrom,rawFrom;
索克伦·特伦,乌伦;
memset(rawBuffer,0,sizeof(rawBuffer));
memset(udpBuffer,0,sizeof(udpBuffer));
memset(udpFrom,0,sizeof(udpFrom));
memset(rawFrom,0,sizeof(rawFrom));
if((rawSockFd=socket(PF_INET,SOCK_RAW,IPPROTO_UDP))<0)
{
perror(“套接字:创建”);
返回值(RFAILED);
}
/*执行IP_HDRINCL呼叫*/
如果(设置锁定选项(rawSockFd、IPPROTO_IP、IP_HDRINCL、val、大小(一个))<0)
{
perror(“服务器:setsockopt”);
返回值(RFAILED);
}
rsin.sin_family=AF_INET;
rsin.sin_addr.s_addr=htonl(在任何情况下);
rsin.sin_port=htons(0);
usin.sin_family=AF_INET;
usin.sin_addr.s_addr=htons(INADDR_ANY);
usin.sinu port=htons(2905);
if(bind(rawSockFd,(struct sockaddr*)&rsin,sizeof(rsin))<0)
{
perror(“服务器:绑定失败”);
返回值(RFAILED);
}
如果((udpSockFd=套接字(PF_INET、SOCK_DGRAM、IPPROTO_UDP))<0)
{
perror(“套接字:创建”);
返回值(RFAILED);
}
if(bind(udpSockFd,(struct sockaddr*)&usin,sizeof(usin))<0
{
perror(“服务器:在udpsocket上绑定失败”);
返回值(RFAILED);
}
/*将upd套接字接收缓冲区设置为0*/
1=0;
if(setsockopt(udpSockFd,SOL_SOCKET,SO_RCVBUF,(char*)&one,sizeof(one))<0)
{
perror(“服务器:udpsocket上的setsockopt失败”);
返回值(RFAILED);
}
tv.tv_sec=0;
tv.tv_usec=0;
maxFd=(rawSockFd>udpSockFd)?rawSockFd:udpSockFd;
而(1)
{
FD_ZERO(和RFD);
FD_集(rawSockFd和RFD);
FD_集(udpSockFd和rfds);
ret=选择(最大FD+1,&rfds,0,0,&tv);
如果(ret==-1)
{
perror(“选择失败”);
返回值(RFAILED);
}
if(FD_ISSET(rawSockFd和RFD))
{
printf(“原始套接字接收消息\n”);
如果