(转)Ws2tcpip.h

设置或获取套接字选项在 C/C++ Winsock 应用程序针对 Windows NT、 Windows 2000、 Windows 95 或 Windows 98 中 IPPROTO_IP 级别时, 程序项目中包括正确的标头和库文件至关重要。 如果标头和库文件不正确地匹配,setsockopt 或 getsockopt 可能会因运行时错误 10042 (WSAENOPROTOOPT)。 in certain cases,even if API returns successfully,that set or get option value may not be what would have expected。

若要避免此问题,遵守以下准则:
?与 Wsock32.lib 应该只链接,其中包括 Winsock.h 程序。
?其中包括 Ws2tcpip.h 程序可能会链接与 Ws2_32.lib 或 Wsock32.lib。 请注意 Ws2tcpip.h 必须是显式包含 Winsock 2 h 后才能在此级别使用套接字选项。

  Ws2tcpip.h - noCom - 放弃了多余回到顶端

更多信息

IPPROTO_IP 级别的套接字选项是在比 Winsock.h 的 Ws2tcpip.h 中以不同的方式定义的。 在 Winsock.h,定义是:
/* * Options for use with [gs]etsockopt at the IP level. */ #define IP_OPTIONS          1           /* set/get IP per-packet options    */ #define IP_MULTICAST_IF     2           /* set/get IP multicast interface   */ #define IP_MULTICAST_TTL    3           /* set/get IP multicast timetolive  */ #define IP_MULTICAST_LOOP   4           /* set/get IP multicast loopback    */ #define IP_ADD_MEMBERSHIP   5           /* add  an IP group membership      */ #define IP_DROP_MEMBERSHIP  6           /* drop an IP group membership      */ #define IP_TTL              7           /* set/get IP Time To Live          */ #define IP_TOS              8           /* set/get IP Type Of Service       */ #define IP_DONTFRAGMENT     9           /* set/get IP Don't Fragment flag   */ #define IP_DEFAULT_MULTICAST_TTL   1    /* normally limit m'casts to 1 hop  */ #define IP_DEFAULT_MULTICAST_LOOP  1    /* normally hear sends if a member  */ #define IP_MAX_MEMBERSHIPS         20   /* per socket; must fit in one mbuf */     

相比之下,作为 Ws2tcpip.h 中定义此级别的选项:
/* Option to use with [gs]etsockopt at the IPPROTO_IP level */ #define IP_OPTIONS  1 /* set/get IP options */ #define IP_HDRINCL  2 /* header is included with data */ #define IP_TOS   3 /* IP type of service and preced*/ #define IP_TTL   4 /* IP time to live */ #define IP_MULTICAST_IF  9 /* set/get IP multicast i/f  */ #define IP_MULTICAST_TTL       10 /* set/get IP multicast ttl */ #define IP_MULTICAST_LOOP      11 /*set/get IP multicast loopback */ #define IP_ADD_MEMBERSHIP      12 /* add an IP group membership */ #define IP_DROP_MEMBERSHIP     13/* drop an IP group membership */ #define IP_DONTFRAGMENT     14 /* don't fragment IP datagrams */     

如果您不能正确匹配头和库文件,setsockopt 或 getsockopt 可能会因运行时错误 10042 (WSAENOPROTOOPT) 或者您设置或获取选项值不是您将有预期。
case 1。 Runtime error 10042 (WSAENOPROTOOPT)
属于此类别的选项包括:
IP_ADD_MEMBERSHIPIP_DROP_MEMBERSHIPIP_TTLIP_TOS

假定您想加入多路广播的组通过运行代码与以下内容类似:
#include <stdio.h>#include <stdlib.h>#include <winsock.h>int main(int argc, char* argv[]){   ...   ...   ...   if (setsockopt(sock,                   IPPROTO_IP,                   IP_ADD_MEMBERSHIP,                   (char FAR *)&mreq,                   sizeof (mreq)) == SOCKET_ERROR)   {      printf ("setsockopt failed: %d"), WSAGetLastError());      closesocket (sock);      return FALSE;   }   ...   ...   ...}    

请注意这包括 Winsock.h。 如果该项目已链接与 Ws2_32.lib,setsockopt 将失败,并运行时错误 10042 (WSAENOPROTOOPT)。 这是因为在 Winsock.h,IP_ADD_MEMBERSHIP 被定义为"5"。 相应的 Winsock 运行库不可以解决选项在 IPPROTO_IP 级别,5 以便,错误代码 10042 出现故障。
case 2。 options set or get appear do not take effect

属于此类别的选项包括: IP_MULTICAST_TTL 作为示例。 在 Winsock.h,IP_MULTICAST_TTL 被定义为"3"。 在 ws2tcpip.h,该常量被定义为"10"并且 IP_TOS 被定义为"3"。 尝试更改默认的 TTL 值:

#include <stdio.h>#include <stdlib.h>#include <winsock.h>int main(int argc, char* argv[]){   int ttl = 7 ; // Arbitrary TTL value.   ...   ...   ...   source_sin.sin_family = AF_INET;   source_sin.sin_port = htons(0);       source_sin.sin_addr.s_addr = htonl (INADDR_ANY);   if (bind(sock,             (struct sockaddr FAR *)&source_sin,             sizeof(source_sin)) == SOCKET_ERROR)    {      printf ("bind() failed: %d"), WSAGetLastError());      closesocket (sock);      return FALSE;   }   if (setsockopt(sock,                  IPPROTO_IP,                  IP_MULTICAST_TTL,                  (char *)&ttl,                  sizeof(ttl))) == SOCKET_ERROR)   {      printf ("setsockopt failed: %d"), WSAGetLastError());      closesocket (sock);      return FALSE;   }   ...   ...   ...}    
如果您链接与 Ws2_32.lib 该项目并运行该应用程序,使用 IP_MULTICAST_TTL setsockopt 将成功。 但是,多播的 TTL 设置不会生效。 如果您检查网络跟踪,您将看到 TTL 值仍保持为"1"(默认值)。

转自:http://hi.baidu.com/yiouzhou/blog/item/38421358134b4dd89c820432.html

IP_MULTICAST_IFIP_MULTICAST_TTLIP_MULTICAST_LOOPIP_DONTFRAGMENT
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
关于嗅探器的源代码#include <winsock2.h> #include <windows.h> #include <ws2tcpip.h> #include <stdio.h> #include <stdlib.h> #pragma comment(lib,"ws2_32.lib") #define MAX_HOSTNAME_LAN 255 #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) #define MAX_ADDR_LEN 16 struct ipheader { unsigned char ip_hl:4; unsigned char ip_v:4; unsigned char ip_tos; unsigned short int ip_len; unsigned short int ip_id; unsigned short int ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short int ip_sum; unsigned int ip_src; unsigned int ip_dst; }; typedef struct tcpheader { unsigned short int sport; unsigned short int dport; unsigned int th_seq; unsigned int th_ack; unsigned char th_x:4; unsigned char th_off:4; unsigned char Flags; unsigned short int th_win; unsigned short int th_sum; unsigned short int th_urp; }TCP_HDR; typedef struct udphdr { unsigned short sport; unsigned short dport; unsigned short len; unsigned short cksum; }UDP_HDR; void main(){ SOCKET sock; WSADATA wsd; DWORD dwBytesRet; unsigned int optval = 1; unsigned char *dataudp,*datatcp; int i,pCount=0,lentcp, lenudp; SOCKADDR_IN sa,saSource, saDest; struct hostent FAR * pHostent; char FAR name[MAX_HOSTNAME_LAN]; char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN],RecvBuf[65535] = {0}; struct udphdr *pUdpheader; struct ipheader *pIpheader; struct tcpheader *pTcpheader; WSAStartup(MAKEWORD(2,1),&wsd); if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP))==SOCKET_ERROR) exit(1); gethostname(name, MAX_HOSTNAME_LAN); pHostent = gethostbyname(name); sa.sin_family = AF_INET; sa.sin_port = htons(6000); memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length); bind(sock, (SOCKADDR *)&sa, sizeof(sa)); if ((WSAGetLastError())==10013) exit(1); WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL); pIpheader = (struct ipheader *)RecvBuf; pTcpheader = (struct tcpheader *)(RecvBuf+ sizeof(struct ipheader )); pUdpheader = (struct udphdr *) (RecvBuf+ sizeof(struct ipheader )); while (1){ memset(RecvBuf, 0, sizeof(RecvBuf)); recv(sock, RecvBuf, sizeof(RecvBuf), 0); saSource.sin_addr.s_addr = pIpheader->ip_src; strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN); saDest.sin_addr.s_addr = pIpheader->ip_dst; strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN); lentcp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct tcpheader))); lenudp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct udphdr))); if((pIpheader->ip_p)==IPPROTO_TCP&&lentcp!=0){ printf("*******************************************\n"); pCount++; datatcp=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct tcpheader); printf("-TCP-\n"); printf("\n%s\n",szDestIP); printf("\n%i\n",ntohs(pTcpheader->dport)); printf("datatcp address->%x\n",datatcp); printf("size of ipheader->%i\n",sizeof(struct ipheader)); printf("size of tcpheader->%i\n",sizeof(struct tcpheader)); printf("size of the hole packet->%i\n",ntohs(pIpheader->ip_len)); printf("\nchar Packet%i [%i]=\"",pCount,lentcp-1); for (i=0;i<lentcp;i++){ printf("\\x%.2x",*(datatcp+i)); if (i==0) printf("\"\n\""); } printf("\";\n\n\n"); for (i=0;i<lentcp;i++){ if( *(datatcp+i)<=127&&*(datatcp+i)>=20) printf("%c",*(datatcp+i)); else printf("."); } printf("\n\n*******************************************\n"); } if((pIpheader->ip_p)==IPPROTO_UDP&&lentcp!=0){ pCount++; dataudp=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct udphdr); printf("-UDP-\n"); printf("\n%s\n",szDestIP); printf("\n%d\n",ntohs(pTcpheader->dport)); printf("UDP%x\n",dataudp); printf("IP%i\n",sizeof(struct ipheader)); printf("UDP%i\n",sizeof(struct udphdr)); printf("%i\n",ntohs(pIpheader->ip_len)); printf("\nchar Packet%i [%i]=\"",pCount,lenudp-1); for (i=0;i<lenudp;i++){ printf("\\x%.2x",*(dataudp+i)); if (i==0) printf("\"\n\""); } printf("\";\n\n\n"); for (i=0;i<lenudp;i++){ if( *(dataudp+i)<=127&&*(dataudp+i)>=20) printf("%c",*(dataudp+i)); else printf("."); } printf("\n\n*******************************************\n"); } } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值