Leaked source code of windows server 2003
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.

471 lines
13 KiB

  1. /*++
  2. Copyright (C) 1999 Microsoft Corporation
  3. Implements raw sockets stuff..
  4. --*/
  5. #include "precomp.h"
  6. int show_all = 0;
  7. int show_headers = 0;
  8. void usage(void) {
  9. fprintf(stderr, "usage: dumpdhcp local_ip_address [all] [headers]\n"
  10. " local_ip_address -- binds to this ip address\n"
  11. " all -- shows all UDP packets, not just MADCAP\n"
  12. " hdr -- shows headers only\n"
  13. );
  14. exit(1);
  15. }
  16. void convert_time(DWORD_PTR TimeVal, char *time_buf)
  17. {
  18. struct tm* pTime;
  19. char timeBuf[500];
  20. strcpy(timeBuf, " <???>");
  21. if (pTime = localtime(&TimeVal)) {
  22. SYSTEMTIME systemTime;
  23. int n;
  24. systemTime.wYear = pTime->tm_year + 1900;
  25. systemTime.wMonth = pTime->tm_mon + 1;
  26. systemTime.wDayOfWeek = (WORD)pTime->tm_wday;
  27. systemTime.wDay = (WORD)pTime->tm_mday;
  28. systemTime.wHour = (WORD)pTime->tm_hour;
  29. systemTime.wMinute = (WORD)pTime->tm_min;
  30. systemTime.wSecond = (WORD)pTime->tm_sec;
  31. systemTime.wMilliseconds = 0;
  32. timeBuf[0] = ' ';
  33. n = GetDateFormatA(
  34. LOCALE_NEUTRAL,
  35. DATE_SHORTDATE,
  36. &systemTime,
  37. NULL,
  38. &timeBuf[1],
  39. sizeof(timeBuf)
  40. );
  41. timeBuf[n] = ' ';
  42. GetTimeFormatA(
  43. LOCALE_NEUTRAL, 0, &systemTime,
  44. NULL, &timeBuf[n+1], sizeof(timeBuf) - n - 2
  45. );
  46. }
  47. strcpy(time_buf, timeBuf);
  48. }
  49. void socket_error(char *str) {
  50. fprintf(stderr, "FATAL: %s [0x%lx]\n", str, WSAGetLastError());
  51. exit(1);
  52. }
  53. void DumpInt(
  54. char *s, unsigned long x
  55. )
  56. {
  57. printf(s, x);
  58. }
  59. void DumpBytes(
  60. int tab_offset, int nbytes_per_line, int halfwaymark,
  61. unsigned char separation_character,
  62. unsigned char *buffer,
  63. unsigned long length
  64. )
  65. {
  66. unsigned long dumped;
  67. dumped = 0;
  68. while( dumped < length ) {
  69. if( tab_offset && 0 == (dumped % nbytes_per_line) ) {
  70. int i;
  71. if( dumped ) putchar('\n');
  72. for( i = 0; i < tab_offset; i ++ ) putchar(' ');
  73. } else if( tab_offset && halfwaymark ) {
  74. if( 0 == (dumped % halfwaymark ) ) {
  75. putchar(separation_character);
  76. }
  77. }
  78. printf( (separation_character)?"%02X%c":"%02X",
  79. (unsigned long)(*buffer++), separation_character
  80. );
  81. dumped++;
  82. }
  83. }
  84. typedef struct {
  85. unsigned char HeaderLen:4;
  86. unsigned char Version:4;
  87. unsigned char TOS;
  88. unsigned short Length;
  89. unsigned char Id;
  90. unsigned short Offset;
  91. unsigned char TTL;
  92. unsigned char Proto;
  93. unsigned char Xsum;
  94. struct in_addr Source;
  95. struct in_addr Dest;
  96. } IP_HEADER, *PIP_HEADER;
  97. typedef struct
  98. {
  99. unsigned short SourcePort;
  100. unsigned short DestPort;
  101. unsigned short Length;
  102. unsigned short Xsum;
  103. } UDP_HEADER, *PUDP_HEADER;
  104. #define MADCAP_SERVER_PORT 2535
  105. #define DHCP_SERVER_PORT 67
  106. #define DHCP_CLIENT_PORT 68
  107. #define MADCAP_OPTION_END 0
  108. #define MADCAP_OPTION_LEASE_TIME 1
  109. #define MADCAP_OPTION_SERVER_ID 2
  110. #define MADCAP_OPTION_CLIENT_ID 3
  111. #define MADCAP_OPTION_MCAST_SCOPE 4
  112. #define MADCAP_OPTION_REQUEST_LIST 5
  113. #define MADCAP_OPTION_START_TIME 6
  114. #define MADCAP_OPTION_ADDR_COUNT 7
  115. #define MADCAP_OPTION_REQUESTED_LANG 8
  116. #define MADCAP_OPTION_MCAST_SCOPE_LIST 9
  117. #define MADCAP_OPTION_ADDR_LIST 10
  118. #define MADCAP_OPTION_TIME 11
  119. #define MADCAP_OPTION_FEATURE_LIST 12
  120. #define MADCAP_OPTION_RETRY_TIME 13
  121. #define MADCAP_OPTION_MIN_LEASE_TIME 14
  122. #define MADCAP_OPTION_MAX_START_TIME 15
  123. char *madcap_option_list[] = {
  124. "End", "LeaseTime", "ServerId", "ClientId",
  125. "Scope", "RequestList", "StartTime", "AddressCount",
  126. "RequestedLanguage", "ScopeList", "AddressList",
  127. "Time", "FeatureList", "RetryTime", "MinLeaseTime",
  128. "MaxStartTime",
  129. };
  130. char *madcap_message_types[] = {
  131. "Unknown", "Discover",
  132. "Offer", "Request", "Renew", "Ack", "Nack", "Release", "Inform"
  133. };
  134. char *
  135. MadcapMessageType(
  136. unsigned long type
  137. )
  138. {
  139. static char type_buf[30];
  140. if( type > sizeof(madcap_message_types)/sizeof(madcap_message_types[0])) {
  141. sprintf(type_buf, "Unknown Message Type %ld", type);
  142. return type_buf;
  143. }
  144. return madcap_message_types[type];
  145. }
  146. typedef struct {
  147. WORD Type, Length;
  148. } MADCAP_OPTION_HEADER, *PMADCAP_OPTION_HEADER;
  149. void DumpMadcapOption(
  150. unsigned long OptionType,
  151. unsigned long OptionLength,
  152. char *Buffer
  153. )
  154. {
  155. int nOptions = sizeof(madcap_option_list)/sizeof(madcap_option_list[0]);
  156. DWORD Value;
  157. DWORD AddressFamily;
  158. struct in_addr ipaddr;
  159. int fprint_time = 0;
  160. char time_buf[500];
  161. time_buf[0] = ' ';
  162. time_buf[1] = '\0';
  163. do {
  164. if( OptionType > (unsigned long)nOptions ) break;
  165. if( 0 == OptionLength ) break;
  166. switch( OptionType ) {
  167. case MADCAP_OPTION_END :
  168. case MADCAP_OPTION_CLIENT_ID :
  169. case MADCAP_OPTION_REQUEST_LIST :
  170. case MADCAP_OPTION_REQUESTED_LANG :
  171. case MADCAP_OPTION_MCAST_SCOPE_LIST :
  172. case MADCAP_OPTION_ADDR_LIST :
  173. case MADCAP_OPTION_FEATURE_LIST :
  174. break;
  175. case MADCAP_OPTION_START_TIME :
  176. case MADCAP_OPTION_MAX_START_TIME :
  177. case MADCAP_OPTION_TIME :
  178. case MADCAP_OPTION_RETRY_TIME :
  179. fprint_time = TRUE;
  180. case MADCAP_OPTION_LEASE_TIME :
  181. case MADCAP_OPTION_MCAST_SCOPE :
  182. case MADCAP_OPTION_ADDR_COUNT :
  183. case MADCAP_OPTION_MIN_LEASE_TIME :
  184. //
  185. // print DWORD
  186. //
  187. if( sizeof(DWORD) != OptionLength ) break;
  188. Value = ntohl(*(DWORD UNALIGNED *)Buffer);
  189. if( fprint_time ) {
  190. convert_time(Value, time_buf);
  191. }
  192. printf(
  193. " Option %-20s :%s%ld\n",
  194. madcap_option_list[OptionType], time_buf, Value
  195. );
  196. return;
  197. case MADCAP_OPTION_SERVER_ID :
  198. //
  199. //
  200. //
  201. AddressFamily = (unsigned long)*Buffer;
  202. if( AF_INET != AddressFamily ) break;
  203. if( sizeof(ipaddr) + 1 != OptionLength ) break;
  204. Buffer ++;
  205. ipaddr = *((struct in_addr UNALIGNED *)Buffer);
  206. printf(
  207. " Option %-20s : %s\n",
  208. madcap_option_list[OptionType], inet_ntoa(ipaddr)
  209. );
  210. return;
  211. }
  212. } while ( 0 );
  213. //
  214. // some error..
  215. //
  216. if( OptionType > (unsigned long)nOptions ) {
  217. printf(" Option %-20ld : ", OptionType );
  218. } else printf(" Option %-20s : ", madcap_option_list[OptionType]);
  219. DumpBytes(0, 32, 16, ' ', Buffer, OptionLength); printf("\n");
  220. }
  221. void DumpMadcap(
  222. char *Buffer,
  223. unsigned long Size
  224. )
  225. {
  226. PMADCAP_MESSAGE Message = (PMADCAP_MESSAGE) Buffer;
  227. MADCAP_OPTION_HEADER Header;
  228. unsigned long DumpedSize;
  229. DumpBytes(8, 32, 16, ' ', Buffer, Size); printf("\n\n");
  230. printf(
  231. " %s Xid:0x%lx Version:0x%lx AddressFamily:0x%lx\n",
  232. MadcapMessageType(Message->MessageType),
  233. ntohl(Message->TransactionID), (DWORD)Message->Version,
  234. (DWORD)ntohs(Message->AddressFamily)
  235. );
  236. Buffer += sizeof(MADCAP_MESSAGE);
  237. DumpedSize = sizeof(MADCAP_MESSAGE);
  238. while( DumpedSize + sizeof(Header) <= Size ) {
  239. DumpedSize += sizeof(Header);
  240. Header = *(MADCAP_OPTION_HEADER UNALIGNED *)Buffer;
  241. Buffer += sizeof(Header);
  242. Header.Type = ntohs(Header.Type);
  243. Header.Length = ntohs(Header.Length);
  244. if( DumpedSize + Header.Length > Size ) {
  245. printf(" Type: 0x%lx, Length 0x%lx overrruns message end.\n",
  246. Header.Type, Header.Length);
  247. break;
  248. } else {
  249. DumpMadcapOption(Header.Type, Header.Length, Buffer);
  250. Buffer += Header.Length;
  251. DumpedSize += Header.Length;
  252. if( Header.Type == MADCAP_OPTION_END ) break;
  253. }
  254. }
  255. if( DumpedSize < Size ) {
  256. printf(" Trailing bytes:\n");
  257. DumpBytes(4, 16, 8, ' ', Buffer, Size - DumpedSize );
  258. printf("\n");
  259. }
  260. printf("\n");
  261. }
  262. void DumpDhcp(
  263. char *Buffer,
  264. unsigned long Size
  265. )
  266. {
  267. }
  268. void DumpBuffer(
  269. char *Buffer,
  270. unsigned long Size
  271. )
  272. {
  273. PIP_HEADER Ip;
  274. PUDP_HEADER Udp;
  275. unsigned long IpLength, UdpLength;
  276. unsigned long SrcPort, DestPort;
  277. int IsDhcp, IsMadcap;
  278. char time_buf[100];
  279. char *proto;
  280. Ip = (PIP_HEADER)Buffer;
  281. if( Size < sizeof(IP_HEADER) ) {
  282. DumpInt("IP header too small 0x%lx\n", Size);
  283. } else if( (IpLength = 4*((unsigned long)Ip->HeaderLen)) < sizeof(IP_HEADER ) ) {
  284. DumpInt("IP header reports wrong length 0x%lx\n", IpLength);
  285. } else if( (UdpLength = ntohs(Ip->Length)) < IpLength ) {
  286. DumpInt("Data length incorrect: 0x%lx\n", UdpLength);
  287. } else if( Ip->Proto != IPPROTO_UDP ) {
  288. //
  289. // Not UDP so ignore it
  290. //
  291. } else if( (UdpLength -= IpLength) < sizeof(UDP_HEADER)) {
  292. DumpInt("UDP Header size too small: 0x%lx\n", UdpLength);
  293. } else do {
  294. Udp = (PUDP_HEADER)(Buffer + IpLength);
  295. UdpLength = ntohs(Udp->Length) - sizeof(UDP_HEADER);
  296. Buffer = (char *)(&Udp[1]);
  297. SrcPort = ntohs(Udp->SourcePort);
  298. DestPort = ntohs(Udp->DestPort);
  299. IsDhcp = (SrcPort == DHCP_SERVER_PORT || DestPort == DHCP_SERVER_PORT
  300. || SrcPort == DHCP_CLIENT_PORT || DestPort == DHCP_CLIENT_PORT );
  301. IsMadcap = (DestPort == MADCAP_SERVER_PORT || SrcPort == MADCAP_SERVER_PORT);
  302. if( IsMadcap ) {
  303. proto = "MADCAP";
  304. } else if( IsDhcp ) {
  305. if( !show_headers && !show_all ) break;
  306. proto = "DHCP" ;
  307. } else {
  308. if( !show_all ) break;
  309. proto = "UDP" ;
  310. }
  311. _strtime(time_buf); printf("%s ", time_buf);
  312. printf("%s ", proto );
  313. printf("%s:%ld ---> ", inet_ntoa(Ip->Source), ntohs(Udp->SourcePort));
  314. printf("%s:%ld ", inet_ntoa(Ip->Dest), ntohs(Udp->DestPort));
  315. printf("%ld bytes\n", UdpLength);
  316. if( IsMadcap ) DumpMadcap(Buffer, UdpLength);
  317. // else if( IsDhcp ) DumpDhcp(Buffer, UdpLength);
  318. else {
  319. if( show_headers ) break;
  320. DumpBytes( 8, 32, 16, ' ', Buffer, UdpLength );
  321. printf("\n\n");
  322. }
  323. } while ( 0 );
  324. }
  325. char Buffer[70000];
  326. struct sockaddr_in SockAddr;
  327. void _cdecl main (int argc, char *argv[])
  328. {
  329. SOCKET s;
  330. int Error;
  331. DWORD RecvCount, Flags, dwEnable, dwDontCare;
  332. WSABUF WsaBufs[1];
  333. WSADATA WsaData;
  334. char *ipaddrstring = "0.0.0.0";
  335. if( argc > 1 ) {
  336. ipaddrstring = argv[1];
  337. }
  338. show_all = 0;
  339. show_headers = 0;
  340. if( argc > 2 ) {
  341. if( 0 == _stricmp(argv[2], "all" ) ) show_all = 1;
  342. else if( 0 == _stricmp(argv[2], "hdr") ) show_headers = 1;
  343. else usage();
  344. }
  345. if( argc > 3 ) {
  346. if( 0 == _stricmp(argv[3], "all" ) ) show_all = 1;
  347. else if( 0 == _stricmp(argv[3], "hdr") ) show_headers = 1;
  348. else usage();
  349. }
  350. Error = WSAStartup(MAKEWORD(2,0), &WsaData);
  351. if( 0 != Error ) {
  352. socket_error("WSAStartup");
  353. }
  354. s = WSASocket(
  355. AF_INET, SOCK_RAW, IPPROTO_IGMP, NULL, 0, 0
  356. );
  357. if( INVALID_SOCKET == s ) {
  358. socket_error("WSASocket");
  359. }
  360. SockAddr.sin_family = PF_INET;
  361. SockAddr.sin_addr.s_addr = inet_addr(ipaddrstring);
  362. Error = bind(s, (struct sockaddr *)&SockAddr, sizeof(SockAddr));
  363. if( 0 != Error ) {
  364. socket_error("bind");
  365. }
  366. dwEnable = 1;
  367. Error = WSAIoctl(
  368. s, SIO_RCVALL, (char *)&dwEnable, sizeof(dwEnable),
  369. NULL, 0, &dwDontCare, NULL, NULL
  370. );
  371. if( 0 != Error ) {
  372. socket_error("SIO_RCVALL");
  373. }
  374. while ( TRUE ) {
  375. WsaBufs[0].len = sizeof(Buffer);
  376. WsaBufs[0].buf = (char *)Buffer;
  377. Flags = 0;
  378. Error = WSARecv(
  379. s, WsaBufs, sizeof(WsaBufs)/sizeof(WsaBufs[0]),
  380. &RecvCount, &Flags, NULL, NULL
  381. );
  382. if( 0 != Error ) {
  383. socket_error("WSARecv");
  384. }
  385. DumpBuffer((char*)Buffer, RecvCount);
  386. }
  387. }