gpt4 book ai didi

c - Linux : Can Recvmsg be used to receive the IP_TOS of every incoming packet

转载 作者:太空狗 更新时间:2023-10-29 17:01:56 25 4
gpt4 key购买 nike

可以使用 recvmsg() 获取每个传入数据包的 IP_TOS 字段,还是只显示为特定套接字设置的 IP_TOS 值。如果没有,是否有人知道获取每个传入数据包的 IP_TOS 值的解决方案。我正在使用 UDP 应用程序,因此无法像 TCP 那样在应用程序层查看 IP_TOS 字段。谢谢。

添加我目前编写的代码,以防有帮助:

struct msghdr msg; 
struct iovec iov[1];
memset(&msg, '\0', sizeof(msg));
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = (char *) &pkt;
iov[0].iov_len = sizeof(pkt);

struct cmsghdr cmsgcmsg[1];
msg.msg_control = cmsgcmsg;
msg.msg_controllen = sizeof(struct cmsghdr);


nRet = recvmsg(udpSocket, &msg, 0);

if (nRet > 0) {
struct cmsghdr *cmsg;
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg,cmsg)) {

if ((cmsg->cmsg_level == IPPROTO_IP) && (cmsg->cmsg_type == IP_TOS) &&
(cmsg->cmsg_len) ){
int tos = *(uint8_t *)CMSG_DATA(cmsg);
int isecn = ((tos & INET_ECN_MASK) == INET_ECN_CE);
printf("the tos = %i , is ecn = %d \n", tos, isecn);

}
}

最佳答案

我终于设法解决了这个问题,并在此处添加代码以供其他人使用。我希望这对其他人有帮助。这是用于 IP_TTL 的:

设置 UDPSocket 接收 IP_TTL 值:

int ttl = 60;
if(setsockopt(udpSocket, IPPROTO_IP, IP_RECVTTL, &ttl,sizeof(ttl))<0)
{
printf("cannot set recvttl\n");
}
else
{
printf("socket set to recvttl\n");
}

并通过以下方式从每个数据包中检索 IP_TTL 值(以下程序可以通过 iov[0] 检索数据消息,下面给出代码片段):

struct msghdr msg; 
struct iovec iov[1];
memset(&msg, '\0', sizeof(msg));
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = (char *) &pkt;
iov[0].iov_len = sizeof(pkt);

int *ttlptr=NULL;
int received_ttl = 0;

int cmsg_size = sizeof(struct cmsghdr)+sizeof(received_ttl); // NOTE: Size of header + size of data
char buf[CMSG_SPACE(sizeof(received_ttl))];
msg.msg_control = buf; // Assign buffer space for control header + header data/value
msg.msg_controllen = sizeof(buf); //just initializing it

nRet = recvmsg(udpSocket, &msg, 0);



if (nRet > 0) {
struct cmsghdr *cmsg;
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg,cmsg)) {

if ((cmsg->cmsg_level == IPPROTO_IP) && (cmsg->cmsg_type == IP_TTL) &&
(cmsg->cmsg_len) ){
ttlptr = (int *) CMSG_DATA(cmsg);
received_ttl = *ttlptr;
printf("received_ttl = %i and %d \n", ttlptr, received_ttl);
break;
}
}
}

可以通过以下方式发送和获取数据消息:

发送方:

struct DATA_to_SEND pkt;
struct msghdr msg;
struct iovec iov[1];
memset(&msg, '\0', sizeof(msg));
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = (char *) &pkt;
iov[0].iov_len = sizeof(pkt);
nRet = sendmsg(udpSocket, &msg,0);

接收方(假设 DATA_To_SEND 有一个名为“seq”的参数):

struct DATA_to_SEND pkt;
seqNum = ((struct DATA_to_SEND *) iov[0].iov_base)->seq;

以下是IP_TOS。设置套接字接收IP_TOS:

unsigned char set = 0x03;
if(setsockopt(udpSocket, IPPROTO_IP, IP_RECVTOS, &set,sizeof(set))<0)
{
printf("cannot set recvtos\n");
}
else
{
printf("socket set to recvtos\n");

并通过以下方式从每个数据包 header 中检索 IP_TOS 值:

 struct PC_Pkt pkt;
int *ecnptr;
unsigned char received_ecn;

struct msghdr msg;
struct iovec iov[1];
memset(&msg, '\0', sizeof(msg));
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = (char *) &pkt;
iov[0].iov_len = sizeof(pkt);

int cmsg_size = sizeof(struct cmsghdr)+sizeof(received_ecn);
char buf[CMSG_SPACE(sizeof(received_ecn))];
msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);

nRet = recvmsg(udpSocket, &msg, 0);

if (nRet > 0) {
struct cmsghdr *cmsg;
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
cmsg = CMSG_NXTHDR(&msg,cmsg)) {
if ((cmsg->cmsg_level == IPPROTO_IP) &&
(cmsg->cmsg_type == IP_TOS) && (cmsg->cmsg_len) ){
ecnptr = (int *) CMSG_DATA(cmsg);
received_ecn = *ecnptr;
int isecn = ((received_ecn & INET_ECN_MASK) == INET_ECN_CE);

printf("received_ecn = %i and %d, is ECN CE marked = %d \n", ecnptr, received_ecn, isecn);

break;
}
}
}

关于c - Linux : Can Recvmsg be used to receive the IP_TOS of every incoming packet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2881200/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com