Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
7.4 KiB

  1. #include "allinc.h"
  2. static WORD
  3. Compute16BitXSum(
  4. IN PVOID pvData,
  5. IN DWORD dwNumBytes
  6. )
  7. /*++
  8. Routine Description
  9. Arguments
  10. Return Value
  11. 16 Bit one's complement of the one's complement sum of dwNumBytes starting at pData
  12. --*/
  13. {
  14. REGISTER PWORD pwStart;
  15. REGISTER DWORD dwNumWords,i;
  16. REGISTER DWORD dwSum = 0;
  17. pwStart = (PWORD)pvData;
  18. //
  19. // If there are odd numbered bytes, that has to be handled differently
  20. // However we can never have odd numbered bytes in our case so we optimize.
  21. //
  22. dwNumWords = dwNumBytes/2;
  23. for(i = 0; i < dwNumWords; i++)
  24. {
  25. dwSum += pwStart[i];
  26. if(dwSum & 0x80000000)
  27. {
  28. dwSum = (dwSum & 0x0000FFFF) + (dwSum >> 16);
  29. }
  30. }
  31. return (WORD)~dwSum;
  32. }
  33. int __cdecl
  34. main()
  35. {
  36. SOCKET Socket;
  37. DWORD dwResult,dwNumBytesSent,dwBytesRead,dwAns,dwAddrLen,dwFlags;
  38. LONG i;
  39. DWORD dwSizeOfHeader;
  40. BOOL bOption;
  41. SOCKADDR_IN sinSourceAddr, sinSockAddr;
  42. WSABUF wsaBuf;
  43. DWORD pdwIpAndIcmpBuf[ICMP_RCV_BUFFER_LEN+2];
  44. PIP_HEADER pIpHeader;
  45. PICMP_ROUTER_ADVT_MSG pIcmpAdvt;
  46. ICMP_ROUTER_SOL_MSG icmpSolMsg;
  47. WORD wVersion = MAKEWORD(2,0); //Winsock version 2.0 minimum
  48. WSADATA wsaData;
  49. struct ip_mreq imOption;
  50. icmpSolMsg.byType = 0x0A;
  51. icmpSolMsg.byCode = 0x00;
  52. icmpSolMsg.dwReserved = 0;
  53. icmpSolMsg.wXSum = 0x0000;
  54. icmpSolMsg.wXSum = Compute16BitXSum((PVOID)&icmpSolMsg,
  55. 8);
  56. if(WSAStartup(wVersion,&wsaData) isnot NO_ERROR)
  57. {
  58. printf("WSAStartup failed\n");
  59. exit(1);
  60. }
  61. Socket = WSASocket(AF_INET,
  62. SOCK_RAW,
  63. IPPROTO_ICMP,
  64. NULL,
  65. 0,
  66. RTR_DISC_SOCKET_FLAGS);
  67. if(Socket is INVALID_SOCKET)
  68. {
  69. dwResult = WSAGetLastError();
  70. printf("Couldnt create socket. Error %d\n",
  71. dwResult);
  72. exit(1);
  73. }
  74. //
  75. // Set to SO_REUSEADDR
  76. //
  77. bOption = TRUE;
  78. if(setsockopt(Socket,
  79. SOL_SOCKET,
  80. SO_REUSEADDR,
  81. (const char FAR*)&bOption,
  82. sizeof(BOOL)) is SOCKET_ERROR)
  83. {
  84. printf("Couldnt set linger option. Error %d\n",
  85. WSAGetLastError());
  86. }
  87. //
  88. // Bind to the addresses on the interface
  89. //
  90. sinSourceAddr.sin_family = AF_INET;
  91. sinSourceAddr.sin_addr.s_addr = INADDR_ANY;
  92. sinSourceAddr.sin_port = 0;
  93. if(bind(Socket,
  94. (const struct sockaddr FAR*)&sinSourceAddr,
  95. sizeof(SOCKADDR_IN)) is SOCKET_ERROR)
  96. {
  97. dwResult = WSAGetLastError();
  98. printf("Couldnt bind. Error %d\n",
  99. dwResult);
  100. exit(1);
  101. }
  102. #if 0
  103. //
  104. // Join the multicast session on ALL_SYSTEMS_MULTICAST
  105. //
  106. sinSockAddr.sin_family = AF_INET;
  107. sinSockAddr.sin_addr.s_addr = ALL_SYSTEMS_MULTICAST_GROUP;
  108. sinSockAddr.sin_port = 0;
  109. if(WSAJoinLeaf(Socket,
  110. (const struct sockaddr FAR*)&sinSockAddr,
  111. sizeof(SOCKADDR_IN),
  112. NULL,
  113. NULL,
  114. NULL,
  115. NULL,
  116. JL_BOTH) is INVALID_SOCKET)
  117. {
  118. dwResult = WSAGetLastError();
  119. printf("Error %d joining ALL_SYSTEMS multicast group on socket for %s",
  120. dwResult,
  121. inet_ntoa(*(PIN_ADDR)&(sinSourceAddr.sin_addr)));
  122. closesocket(Socket);
  123. exit(1);
  124. }
  125. #endif
  126. if(setsockopt(Socket,
  127. IPPROTO_IP,
  128. IP_MULTICAST_IF,
  129. (PBYTE)&sinSourceAddr.sin_addr,
  130. sizeof(IN_ADDR)) is SOCKET_ERROR)
  131. {
  132. dwResult = WSAGetLastError();
  133. printf("Couldnt join multicast group on socket for %s",
  134. inet_ntoa(*(PIN_ADDR)&(sinSourceAddr.sin_addr)));
  135. exit(1);
  136. }
  137. imOption.imr_multiaddr.s_addr = ALL_SYSTEMS_MULTICAST_GROUP;
  138. imOption.imr_interface.s_addr = sinSourceAddr.sin_addr.s_addr;
  139. if(setsockopt(Socket,
  140. IPPROTO_IP,
  141. IP_ADD_MEMBERSHIP,
  142. (PBYTE)&imOption,
  143. sizeof(imOption)) is SOCKET_ERROR)
  144. {
  145. dwResult = WSAGetLastError();
  146. printf("Couldnt join multicast group on socket for %s",
  147. inet_ntoa(*(PIN_ADDR)&(sinSourceAddr.sin_addr)));
  148. exit(1);
  149. }
  150. while(TRUE)
  151. {
  152. printf("Send Solicitation? (1 - yes, 0 - no) ");
  153. scanf("%d",&dwAns);
  154. if(!dwAns)
  155. {
  156. break;
  157. }
  158. sinSourceAddr.sin_family = AF_INET;
  159. sinSourceAddr.sin_addr.s_addr = ALL_ROUTERS_MULTICAST_GROUP;
  160. sinSourceAddr.sin_port = 0;
  161. wsaBuf.buf = (PBYTE)&icmpSolMsg;
  162. wsaBuf.len = sizeof(ICMP_ROUTER_SOL_MSG);
  163. if(WSASendTo(Socket,
  164. &wsaBuf,
  165. 1,
  166. &dwNumBytesSent,
  167. MSG_DONTROUTE,
  168. (const struct sockaddr FAR*)&sinSourceAddr,
  169. sizeof(SOCKADDR_IN),
  170. NULL,
  171. NULL
  172. ) is SOCKET_ERROR)
  173. {
  174. dwResult = WSAGetLastError();
  175. printf("WSASendTo failed with %d\n",
  176. dwResult);
  177. break;
  178. }
  179. while(TRUE)
  180. {
  181. dwAddrLen = sizeof(SOCKADDR_IN);
  182. dwFlags = 0;
  183. pIpHeader = (PIP_HEADER)pdwIpAndIcmpBuf;
  184. wsaBuf.buf = (PBYTE)pIpHeader;
  185. wsaBuf.len = (ICMP_RCV_BUFFER_LEN+2) * sizeof(DWORD);
  186. if(WSARecvFrom(Socket,
  187. &wsaBuf,
  188. 1,
  189. &dwBytesRead,
  190. &dwFlags,
  191. (struct sockaddr FAR*)&sinSourceAddr,
  192. &dwAddrLen,
  193. NULL,
  194. NULL) is SOCKET_ERROR)
  195. {
  196. dwResult = WSAGetLastError();
  197. printf("Error %d doing a receive\n",
  198. dwResult);
  199. break;
  200. }
  201. dwSizeOfHeader = ((pIpHeader->byVerLen)&0x0f)<<2;
  202. pIcmpAdvt = (PICMP_ROUTER_ADVT_MSG)(((PBYTE)pIpHeader) + dwSizeOfHeader);
  203. if(pIcmpAdvt->byType is 0x9)
  204. {
  205. for(i = 0; i < MAKELONG(MAKEWORD(pIcmpAdvt->byNumAddrs,0x00),0x0000); i++)
  206. {
  207. printf("Router Address %s \t Preference %d Lifetime %d\n",
  208. inet_ntoa(*(PIN_ADDR)&(pIcmpAdvt->iaAdvt[i].dwRtrIpAddr)),
  209. ntohl(pIcmpAdvt->iaAdvt[i].lPrefLevel),
  210. ntohs(pIcmpAdvt->wLifeTime));
  211. }
  212. break;
  213. }
  214. }
  215. }
  216. return 0;
  217. }