|
|
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
rippkt.c
Abstract:
Common RIP packet functions
Author:
Stefan Solomon 09/01/1995
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
/*++
Function: SetRipIpxHeader
Descr: sets the IPX packet header for a RIP packet to be sent from this machine & the RIP Operation Code
Arguments: hdrp - packet header pointer icbp - pointer to the interface CB on which the packet will be sent dstnode - destination node dstsocket - destination socket RipOpCode - operation to be set in the packet RIP header
Remark: the packet length is not set by this function
--*/
VOID SetRipIpxHeader(PUCHAR hdrp, // pointer to the packet header
PICB icbp, PUCHAR dstnode, PUCHAR dstsocket, USHORT RipOpcode) { PUTUSHORT2SHORT(hdrp + IPXH_CHECKSUM, 0xFFFF); *(hdrp + IPXH_XPORTCTL) = 0; *(hdrp + IPXH_PKTTYPE) = 1; // RIP packet
memcpy(hdrp + IPXH_DESTNET, icbp->AdapterBindingInfo.Network, 4); memcpy(hdrp + IPXH_DESTNODE, dstnode, 6); memcpy(hdrp + IPXH_DESTSOCK, dstsocket, 2); memcpy(hdrp + IPXH_SRCNET, icbp->AdapterBindingInfo.Network, 4); memcpy(hdrp + IPXH_SRCNODE, icbp->AdapterBindingInfo.LocalNode, 6); PUTUSHORT2SHORT(hdrp + IPXH_SRCSOCK, IPX_RIP_SOCKET);
// set the opcode
PUTUSHORT2SHORT(hdrp + RIP_OPCODE, RipOpcode); }
/*++
Function: SetNetworkEntry
Descr: sets a RIP network entry in the RIP packet
--*/
VOID SetNetworkEntry(PUCHAR pktp, // ptr where to set the net entry
PIPX_ROUTE IpxRoutep, USHORT LinkTickCount) // add to the route tick count
{ memcpy(pktp + NE_NETNUMBER, IpxRoutep->Network, 4); if (IpxRoutep->HopCount<16) PUTUSHORT2SHORT(pktp + NE_NROFHOPS, IpxRoutep->HopCount+1); else PUTUSHORT2SHORT(pktp + NE_NROFHOPS, IpxRoutep->HopCount);
// adjust the tick count with the adapter link speed (expressed as ticks)
PUTUSHORT2SHORT(pktp + NE_NROFTICKS, IpxRoutep->TickCount + LinkTickCount); }
/*++
Function: MakeRipGenResponsePacket
Descr: fills in a gen response packet network entries
Returns: the packet length. Note that a length of RIP_INFO means empty packet and a length of RIP_PACKET_LEN means full packet.
--*/
USHORT MakeRipGenResponsePacket(PWORK_ITEM wip, PUCHAR dstnodep, PUCHAR dstsocket) { PUCHAR hdrp; USHORT resplen; IPX_ROUTE IpxRoute; HANDLE EnumHandle; PICB icbp; // interface to send the gen response on
PICB route_icbp; // interface on which the route resides
hdrp = wip->Packet; EnumHandle = wip->WorkItemSpecific.WIS_EnumRoutes.RtmEnumerationHandle; icbp = wip->icbp;
// create the IPX packet header
SetRipIpxHeader(hdrp, icbp, dstnodep, dstsocket, RIP_RESPONSE);
resplen = RIP_INFO;
while(resplen < RIP_PACKET_LEN) { if(EnumGetNextRoute(EnumHandle, &IpxRoute) != NO_ERROR) {
break; }
// check if this route can be advertised over this interface
if(IsRouteAdvertisable(icbp, &IpxRoute)) {
// if this is the local client if, we advertise only the internal
// net over it
if(icbp->InterfaceType == LOCAL_WORKSTATION_DIAL) {
if(IpxRoute.InterfaceIndex != 0) {
// skip if not internal net
continue; } }
// check if the network doesn't appear also on the interface we
// will broadcast WITH THE SAME METRIC
if(IsDuplicateBestRoute(icbp, &IpxRoute)) {
continue; }
SetNetworkEntry(hdrp + resplen, &IpxRoute, icbp->LinkTickCount); resplen += NE_ENTRYSIZE; } }
// set the packet size in the IPX packet header
PUTUSHORT2SHORT(hdrp + IPXH_LENGTH, resplen);
return resplen; }
/*++
Function: SendRipGenRequest
Descr: sends a RIP General Request packet over the specified interface
Remark: >> called with the interface lock held <<
--*/
DWORD SendRipGenRequest(PICB icbp) { PWORK_ITEM wip; UCHAR ripsocket[2]; USHORT pktlen;
PUTUSHORT2SHORT(ripsocket, IPX_RIP_SOCKET);
if((wip = AllocateWorkItem(SEND_PACKET_TYPE)) == NULL) {
return ERROR_CAN_NOT_COMPLETE; }
wip->icbp = icbp; wip->AdapterIndex = icbp->AdapterBindingInfo.AdapterIndex;
SetRipIpxHeader(wip->Packet, icbp, bcastnode, ripsocket, RIP_REQUEST);
memcpy(wip->Packet + RIP_INFO + NE_NETNUMBER, bcastnet, 4); PUTUSHORT2SHORT(wip->Packet + RIP_INFO + NE_NROFHOPS, 0xFFFF); PUTUSHORT2SHORT(wip->Packet + RIP_INFO + NE_NROFTICKS, 0xFFFF);
pktlen = RIP_INFO + NE_ENTRYSIZE;
PUTUSHORT2SHORT(wip->Packet + IPXH_LENGTH, pktlen);
if(SendSubmit(wip) != NO_ERROR) {
FreeWorkItem(wip); }
return NO_ERROR; }
/*++
Function: IsRouteAdvertisable
Descr: checks if the route can be advertised over this interface
Arguments: interface to advertise on route
Remark: >> called with interface lock taken <<
--*/
BOOL IsRouteAdvertisable(PICB icbp, PIPX_ROUTE IpxRoutep) { if((icbp->InterfaceIndex != IpxRoutep->InterfaceIndex) && PassRipSupplyFilter(icbp, IpxRoutep->Network) && ((IpxRoutep->Flags & DO_NOT_ADVERTISE_ROUTE) == 0)) {
return TRUE; } else { return FALSE; } }
|