Linux:可以使用Recvmsg接收每个传入数据包的IP_TOS
发布时间:2020-12-14 02:18:50 所属栏目:Linux 来源:网络整理
导读:可以使用recvmsg()来获取每个传入数据包的IP_TOS字段,或者只显示为特定套接字设置的IP_TOS值.如果没有,是否有人知道获得每个传入数据包的IP_TOS值的解决方案.我正在使用UDP应用程序,因此无法像TCP一样在应用程序层查看IP_TOS字段.谢谢. 添加我到目前为止编写
可以使用recvmsg()来获取每个传入数据包的IP_TOS字段,或者只显示为特定套接字设置的IP_TOS值.如果没有,是否有人知道获得每个传入数据包的IP_TOS值的解决方案.我正在使用UDP应用程序,因此无法像TCP一样在应用程序层查看IP_TOS字段.谢谢.
添加我到目前为止编写的代码,这有助于: struct msghdr msg; struct iovec iov[1]; memset(&msg,' ',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 recvttln"); } else { printf("socket set to recvttln"); } 并按以下方式从每个数据包中检索IP_TTL值(以下程序可以通过iov [0]检索数据消息,下面给出了代码片段): struct msghdr msg; struct iovec iov[1]; memset(&msg,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,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,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,0); 接收方(假设DATA_To_SEND有一个名为“seq”的参数): struct DATA_to_SEND pkt; seqNum = ((struct DATA_to_SEND *) iov[0].iov_base)->seq; 以下是IP_TOS. unsigned char set = 0x03; if(setsockopt(udpSocket,IP_RECVTOS,&set,sizeof(set))<0) { printf("cannot set recvtosn"); } else { printf("socket set to recvtosn"); 并通过以下方式从每个数据包标头中检索IP_TOS值: struct PC_Pkt pkt; int *ecnptr; unsigned char received_ecn; struct msghdr msg; struct iovec iov[1]; memset(&msg,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,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; } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |