818 lines
21 KiB
C
818 lines
21 KiB
C
/*
|
|
Module Name:
|
|
|
|
btest.c
|
|
|
|
Abstract:
|
|
|
|
This module sends sample BINL packets to the BINL server of your choice.
|
|
|
|
-b Use broadcast rather than directed datagram to <ServerName>
|
|
-s <Servername> To specify a BINL server of your choice. Default is COLINW2
|
|
|
|
Author:
|
|
|
|
Colin Watson Apr 29 1997
|
|
|
|
Revision History:
|
|
|
|
*/
|
|
|
|
#include <binl.h>
|
|
#pragma hdrstop
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <tdiinfo.h>
|
|
#include <wsipx.h>
|
|
#include <wsnwlink.h>
|
|
#include <nb30.h>
|
|
|
|
#include <binldef.h>
|
|
|
|
#define MAX_MSGLEN 80
|
|
#define MAX_ADDLEN 80
|
|
#define MAX_MSLOTNAME 80
|
|
|
|
typedef struct _OPTION2 {
|
|
BYTE OptionType;
|
|
BYTE OptionLength;
|
|
BYTE OptionValue[];
|
|
} OPTION2, *POPTION2, *LPOPTION2;
|
|
|
|
BOOL __stdcall
|
|
CtrlCHandler (
|
|
DWORD dwEvent
|
|
);
|
|
|
|
void __stdcall
|
|
Udp (
|
|
);
|
|
|
|
void __stdcall
|
|
Usage (
|
|
CHAR *pszProgramName
|
|
);
|
|
|
|
void __stdcall
|
|
PrintError (
|
|
LPSTR lpszRoutine,
|
|
LPSTR lpszCallName,
|
|
DWORD dwError
|
|
);
|
|
|
|
void __stdcall
|
|
DoStartup ( void );
|
|
|
|
void __stdcall
|
|
DoCleanup ( void );
|
|
|
|
VOID
|
|
GetHardwareAddress(
|
|
PUCHAR Address
|
|
);
|
|
|
|
VOID
|
|
DumpMessage(
|
|
LPDHCP_MESSAGE BinlMessage
|
|
);
|
|
|
|
//
|
|
// Global Variables
|
|
//
|
|
|
|
// If Startup was successful, fStarted is used to keep track.
|
|
BOOL fStarted = FALSE;
|
|
|
|
BOOL fBroadcast = FALSE;
|
|
|
|
// Global socket descriptor
|
|
SOCKET sock = INVALID_SOCKET;
|
|
|
|
LPSTR ServerName = "COLINW2";
|
|
|
|
ULONG ServerAddress;
|
|
ULONG ClientAddress;
|
|
|
|
void __cdecl
|
|
main (
|
|
INT argc,
|
|
CHAR **argv
|
|
)
|
|
{
|
|
int i;
|
|
|
|
//
|
|
// Install the CTRL+BREAK Handler
|
|
//
|
|
if ( FALSE == SetConsoleCtrlHandler ( (PHANDLER_ROUTINE) CtrlCHandler,
|
|
TRUE
|
|
) ){
|
|
PrintError ( "main", "SetConsoleCtrlHandler", GetLastError ( ) );
|
|
}
|
|
|
|
//
|
|
// allow the user to override settings with command line switches
|
|
//
|
|
for ( i = 1; i < argc; i++ )
|
|
{
|
|
if ( ( *argv[i] == '-' ) || ( *argv[i] == '/' ) )
|
|
{
|
|
switch ( tolower ( *( argv[i]+1 ) ) )
|
|
{
|
|
//
|
|
// Broadcast
|
|
//
|
|
case 'b':
|
|
fBroadcast = TRUE;
|
|
break;
|
|
//
|
|
// ServerName.
|
|
//
|
|
case 's':
|
|
ServerName = argv[++i];
|
|
break;
|
|
|
|
//
|
|
// Help.
|
|
//
|
|
case 'h':
|
|
case '?':
|
|
default:
|
|
Usage ( argv[0] );
|
|
}
|
|
}
|
|
else
|
|
//
|
|
// Help.
|
|
//
|
|
Usage ( argv[0] );
|
|
}
|
|
|
|
//
|
|
// Print a Summary of the switches specfied
|
|
// Helpful for debugging
|
|
//
|
|
fprintf ( stdout, "SUMMARY:\n" );
|
|
if (fBroadcast) {
|
|
fprintf ( stdout, "Broadcast test\n" );
|
|
} else {
|
|
fprintf ( stdout, "Unicast to BINL server %s\n", ServerName );
|
|
}
|
|
|
|
DoStartup ( );
|
|
Udp();
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// CtrlCHandler () intercepts the CTRL+BREAK or CTRL+C events and calls the
|
|
// cleanup routines.
|
|
//
|
|
BOOL __stdcall
|
|
CtrlCHandler (
|
|
DWORD dwEvent
|
|
)
|
|
{
|
|
if ( ( CTRL_C_EVENT == dwEvent ) || ( CTRL_BREAK_EVENT == dwEvent ) )
|
|
{
|
|
DoCleanup ( );
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void __stdcall
|
|
Discover(
|
|
)
|
|
{
|
|
// IP address structures needed to fill the source and destination
|
|
// addresses.
|
|
SOCKADDR_IN saUdpServ, saUdpCli;
|
|
|
|
INT err;
|
|
DWORD nSize;
|
|
|
|
UCHAR MessageBuffer[DHCP_MESSAGE_SIZE];
|
|
PDHCP_MESSAGE Message = (PDHCP_MESSAGE)&MessageBuffer[0];
|
|
|
|
// Data used for building Messages
|
|
LPOPTION Option;
|
|
|
|
UCHAR MagicCookie[] = {DHCP_MAGIC_COOKIE_BYTE1,
|
|
DHCP_MAGIC_COOKIE_BYTE2,
|
|
DHCP_MAGIC_COOKIE_BYTE3,
|
|
DHCP_MAGIC_COOKIE_BYTE4};
|
|
#define COOKIESIZE (4)
|
|
|
|
OPTION2 DiscoverOption = {OPTION_MESSAGE_TYPE, 1, DHCP_DISCOVER_MESSAGE};
|
|
#define DISCOVEROPTIONSIZE (DiscoverOption.OptionLength + 2)
|
|
|
|
OPTION2 ClientOption = {OPTION_CLIENT_CLASS_INFO,9,"PXEClient"};
|
|
// Size must ignore null at end of the string.
|
|
#define CLIENTOPTIONSIZE (ClientOption.OptionLength + 2)
|
|
|
|
OPTION2 NITOption = {OPTION_NETWORK_INTERFACE_TYPE,3,1,2,0};
|
|
// Size must ignore null at end of the string.
|
|
#define NITOPTIONSIZE (NITOption.OptionLength + 2)
|
|
|
|
OPTION2 SAOption = {OPTION_SYSTEM_ARCHITECTURE,1,0};
|
|
// Size must ignore null at end of the string.
|
|
#define SAOPTIONSIZE (SAOption.OptionLength + 2)
|
|
|
|
OPTION2 EndOption = {OPTION_END,0};
|
|
// Size must ignore null at end of the string.
|
|
#define ENDOPTIONSIZE (1)
|
|
|
|
do {
|
|
sendagain:
|
|
//
|
|
// Fill an IP address structure, to send an IP broadcast.
|
|
//
|
|
saUdpServ.sin_family = AF_INET;
|
|
if (fBroadcast) {
|
|
saUdpServ.sin_addr.s_addr = htonl ( INADDR_BROADCAST );
|
|
} else {
|
|
saUdpServ.sin_addr.s_addr = ServerAddress;
|
|
}
|
|
saUdpServ.sin_port = htons ( DHCP_SERVR_PORT );
|
|
|
|
// Practice with a dummy BINL Discover packet
|
|
ZeroMemory(MessageBuffer, sizeof(MessageBuffer));
|
|
Message->Operation = BOOT_REQUEST;
|
|
Option = &Message->Option;
|
|
|
|
GetHardwareAddress(Message->HardwareAddress);
|
|
Message->HardwareAddressType = 1;
|
|
Message->HardwareAddressLength = 6;
|
|
Message->TransactionID = 0x12345678;
|
|
|
|
memcpy(Option, &MagicCookie, COOKIESIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + COOKIESIZE);
|
|
|
|
memcpy(Option, &DiscoverOption, DISCOVEROPTIONSIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + DISCOVEROPTIONSIZE);
|
|
|
|
memcpy(Option, &ClientOption, CLIENTOPTIONSIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + CLIENTOPTIONSIZE);
|
|
|
|
memcpy(Option, &NITOption, NITOPTIONSIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + NITOPTIONSIZE);
|
|
|
|
memcpy(Option, &SAOption, SAOPTIONSIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + SAOPTIONSIZE);
|
|
|
|
memcpy(Option, &EndOption, ENDOPTIONSIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + ENDOPTIONSIZE);
|
|
|
|
err = sendto ( sock,
|
|
(PUCHAR)Message,
|
|
(PUCHAR)Option - (PUCHAR)Message,
|
|
0,
|
|
(SOCKADDR *) &saUdpServ,
|
|
sizeof ( SOCKADDR_IN )
|
|
);
|
|
|
|
if ( SOCKET_ERROR == err )
|
|
{
|
|
PrintError ( "Udp", "sendto", WSAGetLastError ( ) );
|
|
}
|
|
|
|
fprintf ( stdout, "%d bytes of data sent\n", err );
|
|
|
|
Sleep(1000); // Give server a few seconds to respond.
|
|
|
|
do {
|
|
|
|
err = ioctlsocket( sock, FIONREAD, &nSize);
|
|
|
|
if ( SOCKET_ERROR == err )
|
|
{
|
|
PrintError ( "Udp", "recvfrom", WSAGetLastError ( ) );
|
|
}
|
|
|
|
if (!nSize) {
|
|
goto sendagain; // we have processed all the DHCP/BINL responses
|
|
}
|
|
|
|
//
|
|
// receive a datagram on the bound port number.
|
|
//
|
|
|
|
nSize = sizeof ( SOCKADDR_IN );
|
|
err = recvfrom ( sock,
|
|
(PUCHAR)Message,
|
|
DHCP_MESSAGE_SIZE,
|
|
0,
|
|
(SOCKADDR FAR *) &saUdpCli,
|
|
&nSize
|
|
);
|
|
|
|
if ( SOCKET_ERROR == err )
|
|
{
|
|
PrintError ( "Udp", "recvfrom", WSAGetLastError ( ) );
|
|
}
|
|
|
|
if (Message->TransactionID == 0x12345678) {
|
|
goto processit;
|
|
}
|
|
} while ( 1 ); // while there are datagrams queued
|
|
|
|
} while (1);
|
|
|
|
processit:
|
|
|
|
//
|
|
// print the sender's information.
|
|
//
|
|
fprintf ( stdout, "A Udp Datagram of length %d bytes received from ", err );
|
|
fprintf ( stdout, "\n\tIP Adress->%s ", inet_ntoa ( saUdpCli.sin_addr ) );
|
|
fprintf ( stdout, "\n\tPort Number->%d\n", ntohs ( saUdpCli.sin_port ) );
|
|
|
|
DumpMessage(Message);
|
|
}
|
|
|
|
void __stdcall
|
|
Request(
|
|
)
|
|
{
|
|
// IP address structures needed to fill the source and destination
|
|
// addresses.
|
|
SOCKADDR_IN saUdpServ, saUdpCli;
|
|
|
|
INT err;
|
|
DWORD nSize;
|
|
|
|
UCHAR MessageBuffer[DHCP_MESSAGE_SIZE];
|
|
PDHCP_MESSAGE Message = (PDHCP_MESSAGE)&MessageBuffer[0];
|
|
|
|
// Data used for building Messages
|
|
LPOPTION Option;
|
|
|
|
UCHAR MagicCookie[] = {DHCP_MAGIC_COOKIE_BYTE1,
|
|
DHCP_MAGIC_COOKIE_BYTE2,
|
|
DHCP_MAGIC_COOKIE_BYTE3,
|
|
DHCP_MAGIC_COOKIE_BYTE4};
|
|
#define COOKIESIZE (4)
|
|
|
|
OPTION2 RequestOption = {OPTION_MESSAGE_TYPE, 1, DHCP_REQUEST_MESSAGE};
|
|
#define REQUESTOPTIONSIZE (RequestOption.OptionLength + 2)
|
|
|
|
OPTION2 ClientOption = {OPTION_CLIENT_CLASS_INFO,9,"PXEClient"};
|
|
// Size must ignore null at end of the string.
|
|
#define CLIENTOPTIONSIZE (ClientOption.OptionLength + 2)
|
|
|
|
OPTION2 NITOption = {OPTION_NETWORK_INTERFACE_TYPE,3,1,2,0};
|
|
// Size must ignore null at end of the string.
|
|
#define NITOPTIONSIZE (NITOption.OptionLength + 2)
|
|
|
|
OPTION2 SAOption = {OPTION_SYSTEM_ARCHITECTURE,1,0};
|
|
// Size must ignore null at end of the string.
|
|
#define SAOPTIONSIZE (SAOption.OptionLength + 2)
|
|
|
|
OPTION2 EndOption = {OPTION_END,0};
|
|
// Size must ignore null at end of the string.
|
|
#define ENDOPTIONSIZE (1)
|
|
|
|
do {
|
|
sendagain:
|
|
//
|
|
// Fill an IP address structure, to send an IP broadcast.
|
|
//
|
|
saUdpServ.sin_family = AF_INET;
|
|
if (fBroadcast) {
|
|
saUdpServ.sin_addr.s_addr = htonl ( INADDR_BROADCAST );
|
|
} else {
|
|
saUdpServ.sin_addr.s_addr = ServerAddress;
|
|
}
|
|
//saUdpServ.sin_port = htons ( BINL_DEFAULT_PORT );
|
|
saUdpServ.sin_port = htons ( 0xaee8 );
|
|
|
|
// Practice with a dummy BINL Request packet
|
|
ZeroMemory(MessageBuffer, sizeof(MessageBuffer));
|
|
Message->Operation = BOOT_REQUEST;
|
|
Option = &Message->Option;
|
|
|
|
GetHardwareAddress(Message->HardwareAddress);
|
|
Message->HardwareAddressType = 1;
|
|
Message->HardwareAddressLength = 6;
|
|
Message->TransactionID = 0x56781234;
|
|
Message->YourIpAddress = ClientAddress;
|
|
|
|
memcpy(Option, &MagicCookie, COOKIESIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + COOKIESIZE);
|
|
|
|
memcpy(Option, &RequestOption, REQUESTOPTIONSIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + REQUESTOPTIONSIZE);
|
|
|
|
memcpy(Option, &ClientOption, CLIENTOPTIONSIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + CLIENTOPTIONSIZE);
|
|
|
|
memcpy(Option, &NITOption, NITOPTIONSIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + NITOPTIONSIZE);
|
|
|
|
memcpy(Option, &SAOption, SAOPTIONSIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + SAOPTIONSIZE);
|
|
|
|
memcpy(Option, &EndOption, ENDOPTIONSIZE);
|
|
Option = (LPOPTION)((PUCHAR)Option + ENDOPTIONSIZE);
|
|
|
|
err = sendto ( sock,
|
|
(PUCHAR)Message,
|
|
(PUCHAR)Option - (PUCHAR)Message,
|
|
0,
|
|
(SOCKADDR *) &saUdpServ,
|
|
sizeof ( SOCKADDR_IN )
|
|
);
|
|
|
|
if ( SOCKET_ERROR == err )
|
|
{
|
|
PrintError ( "Udp", "sendto", WSAGetLastError ( ) );
|
|
}
|
|
|
|
fprintf ( stdout, "%d bytes of data sent\n", err );
|
|
|
|
Sleep(1000); // Give server a few seconds to respond.
|
|
|
|
do {
|
|
|
|
err = ioctlsocket( sock, FIONREAD, &nSize);
|
|
|
|
if ( SOCKET_ERROR == err )
|
|
{
|
|
PrintError ( "Udp", "recvfrom", WSAGetLastError ( ) );
|
|
}
|
|
|
|
if (!nSize) {
|
|
goto sendagain; // we have processed all the DHCP/BINL responses
|
|
}
|
|
|
|
//
|
|
// receive a datagram on the bound port number.
|
|
//
|
|
|
|
nSize = sizeof ( SOCKADDR_IN );
|
|
err = recvfrom ( sock,
|
|
(PUCHAR)Message,
|
|
DHCP_MESSAGE_SIZE,
|
|
0,
|
|
(SOCKADDR FAR *) &saUdpCli,
|
|
&nSize
|
|
);
|
|
|
|
if ( SOCKET_ERROR == err )
|
|
{
|
|
PrintError ( "Udp", "recvfrom", WSAGetLastError ( ) );
|
|
}
|
|
|
|
if (Message->TransactionID == 0x56781234) {
|
|
goto processit;
|
|
}
|
|
} while ( 1 ); // while there are datagrams queued
|
|
|
|
} while (1);
|
|
|
|
processit:
|
|
|
|
//
|
|
// print the sender's information.
|
|
//
|
|
fprintf ( stdout, "A Udp Datagram of length %d bytes received from ", err );
|
|
fprintf ( stdout, "\n\tIP Adress->%s ", inet_ntoa ( saUdpCli.sin_addr ) );
|
|
fprintf ( stdout, "\n\tPort Number->%d\n", ntohs ( saUdpCli.sin_port ) );
|
|
|
|
DumpMessage(Message);
|
|
}
|
|
|
|
void __stdcall
|
|
Udp(
|
|
)
|
|
{
|
|
INT err;
|
|
LPHOSTENT pServerHostEntry;
|
|
char MyName[80];
|
|
|
|
// IP address structures needed to fill the source and destination
|
|
// addresses.
|
|
SOCKADDR_IN saUdpServ, saUdpCli;
|
|
|
|
//
|
|
// Initialize the global socket descriptor.
|
|
//
|
|
sock = socket ( AF_INET, SOCK_DGRAM, 0 );
|
|
|
|
if ( INVALID_SOCKET == sock)
|
|
{
|
|
PrintError ( "Udp", "socket", WSAGetLastError() );
|
|
}
|
|
|
|
if (fBroadcast) {
|
|
err = setsockopt ( sock,
|
|
SOL_SOCKET,
|
|
SO_BROADCAST,
|
|
(CHAR *) &fBroadcast,
|
|
sizeof ( BOOL )
|
|
);
|
|
|
|
if ( SOCKET_ERROR == err )
|
|
{
|
|
PrintError ( "Udp", "setsockopt", WSAGetLastError ( ) );
|
|
}
|
|
} else {
|
|
// Convert ServerName to an IP address
|
|
ServerAddress = inet_addr(ServerName); // Dotted form of address
|
|
|
|
if ((ServerAddress == INADDR_NONE) &&
|
|
(memcmp(ServerName, "255.255.255.255", sizeof("255.255.255.255")))) {
|
|
// must be a servername
|
|
pServerHostEntry = gethostbyname(ServerName);
|
|
if (pServerHostEntry) {
|
|
ServerAddress = *((PULONG)(pServerHostEntry->h_addr));
|
|
} else {
|
|
PrintError ( "Udp", "gethostbyname", WSAGetLastError ( ) );
|
|
return;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// bind to a local socket and an interface.
|
|
//
|
|
saUdpCli.sin_family = AF_INET;
|
|
saUdpCli.sin_addr.s_addr = htonl ( INADDR_ANY );
|
|
saUdpCli.sin_port = htons ( DHCP_CLIENT_PORT );
|
|
|
|
err = bind ( sock, (SOCKADDR *) &saUdpCli, sizeof (SOCKADDR_IN) );
|
|
|
|
if ( SOCKET_ERROR == err )
|
|
{
|
|
PrintError ( "Udp", "bind", WSAGetLastError ( ) );
|
|
}
|
|
|
|
// Find my (clients) IP address.
|
|
if (gethostname(MyName, sizeof(MyName)) != SOCKET_ERROR ){
|
|
PHOSTENT Host;
|
|
Host = gethostbyname(MyName);
|
|
if (Host) {
|
|
ClientAddress = *(PDHCP_IP_ADDRESS)Host->h_addr;
|
|
}
|
|
}
|
|
|
|
Discover();
|
|
|
|
Request();
|
|
|
|
//
|
|
// Call the cleanup routine.
|
|
//
|
|
DoCleanup ( );
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//
|
|
// Usage () lists the available command line options.
|
|
//
|
|
void __stdcall
|
|
Usage (
|
|
CHAR *pszProgramName
|
|
)
|
|
{
|
|
fprintf ( stderr, "Usage: %s\n", pszProgramName );
|
|
fprintf ( stderr, "\t-b Use broadcast to DHCP/BINL socket\n" );
|
|
fprintf ( stderr,
|
|
"\t-s <ServerName>, Use directed datagram to ServerName default - COLINW2)\n" );
|
|
exit ( 1 );
|
|
}
|
|
|
|
|
|
//
|
|
// PrintError () is a function available globally for printing the error and
|
|
// doing the cleanup.
|
|
//
|
|
void __stdcall
|
|
PrintError (
|
|
LPSTR lpszRoutine,
|
|
LPSTR lpszCallName,
|
|
DWORD dwError
|
|
)
|
|
{
|
|
|
|
fprintf ( stderr,
|
|
"The Call to %s() in routine() %s failed with error %d\n",
|
|
lpszCallName,
|
|
lpszRoutine,
|
|
dwError
|
|
);
|
|
|
|
DoCleanup ( );
|
|
|
|
exit ( 1 );
|
|
}
|
|
|
|
//
|
|
// DoStartup () initializes the Winsock DLL with Winsock version 1.1
|
|
//
|
|
void __stdcall
|
|
DoStartup ( void )
|
|
{
|
|
WSADATA wsaData;
|
|
|
|
INT iRetVal;
|
|
|
|
iRetVal = WSAStartup ( MAKEWORD ( 1,1 ), &wsaData );
|
|
|
|
if ( 0 != iRetVal)
|
|
{
|
|
PrintError ( "DoStartup", "WSAStartup", iRetVal );
|
|
}
|
|
|
|
//
|
|
// Set the global flag.
|
|
//
|
|
fStarted = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// DoCleanup () will close the global socket which was opened successfully by
|
|
// a call to socket (). Additionally, it will call WSACleanup (), if a call
|
|
// to WSAStartup () was made successfully.
|
|
//
|
|
void __stdcall
|
|
DoCleanup ( void )
|
|
{
|
|
if ( INVALID_SOCKET != sock )
|
|
{
|
|
closesocket ( sock );
|
|
}
|
|
|
|
if ( TRUE == fStarted )
|
|
{
|
|
WSACleanup ( );
|
|
}
|
|
|
|
fprintf ( stdout, "DONE\n" );
|
|
|
|
return;
|
|
}
|
|
|
|
#define ClearNcb( PNCB ) { \
|
|
ZeroMemory( PNCB , sizeof (NCB) ); \
|
|
MoveMemory( (PNCB)->ncb_name, SPACES, sizeof(SPACES)-1 );\
|
|
MoveMemory( (PNCB)->ncb_callname, SPACES, sizeof(SPACES)-1 );\
|
|
}
|
|
|
|
#define SPACES " "
|
|
|
|
VOID
|
|
GetHardwareAddress(
|
|
PUCHAR Address
|
|
) {
|
|
NCB myncb;
|
|
ADAPTER_STATUS adapterstatus;
|
|
UCHAR lanNumber;
|
|
|
|
LANA_ENUM Enum;
|
|
ClearNcb( &myncb );
|
|
myncb.ncb_command = NCBENUM;
|
|
myncb.ncb_lana_num = 0;
|
|
myncb.ncb_length = sizeof(Enum);
|
|
myncb.ncb_buffer = (PUCHAR)&Enum;
|
|
Netbios( &myncb );
|
|
if (( myncb.ncb_retcode != NRC_GOODRET ) ||
|
|
( !Enum.length )) {
|
|
return;
|
|
}
|
|
|
|
lanNumber = Enum.lana[0];
|
|
|
|
ClearNcb( &myncb );
|
|
myncb.ncb_command = NCBRESET;
|
|
myncb.ncb_lsn = 0; // Request resources
|
|
myncb.ncb_lana_num = lanNumber;
|
|
myncb.ncb_callname[0] = 0; // 16 sessions
|
|
myncb.ncb_callname[1] = 0; // 16 commands
|
|
myncb.ncb_callname[2] = 0; // 8 names
|
|
Netbios( &myncb );
|
|
|
|
if ( myncb.ncb_retcode != NRC_GOODRET ) return;
|
|
|
|
ClearNcb( &myncb );
|
|
myncb.ncb_command = NCBASTAT;
|
|
myncb.ncb_lana_num = lanNumber;
|
|
myncb.ncb_buffer = (PUCHAR)&adapterstatus;
|
|
myncb.ncb_length = sizeof(adapterstatus);
|
|
myncb.ncb_callname[0] = '*';
|
|
|
|
Netbios( &myncb );
|
|
if ( myncb.ncb_retcode != NRC_GOODRET ) return;
|
|
|
|
CopyMemory(Address, &adapterstatus.adapter_address[0], 6);
|
|
}
|
|
|
|
VOID
|
|
DumpMessage(
|
|
LPDHCP_MESSAGE BinlMessage
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function dumps a DHCP packet in human readable form.
|
|
|
|
Arguments:
|
|
|
|
BinlMessage - A pointer to a DHCP message.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
LPOPTION option;
|
|
BYTE i;
|
|
|
|
fprintf ( stdout,"Binl message: \n\n");
|
|
|
|
fprintf ( stdout,"Operation :");
|
|
if ( BinlMessage->Operation == BOOT_REQUEST ) {
|
|
fprintf ( stdout, "BootRequest\n");
|
|
} else if ( BinlMessage->Operation == BOOT_REPLY ) {
|
|
fprintf ( stdout, "BootReply\n");
|
|
} else {
|
|
fprintf ( stdout, "Unknown\n");
|
|
}
|
|
|
|
fprintf ( stdout,"Hardware Address type : %d\n", BinlMessage->HardwareAddressType);
|
|
fprintf ( stdout,"Hardware Address Length: %d\n", BinlMessage->HardwareAddressLength);
|
|
fprintf ( stdout,"Hop Count : %d\n", BinlMessage->HopCount );
|
|
fprintf ( stdout,"Transaction ID : %lx\n", BinlMessage->TransactionID );
|
|
fprintf ( stdout,"Seconds Since Boot : %d\n", BinlMessage->SecondsSinceBoot );
|
|
fprintf ( stdout,"Client IP Address : " );
|
|
fprintf ( stdout,"%s\n",
|
|
inet_ntoa(*(struct in_addr *)&BinlMessage->ClientIpAddress ) );
|
|
|
|
fprintf ( stdout,"Your IP Address : " );
|
|
fprintf ( stdout,"%s\n",
|
|
inet_ntoa(*(struct in_addr *)&BinlMessage->YourIpAddress ) );
|
|
|
|
fprintf ( stdout,"Server IP Address : " );
|
|
fprintf ( stdout,"%s\n",
|
|
inet_ntoa(*(struct in_addr *)&BinlMessage->BootstrapServerAddress ) );
|
|
|
|
fprintf ( stdout,"Relay Agent IP Address : " );
|
|
fprintf ( stdout,"%s\n",
|
|
inet_ntoa(*(struct in_addr *)&BinlMessage->RelayAgentIpAddress ) );
|
|
|
|
fprintf ( stdout,"Hardware Address : ");
|
|
for ( i = 0; i < BinlMessage->HardwareAddressLength; i++ ) {
|
|
fprintf ( stdout,"%2.2x", BinlMessage->HardwareAddress[i] );
|
|
}
|
|
|
|
if (BinlMessage->HostName[0]) {
|
|
fprintf( stdout, "\nHostName \"%s\"\n", BinlMessage->HostName);
|
|
}
|
|
if (BinlMessage->BootFileName[0]) {
|
|
fprintf( stdout, "BootFileName \"%s\"\n", BinlMessage->BootFileName);
|
|
}
|
|
|
|
option = &BinlMessage->Option;
|
|
|
|
fprintf ( stdout,"\nMagic Cookie: ");
|
|
for ( i = 0; i < 4; i++ ) {
|
|
fprintf ( stdout,"%d ", *((LPBYTE)option)++ );
|
|
}
|
|
fprintf ( stdout,"\n\n");
|
|
|
|
fprintf ( stdout,"Options:\n");
|
|
while ( option->OptionType != 255 ) {
|
|
fprintf ( stdout,"\tType = %d ", option->OptionType );
|
|
for ( i = 0; i < option->OptionLength; i++ ) {
|
|
fprintf ( stdout,"%2.2x", option->OptionValue[i] );
|
|
}
|
|
fprintf ( stdout,"\n");
|
|
|
|
if ( option->OptionType == OPTION_PAD ||
|
|
option->OptionType == OPTION_END ) {
|
|
|
|
option = (LPOPTION)( (LPBYTE)(option) + 1);
|
|
|
|
} else {
|
|
|
|
option = (LPOPTION)( (LPBYTE)(option) + option->OptionLength + 2);
|
|
|
|
}
|
|
|
|
if ( (LPBYTE)option - (LPBYTE)BinlMessage > DHCP_MESSAGE_SIZE ) {
|
|
fprintf ( stdout,"End of message, but no trailer found!\n");
|
|
break;
|
|
}
|
|
}
|
|
}
|