mirror of https://github.com/lianthony/NT4.0
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.
1213 lines
28 KiB
1213 lines
28 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
supp.c
|
|
|
|
Abstract:
|
|
|
|
Support routines for the RIP test program
|
|
|
|
Author:
|
|
|
|
Sam Patton (sampa) 04-Oct-1993
|
|
|
|
Environment:
|
|
|
|
User mode sockets app
|
|
|
|
Revision History:
|
|
|
|
dd-mmm-yyy <email>
|
|
|
|
--*/
|
|
|
|
#include <winsock.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <malloc.h>
|
|
|
|
#include "types.h"
|
|
#include "proto.h"
|
|
|
|
int trace = 0;
|
|
|
|
void
|
|
Usage(
|
|
char * ExeName)
|
|
{
|
|
int SpaceAllocated;
|
|
char * SpaceBuffer;
|
|
char Space[2] = " ";
|
|
unsigned int i;
|
|
char * NameBuffer;
|
|
|
|
if (trace) {
|
|
printf("Usage entered\n");
|
|
}
|
|
|
|
for (NameBuffer = ExeName+strlen(ExeName); ; NameBuffer --) {
|
|
if (NameBuffer == ExeName) {
|
|
break;
|
|
}
|
|
if (*NameBuffer == '\\') {
|
|
NameBuffer ++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
SpaceBuffer = (char *) malloc((strlen(NameBuffer) + 1) * sizeof(char));
|
|
if (SpaceBuffer) {
|
|
SpaceAllocated = 1;
|
|
for (i=0; i<strlen(NameBuffer); i++) {
|
|
SpaceBuffer[i] = ' ';
|
|
}
|
|
SpaceBuffer[strlen(NameBuffer)] = '\0';
|
|
} else {
|
|
SpaceAllocated = 0;
|
|
SpaceBuffer = Space;
|
|
}
|
|
|
|
printf("%s send <ip address> <source port> <command> <version> <reserved 1)\n", NameBuffer);
|
|
printf("%s <address family> <reserved 2> <IP address>\n", SpaceBuffer);
|
|
printf("%s <reserved 3> <reserved 4> <metric>\n", SpaceBuffer);
|
|
printf("%s <address family> <reserved 2> <IP address>\n", SpaceBuffer);
|
|
printf("%s <reserved 3> <reserved 4> <metric>\n", SpaceBuffer);
|
|
printf("%s ....\n", SpaceBuffer);
|
|
printf("%s send -f <addressfile>\n", SpaceBuffer);
|
|
printf("%s -f <commandfile> [commandfile] ...\n", NameBuffer);
|
|
printf("%s receive <ip address> [timeout]\n", NameBuffer);
|
|
for (i=0; i<strlen(SpaceBuffer); i++) {
|
|
SpaceBuffer[i] = '-';
|
|
}
|
|
printf("%s---------------------------------------------------\n", SpaceBuffer);
|
|
printf("where <ip address> of the form 11.1.15.76\n");
|
|
printf(" <command> 1 for request\n");
|
|
printf(" 2 for response\n");
|
|
printf(" 3 for traceon\n");
|
|
printf(" 4 for traceoff\n");
|
|
printf(" 5 for reserved Sun command\n");
|
|
printf(" <version> 1 for rfc 1058\n");
|
|
printf(" <address family> 2 for ip\n");
|
|
printf(" <metric> integer 0-16\n");
|
|
printf(" <reserved #> 0\n");
|
|
printf(" [timeout] timeout in seconds to wait for RIP packet\n");
|
|
printf(" <addressfile> file containing arguments for the send command\n");
|
|
printf(" <commandfile> file containing commands of the above form\n");
|
|
|
|
if (SpaceAllocated) {
|
|
free(SpaceBuffer);
|
|
}
|
|
}
|
|
|
|
PRIP_ANNOUNCEMENT
|
|
ReceiveRipAnnouncement(
|
|
int argc,
|
|
char * argv[])
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This listens for a RIP announcement from a given router.
|
|
|
|
Arguments:
|
|
|
|
argc - number of command line arguments
|
|
argv - array of command line arguments
|
|
|
|
Return Value:
|
|
|
|
Pointer to a RIP_ANNOUNCEMENT structure. NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
BOOL ReceiveAny;
|
|
struct sockaddr_in RemoteAddress;
|
|
int ReuseFlag;
|
|
struct sockaddr_in RipAddress;
|
|
unsigned int RipAddressLength;
|
|
PRIP_ANNOUNCEMENT RipAnnouncement;
|
|
SOCKET RipSocket;
|
|
unsigned char RipBuffer[RIP_BUFFER_SIZE];
|
|
int Status;
|
|
|
|
if (trace) {
|
|
printf("ReceiveRipAnnouncement entered\n");
|
|
}
|
|
|
|
//
|
|
// argv[2] should be the ip address of the machine that I want to receive
|
|
// from. If there is no argv[2], receive any announcement.
|
|
//
|
|
|
|
if (argc < 2) {
|
|
Usage(argv[0]);
|
|
fprintf(stderr, "Incorrect number of arguments\n");
|
|
return NULL;
|
|
}
|
|
|
|
if (argc == 3) {
|
|
ReceiveAny = FALSE;
|
|
} else {
|
|
ReceiveAny = TRUE;
|
|
}
|
|
|
|
if (!ReceiveAny) {
|
|
RemoteAddress.sin_addr.S_un.S_addr = inet_addr(argv[2]);
|
|
}
|
|
|
|
//
|
|
// Open the RIP socket.
|
|
// Socket 520, UDP
|
|
//
|
|
|
|
if (trace) {
|
|
printf("ReceiveRipAnnouncement - socket\n");
|
|
}
|
|
|
|
RipSocket =
|
|
socket(
|
|
AF_INET,
|
|
SOCK_DGRAM,
|
|
0);
|
|
|
|
if (RipSocket == INVALID_SOCKET) {
|
|
fprintf(stderr, "Error opening listening RIP socket\n");
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Set the socket to be reusable
|
|
//
|
|
|
|
ReuseFlag = 1;
|
|
|
|
Status =
|
|
setsockopt(
|
|
RipSocket,
|
|
SOL_SOCKET,
|
|
SO_REUSEADDR,
|
|
(char *) &ReuseFlag,
|
|
sizeof(ReuseFlag));
|
|
|
|
if (Status) {
|
|
fprintf(stderr, "Error setting RIP socket to be reusable\n");
|
|
closesocket(RipSocket);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Bind to socket 520
|
|
//
|
|
|
|
RipAddress.sin_family = AF_INET;
|
|
RipAddress.sin_port = htons(520);
|
|
RipAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
if (trace) {
|
|
printf("ReceiveRipAnnouncement - bind\n");
|
|
}
|
|
|
|
Status =
|
|
bind(
|
|
RipSocket,
|
|
(struct sockaddr *) &RipAddress,
|
|
sizeof(RipAddress));
|
|
|
|
if (Status) {
|
|
fprintf(stderr, "Error binding listening RIP socket\n");
|
|
closesocket(RipSocket);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Get a RIP announcement
|
|
//
|
|
|
|
if (trace) {
|
|
printf("ReceiveRipAnnouncement - recvfrom\n");
|
|
}
|
|
|
|
do {
|
|
RipAddressLength = sizeof(RipAddress);
|
|
|
|
Status =
|
|
recvfrom(
|
|
RipSocket,
|
|
RipBuffer,
|
|
sizeof(RipBuffer),
|
|
0,
|
|
(struct sockaddr *) &RipAddress,
|
|
&RipAddressLength);
|
|
|
|
} while ((!ReceiveAny) && RipAddress.sin_addr.S_un.S_addr != RemoteAddress.sin_addr.S_un.S_addr);
|
|
|
|
if (trace) {
|
|
printf("ReceiveRipAnnouncement - ParseRipAnnouncement\n");
|
|
}
|
|
|
|
RipAnnouncement =
|
|
ParseRipAnnouncement(
|
|
RipBuffer,
|
|
Status,
|
|
&RipAddress,
|
|
RipAddressLength);
|
|
|
|
closesocket(RipSocket);
|
|
|
|
return RipAnnouncement;
|
|
}
|
|
|
|
PRIP_ANNOUNCEMENT
|
|
ParseRipAnnouncement(
|
|
char * RipBuffer,
|
|
int RipBufferLength,
|
|
struct sockaddr_in * RemoteAddress,
|
|
int RemoteAddressLength)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This parses a given rip announcement into a RIP_ANNOUNCEMENT structure for
|
|
further parsing.
|
|
|
|
Arguments:
|
|
|
|
RipBuffer - buffer containing the rip announcement
|
|
RipBufferLength - length of the buffer.
|
|
RemoteAddress - originating machine
|
|
RemoteAddressLength - length of address.
|
|
|
|
Return Value:
|
|
|
|
A RIP_ANNOUNCEMENT pointer if successful.
|
|
NULL if not.
|
|
|
|
--*/
|
|
{
|
|
PRIP_ANNOUNCEMENT RipAnnouncement;
|
|
PRIP_ADDRESS_FIELD RipAddressField, AddressFieldPtr;
|
|
char * CurrentPointer;
|
|
|
|
if (trace) {
|
|
printf("ParseRipAnnouncement entered\n");
|
|
}
|
|
|
|
RipAnnouncement = (PRIP_ANNOUNCEMENT) malloc (sizeof(RIP_ANNOUNCEMENT));
|
|
if (RipAnnouncement == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Copy the first part of the RIP announcement into the structure.
|
|
//
|
|
|
|
memmove(RipAnnouncement, RipBuffer, 4);
|
|
memmove(&RipAnnouncement->RemoteAddress,RemoteAddress, RemoteAddressLength);
|
|
RipAnnouncement->Address = NULL;
|
|
|
|
//
|
|
// Copy the address fields into the structure
|
|
//
|
|
|
|
for (CurrentPointer = RipBuffer + 4;
|
|
CurrentPointer < RipBuffer + RipBufferLength;
|
|
CurrentPointer += 20) {
|
|
|
|
RipAddressField = (PRIP_ADDRESS_FIELD) malloc (sizeof(RIP_ADDRESS_FIELD));
|
|
if (RipAddressField == NULL) {
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
memmove(RipAddressField, CurrentPointer, 20);
|
|
RipAddressField->Next = NULL;
|
|
if (RipAnnouncement->Address == NULL) {
|
|
RipAnnouncement->Address = RipAddressField;
|
|
} else {
|
|
for (AddressFieldPtr = RipAnnouncement->Address;
|
|
AddressFieldPtr->Next;
|
|
AddressFieldPtr = AddressFieldPtr->Next);
|
|
AddressFieldPtr->Next = RipAddressField;
|
|
}
|
|
}
|
|
|
|
return RipAnnouncement;
|
|
}
|
|
|
|
void
|
|
FreeRipAnnouncement(
|
|
PRIP_ANNOUNCEMENT RipAnnouncement)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This frees all of the structures associated with a RIP_ANNOUNCEMENT.
|
|
|
|
Arguments:
|
|
|
|
RipAnnouncement - announcement to be freed
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PRIP_ADDRESS_FIELD AddressField1, AddressField2;
|
|
|
|
if (trace) {
|
|
printf("FreeRipAnnouncement entered\n");
|
|
}
|
|
|
|
if (RipAnnouncement->Address) {
|
|
if (RipAnnouncement->Address->Next) {
|
|
AddressField1 = RipAnnouncement->Address;
|
|
AddressField2 = RipAnnouncement->Address->Next;
|
|
while (AddressField2->Next) {
|
|
AddressField1 = AddressField2;
|
|
AddressField2 = AddressField2->Next;
|
|
}
|
|
free(AddressField2);
|
|
AddressField1->Next = NULL;
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
} else {
|
|
free(RipAnnouncement->Address);
|
|
}
|
|
}
|
|
free(RipAnnouncement);
|
|
}
|
|
|
|
void
|
|
PrintRipAnnouncement(
|
|
PRIP_ANNOUNCEMENT RipAnnouncement)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This prints out a RIP announcement in human readable format.
|
|
|
|
Arguments:
|
|
|
|
RipAnnouncement - announcement to print.
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PRIP_ADDRESS_FIELD AddressFieldPtr;
|
|
struct in_addr InAddress;
|
|
|
|
if (trace) {
|
|
printf("PrintRipAnnouncement entered\n");
|
|
}
|
|
|
|
//
|
|
// Print out the first part
|
|
//
|
|
|
|
printf("Source - %s\n", inet_ntoa(RipAnnouncement->RemoteAddress.sin_addr));
|
|
printf("Port - %lu\n", (long) htons(RipAnnouncement->RemoteAddress.sin_port));
|
|
printf("Command - %x\n", (long) RipAnnouncement->Command);
|
|
printf("Version - %x\n", (long) RipAnnouncement->Version);
|
|
printf("Reserved - %x\n", (long) htons(RipAnnouncement->Reserved1));
|
|
printf("\n");
|
|
|
|
//
|
|
// Print out the address part
|
|
//
|
|
|
|
for (AddressFieldPtr = RipAnnouncement->Address;
|
|
AddressFieldPtr;
|
|
AddressFieldPtr = AddressFieldPtr->Next) {
|
|
printf("AddressFamily - %x\n", (long) htons(AddressFieldPtr->AddressFamily));
|
|
printf("Reserved - %x\n", (long) htons(AddressFieldPtr->Reserved1));
|
|
InAddress.S_un.S_addr = AddressFieldPtr->Address;
|
|
printf("Address - %s\n", inet_ntoa(InAddress));
|
|
printf("Reserved - %x\n", (long) htonl(AddressFieldPtr->Reserved2));
|
|
printf("Reserved - %x\n", (long) htonl(AddressFieldPtr->Reserved3));
|
|
printf("Metric - %x\n", (long) htonl(AddressFieldPtr->Metric));
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
void
|
|
ProcessCommandFile(
|
|
int argc,
|
|
char * argv[])
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function processes a command file and does all of the requests in the
|
|
command file.
|
|
|
|
Arguments:
|
|
|
|
argc - number of arguments
|
|
argv - array of arguments
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
FILE * InputFile;
|
|
char InputBuffer[256];
|
|
char * ArgPointer;
|
|
int NumArgs;
|
|
BOOL InArg;
|
|
char ** ArgArray;
|
|
|
|
if (argc == 2) {
|
|
Usage(argv[0]);
|
|
return;
|
|
}
|
|
|
|
argc -= 2;
|
|
argv += 2;
|
|
|
|
while (argc != 0) {
|
|
|
|
//
|
|
// Open input file
|
|
//
|
|
|
|
InputFile = fopen(*argv, "r");
|
|
if (InputFile == NULL) {
|
|
printf("Error opening file %s\n", *argv);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Read the file and process the commands. Each line is a seperate
|
|
// command.
|
|
//
|
|
|
|
while (fgets(InputBuffer, 256, InputFile) != NULL) {
|
|
//
|
|
// Count the arguments
|
|
//
|
|
NumArgs = 1;
|
|
InArg = FALSE;
|
|
|
|
for (ArgPointer = InputBuffer; *ArgPointer; ArgPointer ++) {
|
|
if ((*ArgPointer == ' ') || (*ArgPointer == '\t') || (*ArgPointer == '\n')) {
|
|
if (InArg) {
|
|
NumArgs ++;
|
|
InArg = FALSE;
|
|
}
|
|
} else {
|
|
InArg = TRUE;
|
|
}
|
|
}
|
|
|
|
if (NumArgs > 1) {
|
|
//
|
|
// Allocate the argument array
|
|
//
|
|
|
|
ArgArray = (char **) malloc (sizeof(char *) * NumArgs);
|
|
if (ArgArray == NULL) {
|
|
printf("Error processing file %s\n", *argv);
|
|
return;
|
|
}
|
|
|
|
NumArgs = 1;
|
|
InArg = FALSE;
|
|
for (ArgPointer = InputBuffer; *ArgPointer; ArgPointer ++) {
|
|
if ((*ArgPointer == ' ') || (*ArgPointer == '\t') || (*ArgPointer == '\n')) {
|
|
if (InArg) {
|
|
NumArgs ++;
|
|
InArg = FALSE;
|
|
*ArgPointer = '\0';
|
|
}
|
|
} else {
|
|
if (!InArg) {
|
|
InArg = TRUE;
|
|
ArgArray[NumArgs] = ArgPointer;
|
|
}
|
|
}
|
|
}
|
|
ArgArray[0] = "Script RIP_TEST";
|
|
main(NumArgs, ArgArray);
|
|
}
|
|
}
|
|
|
|
fclose(InputFile);
|
|
argc --;
|
|
argv ++;
|
|
}
|
|
}
|
|
|
|
PRIP_ANNOUNCEMENT
|
|
CreateRipAnnouncementFromCommandLine(
|
|
int argc,
|
|
char * argv[])
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function creates a RIP announcement from the given arguments.
|
|
The arguments are of two possible forms - see usage above for the formats.
|
|
|
|
Arguments:
|
|
|
|
argc - number of arguments
|
|
argv - array of arguments
|
|
|
|
Return Value:
|
|
|
|
A rip announcement on success.
|
|
NULL on failure
|
|
|
|
--*/
|
|
{
|
|
PRIP_ADDRESS_FIELD AddressFieldPtr;
|
|
char ArgBuffer[80];
|
|
char * ExeName = argv[0];
|
|
FILE * InputFile;
|
|
PRIP_ADDRESS_FIELD RipAddressField;
|
|
PRIP_ANNOUNCEMENT RipAnnouncement;
|
|
int Status;
|
|
|
|
if (trace) {
|
|
printf("CreateRipAnnouncementFromCommandLine entered\n");
|
|
}
|
|
|
|
if (argc < 4) {
|
|
Usage(argv[0]);
|
|
return NULL;
|
|
}
|
|
|
|
argc -= 1;
|
|
argv += 1;
|
|
|
|
RipAnnouncement = (PRIP_ANNOUNCEMENT) malloc (sizeof(RIP_ANNOUNCEMENT));
|
|
if (RipAnnouncement == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
RipAnnouncement->RemoteAddress.sin_family = AF_INET;
|
|
RipAnnouncement->RemoteAddress.sin_port = htons(520);
|
|
RipAnnouncement->Address = NULL;
|
|
|
|
if (strncmp(argv[1], "-f", 2) != 0) {
|
|
//
|
|
// Case 1 - all of the arguments are on the command line
|
|
//
|
|
|
|
//
|
|
// First argument - ip address
|
|
//
|
|
|
|
argc --;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d ip address %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
return NULL;
|
|
}
|
|
|
|
RipAnnouncement->RemoteAddress.sin_addr.S_un.S_addr = inet_addr(*argv);
|
|
|
|
//
|
|
// Second argument - source port
|
|
//
|
|
|
|
argc --;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d source port %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
return NULL;
|
|
}
|
|
|
|
RipAnnouncement->LocalAddress.sin_family = AF_INET;
|
|
RipAnnouncement->LocalAddress.sin_port = htons((WORD) atoi(*argv));
|
|
RipAnnouncement->LocalAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
//
|
|
// Third argument - command
|
|
//
|
|
|
|
argc --;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d command %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
return NULL;
|
|
}
|
|
|
|
RipAnnouncement->Command = atoi(*argv);
|
|
|
|
//
|
|
// Fourth argument - version
|
|
//
|
|
|
|
argc --;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d version %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
return NULL;
|
|
}
|
|
|
|
RipAnnouncement->Version = atoi(*argv);
|
|
|
|
//
|
|
// Fifth argument - reserved1
|
|
//
|
|
|
|
argc --;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d reserved1 %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
return NULL;
|
|
}
|
|
|
|
RipAnnouncement->Reserved1 = htons((WORD) atoi(*argv));
|
|
|
|
//
|
|
// The rest of the arguments are addresses to be filled in
|
|
//
|
|
|
|
while (argc > 1) {
|
|
|
|
RipAddressField = (PRIP_ADDRESS_FIELD) malloc (sizeof(RIP_ADDRESS_FIELD));
|
|
if (RipAddressField == NULL) {
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
RipAddressField->Next = NULL;
|
|
if (RipAnnouncement->Address == NULL) {
|
|
RipAnnouncement->Address = RipAddressField;
|
|
} else {
|
|
for (AddressFieldPtr = RipAnnouncement->Address;
|
|
AddressFieldPtr->Next;
|
|
AddressFieldPtr = AddressFieldPtr->Next);
|
|
AddressFieldPtr->Next = RipAddressField;
|
|
}
|
|
|
|
//
|
|
// Address Family
|
|
//
|
|
|
|
argc --;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d Address Family %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
RipAddressField->AddressFamily = htons((WORD) atoi(*argv));
|
|
|
|
//
|
|
// Reserved1
|
|
//
|
|
|
|
argc --;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d Reserved1 %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
RipAddressField->Reserved1 = htons((WORD) atoi(*argv));
|
|
|
|
//
|
|
// Address
|
|
//
|
|
|
|
argc --;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d Address %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
RipAddressField->Address = inet_addr(*argv);
|
|
|
|
//
|
|
// Reserved2
|
|
//
|
|
|
|
argc --;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d Reserved2 %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
RipAddressField->Reserved2 = htonl(atoi(*argv));
|
|
|
|
//
|
|
// Reserved3
|
|
//
|
|
|
|
argc --;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d Reserved3 %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
RipAddressField->Reserved3 = htonl(atoi(*argv));
|
|
|
|
//
|
|
// Metric
|
|
//
|
|
|
|
argc --;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d Metric %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
RipAddressField->Metric = htonl(atoi(*argv));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// Case 2 - the arguments are in a file
|
|
//
|
|
|
|
//
|
|
// File name
|
|
//
|
|
|
|
argc --;
|
|
argc --;
|
|
argv ++;
|
|
argv ++;
|
|
|
|
if (trace) {
|
|
printf("%d File name %s\n", argc, *argv);
|
|
}
|
|
|
|
if (argc == 0) {
|
|
Usage(ExeName);
|
|
return NULL;
|
|
}
|
|
|
|
InputFile = fopen(*argv, "r");
|
|
|
|
if (InputFile == NULL) {
|
|
printf("Error opening file %s\n", *argv);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// First argument - ip address
|
|
//
|
|
|
|
Status = fscanf(InputFile, "%s", ArgBuffer);
|
|
|
|
if (Status != 1) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
if (trace) {
|
|
printf("ip address %s\n", ArgBuffer);
|
|
}
|
|
|
|
RipAnnouncement->RemoteAddress.sin_addr.S_un.S_addr = inet_addr(ArgBuffer);
|
|
|
|
//
|
|
// Second argument - source port
|
|
//
|
|
|
|
Status = fscanf(InputFile, "%s", ArgBuffer);
|
|
|
|
if (Status != 1) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
if (trace) {
|
|
printf("source port %s\n", ArgBuffer);
|
|
}
|
|
|
|
RipAnnouncement->LocalAddress.sin_family = AF_INET;
|
|
RipAnnouncement->LocalAddress.sin_port = htons((WORD) atoi(ArgBuffer));
|
|
RipAnnouncement->LocalAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
//
|
|
// Third argument - command
|
|
//
|
|
|
|
Status = fscanf(InputFile, "%s", ArgBuffer);
|
|
|
|
if (Status != 1) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
if (trace) {
|
|
printf("command %s\n", ArgBuffer);
|
|
}
|
|
|
|
RipAnnouncement->Command = atoi(ArgBuffer);
|
|
|
|
//
|
|
// Fourth argument - version
|
|
//
|
|
|
|
Status = fscanf(InputFile, "%s", ArgBuffer);
|
|
|
|
if (Status != 1) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
if (trace) {
|
|
printf("version %s\n", ArgBuffer);
|
|
}
|
|
|
|
RipAnnouncement->Version = atoi(ArgBuffer);
|
|
|
|
//
|
|
// Fifth argument - reserved1
|
|
//
|
|
|
|
Status = fscanf(InputFile, "%s", ArgBuffer);
|
|
|
|
if (Status != 1) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
if (trace) {
|
|
printf("reserved1 %s\n", ArgBuffer);
|
|
}
|
|
|
|
RipAnnouncement->Reserved1 = htons((WORD) atoi(ArgBuffer));
|
|
|
|
//
|
|
// The rest of the arguments are addresses to be filled in
|
|
//
|
|
|
|
while (1) {
|
|
|
|
RipAddressField = (PRIP_ADDRESS_FIELD) malloc (sizeof(RIP_ADDRESS_FIELD));
|
|
if (RipAddressField == NULL) {
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
RipAddressField->Next = NULL;
|
|
if (RipAnnouncement->Address == NULL) {
|
|
RipAnnouncement->Address = RipAddressField;
|
|
} else {
|
|
for (AddressFieldPtr = RipAnnouncement->Address;
|
|
AddressFieldPtr->Next;
|
|
AddressFieldPtr = AddressFieldPtr->Next);
|
|
AddressFieldPtr->Next = RipAddressField;
|
|
}
|
|
|
|
//
|
|
// Address Family
|
|
//
|
|
|
|
Status = fscanf(InputFile, "%s", ArgBuffer);
|
|
|
|
if (Status != 1) {
|
|
//
|
|
// End of file
|
|
//
|
|
break;
|
|
}
|
|
|
|
if (trace) {
|
|
printf("Address Family %s\n", ArgBuffer);
|
|
}
|
|
|
|
RipAddressField->AddressFamily = htons((WORD) atoi(ArgBuffer));
|
|
|
|
//
|
|
// Reserved1
|
|
//
|
|
|
|
Status = fscanf(InputFile, "%s", ArgBuffer);
|
|
|
|
if (Status != 1) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
if (trace) {
|
|
printf("Reserved1 %s\n", ArgBuffer);
|
|
}
|
|
|
|
RipAddressField->Reserved1 = htons((WORD) atoi(ArgBuffer));
|
|
|
|
//
|
|
// Address
|
|
//
|
|
|
|
Status = fscanf(InputFile, "%s", ArgBuffer);
|
|
|
|
if (Status != 1) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
if (trace) {
|
|
printf("Address %s\n", ArgBuffer);
|
|
}
|
|
|
|
RipAddressField->Address = inet_addr(ArgBuffer);
|
|
|
|
//
|
|
// Reserved2
|
|
//
|
|
|
|
Status = fscanf(InputFile, "%s", ArgBuffer);
|
|
|
|
if (Status != 1) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
if (trace) {
|
|
printf("Reserved2 %s\n", ArgBuffer);
|
|
}
|
|
|
|
RipAddressField->Reserved2 = htonl(atoi(ArgBuffer));
|
|
|
|
//
|
|
// Reserved3
|
|
//
|
|
|
|
Status = fscanf(InputFile, "%s", ArgBuffer);
|
|
|
|
if (Status != 1) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
if (trace) {
|
|
printf("Reserved3 %s\n", ArgBuffer);
|
|
}
|
|
|
|
RipAddressField->Reserved3 = htonl(atoi(ArgBuffer));
|
|
|
|
//
|
|
// Metric
|
|
//
|
|
|
|
Status = fscanf(InputFile, "%s", ArgBuffer);
|
|
|
|
if (Status != 1) {
|
|
Usage(ExeName);
|
|
FreeRipAnnouncement(RipAnnouncement);
|
|
return NULL;
|
|
}
|
|
|
|
if (trace) {
|
|
printf("Metric %s\n", ArgBuffer);
|
|
}
|
|
|
|
RipAddressField->Metric = htonl(atoi(ArgBuffer));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return RipAnnouncement;
|
|
|
|
}
|
|
|
|
BOOL
|
|
SendRipAnnouncement(
|
|
PRIP_ANNOUNCEMENT RipAnnouncement)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function sends a RIP announcement with the given arguments.
|
|
|
|
Arguments:
|
|
|
|
RipAnnouncement - announcment to send.
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
--*/
|
|
{
|
|
char * CurrentPointer;
|
|
int ReuseFlag;
|
|
PRIP_ADDRESS_FIELD RipAddressField;
|
|
unsigned char RipBuffer[RIP_BUFFER_SIZE];
|
|
SOCKET RipSocket;
|
|
int Status;
|
|
|
|
if (trace) {
|
|
printf("SendRipAnnouncement entered\n");
|
|
}
|
|
|
|
CurrentPointer = (char *) RipBuffer;
|
|
memmove(CurrentPointer, RipAnnouncement, 4);
|
|
|
|
CurrentPointer += 4;
|
|
RipAddressField = RipAnnouncement->Address;
|
|
|
|
while (RipAddressField) {
|
|
memmove(CurrentPointer, RipAddressField, 20);
|
|
CurrentPointer += 20;
|
|
RipAddressField = RipAddressField->Next;
|
|
}
|
|
|
|
//
|
|
// Open the local socket.
|
|
//
|
|
|
|
RipSocket =
|
|
socket(
|
|
AF_INET,
|
|
SOCK_DGRAM,
|
|
0);
|
|
|
|
if (RipSocket == INVALID_SOCKET) {
|
|
fprintf(stderr, "Error opening source RIP socket\n");
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Set the socket to be reusable
|
|
//
|
|
|
|
ReuseFlag = 1;
|
|
|
|
Status =
|
|
setsockopt(
|
|
RipSocket,
|
|
SOL_SOCKET,
|
|
SO_REUSEADDR,
|
|
(char *) &ReuseFlag,
|
|
sizeof(ReuseFlag));
|
|
|
|
if (Status) {
|
|
fprintf(stderr, "Error setting RIP socket to be reusable\n");
|
|
closesocket(RipSocket);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Bind to socket
|
|
//
|
|
|
|
Status =
|
|
bind(
|
|
RipSocket,
|
|
(struct sockaddr *) &RipAnnouncement->LocalAddress,
|
|
sizeof(RipAnnouncement->LocalAddress));
|
|
|
|
if (Status) {
|
|
fprintf(stderr, "Error binding source RIP socket\n");
|
|
closesocket(RipSocket);
|
|
return FALSE;
|
|
}
|
|
|
|
Status =
|
|
sendto(
|
|
RipSocket,
|
|
RipBuffer,
|
|
CurrentPointer-RipBuffer,
|
|
0,
|
|
(struct sockaddr *) &RipAnnouncement->RemoteAddress,
|
|
sizeof(RipAnnouncement->RemoteAddress));
|
|
|
|
closesocket(RipSocket);
|
|
|
|
if (trace) {
|
|
printf("sendto returned %d\n", Status);
|
|
printf("GetLastError %lx\n", GetLastError());
|
|
}
|
|
|
|
if (Status == (CurrentPointer-RipBuffer)) {
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|