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.

239 lines
5.2 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. rippkt.c
  5. Abstract:
  6. Common RIP packet functions
  7. Author:
  8. Stefan Solomon 09/01/1995
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. /*++
  14. Function: SetRipIpxHeader
  15. Descr: sets the IPX packet header for a RIP packet to be sent
  16. from this machine & the RIP Operation Code
  17. Arguments:
  18. hdrp - packet header pointer
  19. icbp - pointer to the interface CB on which the packet will be sent
  20. dstnode - destination node
  21. dstsocket - destination socket
  22. RipOpCode - operation to be set in the packet RIP header
  23. Remark: the packet length is not set by this function
  24. --*/
  25. VOID
  26. SetRipIpxHeader(PUCHAR hdrp, // pointer to the packet header
  27. PICB icbp,
  28. PUCHAR dstnode,
  29. PUCHAR dstsocket,
  30. USHORT RipOpcode)
  31. {
  32. PUTUSHORT2SHORT(hdrp + IPXH_CHECKSUM, 0xFFFF);
  33. *(hdrp + IPXH_XPORTCTL) = 0;
  34. *(hdrp + IPXH_PKTTYPE) = 1; // RIP packet
  35. memcpy(hdrp + IPXH_DESTNET, icbp->AdapterBindingInfo.Network, 4);
  36. memcpy(hdrp + IPXH_DESTNODE, dstnode, 6);
  37. memcpy(hdrp + IPXH_DESTSOCK, dstsocket, 2);
  38. memcpy(hdrp + IPXH_SRCNET, icbp->AdapterBindingInfo.Network, 4);
  39. memcpy(hdrp + IPXH_SRCNODE, icbp->AdapterBindingInfo.LocalNode, 6);
  40. PUTUSHORT2SHORT(hdrp + IPXH_SRCSOCK, IPX_RIP_SOCKET);
  41. // set the opcode
  42. PUTUSHORT2SHORT(hdrp + RIP_OPCODE, RipOpcode);
  43. }
  44. /*++
  45. Function: SetNetworkEntry
  46. Descr: sets a RIP network entry in the RIP packet
  47. --*/
  48. VOID
  49. SetNetworkEntry(PUCHAR pktp, // ptr where to set the net entry
  50. PIPX_ROUTE IpxRoutep,
  51. USHORT LinkTickCount) // add to the route tick count
  52. {
  53. memcpy(pktp + NE_NETNUMBER, IpxRoutep->Network, 4);
  54. if (IpxRoutep->HopCount<16)
  55. PUTUSHORT2SHORT(pktp + NE_NROFHOPS, IpxRoutep->HopCount+1);
  56. else
  57. PUTUSHORT2SHORT(pktp + NE_NROFHOPS, IpxRoutep->HopCount);
  58. // adjust the tick count with the adapter link speed (expressed as ticks)
  59. PUTUSHORT2SHORT(pktp + NE_NROFTICKS, IpxRoutep->TickCount + LinkTickCount);
  60. }
  61. /*++
  62. Function: MakeRipGenResponsePacket
  63. Descr: fills in a gen response packet network entries
  64. Returns: the packet length. Note that a length of RIP_INFO means
  65. empty packet and a length of RIP_PACKET_LEN means full packet.
  66. --*/
  67. USHORT
  68. MakeRipGenResponsePacket(PWORK_ITEM wip,
  69. PUCHAR dstnodep,
  70. PUCHAR dstsocket)
  71. {
  72. PUCHAR hdrp;
  73. USHORT resplen;
  74. IPX_ROUTE IpxRoute;
  75. HANDLE EnumHandle;
  76. PICB icbp; // interface to send the gen response on
  77. PICB route_icbp; // interface on which the route resides
  78. hdrp = wip->Packet;
  79. EnumHandle = wip->WorkItemSpecific.WIS_EnumRoutes.RtmEnumerationHandle;
  80. icbp = wip->icbp;
  81. // create the IPX packet header
  82. SetRipIpxHeader(hdrp,
  83. icbp,
  84. dstnodep,
  85. dstsocket,
  86. RIP_RESPONSE);
  87. resplen = RIP_INFO;
  88. while(resplen < RIP_PACKET_LEN)
  89. {
  90. if(EnumGetNextRoute(EnumHandle, &IpxRoute) != NO_ERROR) {
  91. break;
  92. }
  93. // check if this route can be advertised over this interface
  94. if(IsRouteAdvertisable(icbp, &IpxRoute)) {
  95. // if this is the local client if, we advertise only the internal
  96. // net over it
  97. if(icbp->InterfaceType == LOCAL_WORKSTATION_DIAL) {
  98. if(IpxRoute.InterfaceIndex != 0) {
  99. // skip if not internal net
  100. continue;
  101. }
  102. }
  103. // check if the network doesn't appear also on the interface we
  104. // will broadcast WITH THE SAME METRIC
  105. if(IsDuplicateBestRoute(icbp, &IpxRoute)) {
  106. continue;
  107. }
  108. SetNetworkEntry(hdrp + resplen, &IpxRoute, icbp->LinkTickCount);
  109. resplen += NE_ENTRYSIZE;
  110. }
  111. }
  112. // set the packet size in the IPX packet header
  113. PUTUSHORT2SHORT(hdrp + IPXH_LENGTH, resplen);
  114. return resplen;
  115. }
  116. /*++
  117. Function: SendRipGenRequest
  118. Descr: sends a RIP General Request packet over the specified interface
  119. Remark: >> called with the interface lock held <<
  120. --*/
  121. DWORD
  122. SendRipGenRequest(PICB icbp)
  123. {
  124. PWORK_ITEM wip;
  125. UCHAR ripsocket[2];
  126. USHORT pktlen;
  127. PUTUSHORT2SHORT(ripsocket, IPX_RIP_SOCKET);
  128. if((wip = AllocateWorkItem(SEND_PACKET_TYPE)) == NULL) {
  129. return ERROR_CAN_NOT_COMPLETE;
  130. }
  131. wip->icbp = icbp;
  132. wip->AdapterIndex = icbp->AdapterBindingInfo.AdapterIndex;
  133. SetRipIpxHeader(wip->Packet,
  134. icbp,
  135. bcastnode,
  136. ripsocket,
  137. RIP_REQUEST);
  138. memcpy(wip->Packet + RIP_INFO + NE_NETNUMBER, bcastnet, 4);
  139. PUTUSHORT2SHORT(wip->Packet + RIP_INFO + NE_NROFHOPS, 0xFFFF);
  140. PUTUSHORT2SHORT(wip->Packet + RIP_INFO + NE_NROFTICKS, 0xFFFF);
  141. pktlen = RIP_INFO + NE_ENTRYSIZE;
  142. PUTUSHORT2SHORT(wip->Packet + IPXH_LENGTH, pktlen);
  143. if(SendSubmit(wip) != NO_ERROR) {
  144. FreeWorkItem(wip);
  145. }
  146. return NO_ERROR;
  147. }
  148. /*++
  149. Function: IsRouteAdvertisable
  150. Descr: checks if the route can be advertised over this interface
  151. Arguments: interface to advertise on
  152. route
  153. Remark: >> called with interface lock taken <<
  154. --*/
  155. BOOL
  156. IsRouteAdvertisable(PICB icbp,
  157. PIPX_ROUTE IpxRoutep)
  158. {
  159. if((icbp->InterfaceIndex != IpxRoutep->InterfaceIndex) &&
  160. PassRipSupplyFilter(icbp, IpxRoutep->Network) &&
  161. ((IpxRoutep->Flags & DO_NOT_ADVERTISE_ROUTE) == 0)) {
  162. return TRUE;
  163. }
  164. else
  165. {
  166. return FALSE;
  167. }
  168. }