os/kernelhwsrv/kerneltest/e32utils/netcards/netcards.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 1995-2007 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description:
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
/**
sl@0
    20
@internalTechnology
sl@0
    21
@file
sl@0
    22
sl@0
    23
Implementation of the Netcards.exe adapter selection application.
sl@0
    24
This version writes settings to an ethernet.ini file only. Those settings 
sl@0
    25
should be either copied into epoc.ini (EKA2) or extracted into correct setup 
sl@0
    26
files: ethermac.dat and etherdriver.dat (EKA1) using an appropriate tool.
sl@0
    27
*/
sl@0
    28
sl@0
    29
/*
sl@0
    30
 * Desired design of maximum size and alignment.
sl@0
    31
 * These are implementation specific.
sl@0
    32
 */
sl@0
    33
#define _SS_MAXSIZE 128                  // Maximum size.
sl@0
    34
#define _SS_ALIGNSIZE (sizeof(__int64))  // Desired alignment.
sl@0
    35
sl@0
    36
/*
sl@0
    37
 * Definitions used for sockaddr_storage structure paddings design.
sl@0
    38
 */
sl@0
    39
/**
sl@0
    40
 * This version of netcards.c has been written to work and run on Windows 2000
sl@0
    41
 * and Windows XP. It has been compiled against both WinPCap 4.0.
sl@0
    42
 *
sl@0
    43
 * We identify the version of the compiler from the macros set by E32PLAT.pm 
sl@0
    44
 * and if .NET assume that winsock2 will be used (although this is not needed).
sl@0
    45
 */
sl@0
    46
sl@0
    47
#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (short))
sl@0
    48
#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (short) + _SS_PAD1SIZE \
sl@0
    49
                                                    + _SS_ALIGNSIZE))
sl@0
    50
sl@0
    51
struct sockaddr_storage {
sl@0
    52
    short ss_family;               // Address family.
sl@0
    53
    char __ss_pad1[_SS_PAD1SIZE];  // 6 byte pad, this is to make
sl@0
    54
                                   // implementation specific pad up to
sl@0
    55
                                   // alignment field that follows explicit
sl@0
    56
                                   // in the data structure.
sl@0
    57
    __int64 __ss_align;            // Field to force desired structure.
sl@0
    58
    char __ss_pad2[_SS_PAD2SIZE];  // 112 byte pad to achieve desired size;
sl@0
    59
                                   // _SS_MAXSIZE value minus size of
sl@0
    60
                                   // ss_family, __ss_pad1, and
sl@0
    61
                                   // __ss_align fields is 112.
sl@0
    62
};
sl@0
    63
sl@0
    64
// Forward declare struct _RPC_ASYNC_STATE, to avoid a warning in rpcasync.h
sl@0
    65
struct _RPC_ASYNC_STATE;
sl@0
    66
sl@0
    67
// include WinPcap
sl@0
    68
// The dance with warnings is necessary to avoid warnings such as
sl@0
    69
//
sl@0
    70
// \MSVC6\VC98\include\qos.h(236) : warning C4201: nonstandard extension used : 
sl@0
    71
// 	nameless struct/union 
sl@0
    72
//
sl@0
    73
// when we compile at warning level 4.
sl@0
    74
// 
sl@0
    75
sl@0
    76
#pragma warning(disable:4514)
sl@0
    77
#pragma warning(push,3)
sl@0
    78
#include "pcap.h"
sl@0
    79
#pragma warning(pop)
sl@0
    80
sl@0
    81
//other includes
sl@0
    82
#include "packet32.h"
sl@0
    83
#include "ntddndis.h"
sl@0
    84
#include <windows.h>
sl@0
    85
sl@0
    86
#include <stdio.h>
sl@0
    87
#include <malloc.h>
sl@0
    88
#include <conio.h>
sl@0
    89
sl@0
    90
sl@0
    91
#define EPOC_INI_FILE			"ethernet.ini"
sl@0
    92
sl@0
    93
#define EPOC_INI_FILE_TEMP		"__temp__ethernet__.ini"
sl@0
    94
sl@0
    95
#define	ETHER_NIF_ENTRY			"ETHER_NIF"			
sl@0
    96
#define	ETHER_MAC_ENTRY			"ETHER_MAC"
sl@0
    97
#define	ETHER_SPEED_ENTRY		"ETHER_SPEED"
sl@0
    98
sl@0
    99
#define MAX_VALUE		80
sl@0
   100
#define MAX_LINE		100
sl@0
   101
#define MAX_OID_DATA	256
sl@0
   102
sl@0
   103
#define MAX_ADAPTER_LEN	1024
sl@0
   104
#define MAX_ADAPTERS	10
sl@0
   105
sl@0
   106
#define OID_802_3_CURRENT_ADDRESS		   		0x01010102
sl@0
   107
sl@0
   108
sl@0
   109
//
sl@0
   110
// Global list of supported adapter names.
sl@0
   111
//
sl@0
   112
char	AdapterList[MAX_ADAPTERS][MAX_ADAPTER_LEN];
sl@0
   113
sl@0
   114
sl@0
   115
//
sl@0
   116
// Replace or write new 'value' for 'entry' in epoc.ini file
sl@0
   117
// returns 0 if ok, negative value if sth wrong
sl@0
   118
//
sl@0
   119
int replace_in_inifile(char * entry, char* value, BOOL valUnicode );
sl@0
   120
sl@0
   121
sl@0
   122
//
sl@0
   123
// Gets the adapter speed and mac address. Returns 0 if no mac is available,
sl@0
   124
// otherwise returns non-zero if successful.
sl@0
   125
//
sl@0
   126
int get_adapter_speed_and_mac(char* adapterName, UINT* speed, unsigned char* mac);
sl@0
   127
sl@0
   128
//
sl@0
   129
// Main entry point.
sl@0
   130
//
sl@0
   131
int main(int argc, char* argv[])
sl@0
   132
{
sl@0
   133
	char err[PCAP_ERRBUF_SIZE + 1];
sl@0
   134
	
sl@0
   135
sl@0
   136
	// string that contains a list of the network adapters
sl@0
   137
	pcap_if_t *adapterlist, *adapter;
sl@0
   138
sl@0
   139
	int					adapters=0, adapterToUse, i;
sl@0
   140
	UINT				speed_Mbps = 0;
sl@0
   141
	unsigned char		mac[6];
sl@0
   142
sl@0
   143
	FILE				*inifile;
sl@0
   144
sl@0
   145
	char				speed_value[10];
sl@0
   146
	char				*MAC_value = malloc( 13*sizeof(char) );
sl@0
   147
	char				*temp2 = malloc( 13*sizeof(char) );
sl@0
   148
	int					interfaceArg = 0;
sl@0
   149
	int					MACmode = 0;
sl@0
   150
sl@0
   151
	if ( argc>1 && argv[1] )
sl@0
   152
	{
sl@0
   153
		interfaceArg = atoi(argv[1])%10;
sl@0
   154
		MACmode = atoi(argv[1])/10;	//used for set ethernet/WLAN MAC address 
sl@0
   155
	}
sl@0
   156
	//printf("interfaceArg=%d, MACmode=%d\n", interfaceArg, MACmode);
sl@0
   157
sl@0
   158
	//
sl@0
   159
	// Obtain the name of the adapters installed on this machine.
sl@0
   160
	//
sl@0
   161
	// The result of this function is obtained querying the registry, 
sl@0
   162
	// and therefore the format of the result in Windows NTx is different
sl@0
   163
	// from the one in Windows 9x. Windows 9x uses the ASCII encoding method
sl@0
   164
	// to store a string, while Windows NTx uses UNICODE.
sl@0
   165
	//
sl@0
   166
	// In addition different versions of PCAP vary this behaviour meaning
sl@0
   167
	// that the returned data cannot be assumed to be one format or the
sl@0
   168
	// other - in other words we must check it ourselves.
sl@0
   169
	//
sl@0
   170
	printf("\nAdapters installed:\n");
sl@0
   171
	
sl@0
   172
	if(pcap_findalldevs(&adapterlist, err) < 0)
sl@0
   173
		{
sl@0
   174
		printf("Error - pcap_findalldevs: %s\n", err);
sl@0
   175
		return (1);
sl@0
   176
		}
sl@0
   177
	for(adapter = adapterlist; adapter; adapter = adapter->next)
sl@0
   178
		{
sl@0
   179
		memcpy(AdapterList[adapters], adapter->name, strlen(adapter->name));
sl@0
   180
		if(get_adapter_speed_and_mac(AdapterList[adapters], &speed_Mbps, mac))
sl@0
   181
			{
sl@0
   182
			printf("\n%3d - %s\n", adapters+1, AdapterList[adapters]);
sl@0
   183
			adapters++;
sl@0
   184
			}
sl@0
   185
		else
sl@0
   186
			{
sl@0
   187
			printf("\nN/A - %s\n",AdapterList[adapters]);			
sl@0
   188
			}
sl@0
   189
		printf("        %s\n", adapter->description);
sl@0
   190
		}
sl@0
   191
	printf("\n");
sl@0
   192
sl@0
   193
	if (adapters>1)
sl@0
   194
		{
sl@0
   195
		if((interfaceArg>adapters)||(interfaceArg<1) )
sl@0
   196
			{
sl@0
   197
			do
sl@0
   198
				{
sl@0
   199
				printf("Select the number of the adapter to use : ");
sl@0
   200
				scanf("%d",&adapterToUse);
sl@0
   201
				if (adapterToUse > adapters  ||  adapterToUse < 1)
sl@0
   202
					{
sl@0
   203
					printf("\nThe number must be between 1 and %d\n",adapters);
sl@0
   204
					}
sl@0
   205
				} while (adapterToUse > adapters  ||  adapterToUse < 1);
sl@0
   206
			}
sl@0
   207
		else
sl@0
   208
			{
sl@0
   209
			adapterToUse = interfaceArg;
sl@0
   210
			}
sl@0
   211
  		}
sl@0
   212
	else
sl@0
   213
		{
sl@0
   214
		adapterToUse = adapters;
sl@0
   215
 		}
sl@0
   216
sl@0
   217
	MAC_value[0] = '\0';
sl@0
   218
	temp2[0] = '\0';
sl@0
   219
	speed_value[0] = '\0';
sl@0
   220
	
sl@0
   221
	//
sl@0
   222
	// Open the adapter if available...
sl@0
   223
	//
sl@0
   224
	if (adapterToUse > 0  &&  adapterToUse <= adapters)
sl@0
   225
	{
sl@0
   226
		printf("\nUsing adapter %d\n", adapterToUse);
sl@0
   227
sl@0
   228
		if (get_adapter_speed_and_mac(AdapterList[adapterToUse-1], &speed_Mbps, mac))
sl@0
   229
		{
sl@0
   230
			if (speed_Mbps == 0)
sl@0
   231
			{
sl@0
   232
				printf("Could not read Ethernet card's speed\n");
sl@0
   233
			}
sl@0
   234
sl@0
   235
			printf("Physical address read: %02x:%02x:%02x:%02x:%02x:%02x\n",
sl@0
   236
				   mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
sl@0
   237
sl@0
   238
			if(MACmode == 0)	//ethernet MAC
sl@0
   239
				{
sl@0
   240
				mac[0] += 2; // changing address from global to local
sl@0
   241
				}
sl@0
   242
			
sl@0
   243
			for( i=0; i<6; i++ )
sl@0
   244
			{
sl@0
   245
				strcpy( temp2, MAC_value);
sl@0
   246
				if( mac[i] > 15 )
sl@0
   247
				{
sl@0
   248
					// has 2 hex digits
sl@0
   249
					sprintf( MAC_value, "%s%x", temp2, mac[i]);
sl@0
   250
				}
sl@0
   251
				else
sl@0
   252
				{
sl@0
   253
					sprintf( MAC_value, "%s0%x", temp2, mac[i]);
sl@0
   254
				}
sl@0
   255
			}
sl@0
   256
		}
sl@0
   257
		else
sl@0
   258
		{
sl@0
   259
			printf("Problem with opening adapter (packet.lib issue)\n");
sl@0
   260
			return (1);
sl@0
   261
		}
sl@0
   262
	}
sl@0
   263
	else
sl@0
   264
	{
sl@0
   265
		printf("\nNo supported adapters found\n");
sl@0
   266
	}
sl@0
   267
sl@0
   268
	//
sl@0
   269
	// Write the settings to the INI file...
sl@0
   270
	//
sl@0
   271
	printf("Writing settings to %s.\n\n", EPOC_INI_FILE);
sl@0
   272
	
sl@0
   273
	inifile = fopen(EPOC_INI_FILE, "a"); // to create if does exist
sl@0
   274
	if ( NULL != inifile )
sl@0
   275
	{
sl@0
   276
		fclose(inifile);
sl@0
   277
	}
sl@0
   278
	else
sl@0
   279
	{
sl@0
   280
		printf("Can't create or access %s.\n\n", EPOC_INI_FILE);
sl@0
   281
		return (1);
sl@0
   282
	}
sl@0
   283
		
sl@0
   284
	if ( 0 != replace_in_inifile( ETHER_NIF_ENTRY, AdapterList[adapterToUse-1], FALSE ) )
sl@0
   285
	{
sl@0
   286
		printf("Couldn't write adapter name to %s file\n", EPOC_INI_FILE);
sl@0
   287
		return (1);
sl@0
   288
	}
sl@0
   289
		
sl@0
   290
sl@0
   291
	if ( 0 != replace_in_inifile( ETHER_MAC_ENTRY, MAC_value, FALSE ) )
sl@0
   292
	{
sl@0
   293
		printf("Couldn't write MAC address to %s file\n", EPOC_INI_FILE);
sl@0
   294
		return (1);
sl@0
   295
	}
sl@0
   296
sl@0
   297
sl@0
   298
	if( 0 != speed_Mbps )
sl@0
   299
	{
sl@0
   300
		sprintf( speed_value, "%dMbps", speed_Mbps);
sl@0
   301
	}	
sl@0
   302
sl@0
   303
	if ( 0 != replace_in_inifile( ETHER_SPEED_ENTRY, speed_value, FALSE ) )
sl@0
   304
	{
sl@0
   305
		printf("Couldn't write speed value to %s file\n", EPOC_INI_FILE);
sl@0
   306
		return (1);
sl@0
   307
	}
sl@0
   308
	
sl@0
   309
	//printf("Netcards has written settings to %s.\n\n", EPOC_INI_FILE);
sl@0
   310
	free(MAC_value);
sl@0
   311
	free(temp2);
sl@0
   312
	pcap_freealldevs(adapterlist);
sl@0
   313
sl@0
   314
	return (0);
sl@0
   315
} // main
sl@0
   316
sl@0
   317
sl@0
   318
int get_adapter_speed_and_mac(char* adapterName, UINT* speed, unsigned char* mac)
sl@0
   319
{
sl@0
   320
	LPADAPTER	lpAdapter;
sl@0
   321
	int			retVal = 0;
sl@0
   322
sl@0
   323
	//
sl@0
   324
	// Open the adapter and get the speed and MAC address...
sl@0
   325
	//
sl@0
   326
	lpAdapter = PacketOpenAdapter(adapterName);
sl@0
   327
		
sl@0
   328
	if (lpAdapter)
sl@0
   329
	{
sl@0
   330
		PPACKET_OID_DATA	pOidData = malloc(sizeof(PACKET_OID_DATA) + MAX_OID_DATA);
sl@0
   331
sl@0
   332
		//
sl@0
   333
		// Get the link speed first. We use this method rather than call
sl@0
   334
		// PacketGetNetType() as it works better with PCAP3.1...
sl@0
   335
		//
sl@0
   336
		pOidData->Oid    = OID_GEN_LINK_SPEED;
sl@0
   337
		pOidData->Length = MAX_OID_DATA;
sl@0
   338
sl@0
   339
		if (PacketRequest(lpAdapter, FALSE , pOidData))
sl@0
   340
		{
sl@0
   341
			*speed = *((UINT*)pOidData->Data) / 10000; // OID is in 100 bps units.
sl@0
   342
		}
sl@0
   343
		else
sl@0
   344
		{
sl@0
   345
			*speed = 0;
sl@0
   346
		}
sl@0
   347
sl@0
   348
		//
sl@0
   349
		// Check the adapter is 802.3 based, cable connected and has a MAC address.
sl@0
   350
		//
sl@0
   351
		pOidData->Oid    = OID_GEN_MEDIA_IN_USE;
sl@0
   352
		pOidData->Length = MAX_OID_DATA;
sl@0
   353
sl@0
   354
		if (PacketRequest(lpAdapter, FALSE , pOidData)  &&
sl@0
   355
			*((UINT*)pOidData->Data) == NdisMedium802_3)
sl@0
   356
		{
sl@0
   357
			pOidData->Oid    = OID_GEN_MEDIA_CONNECT_STATUS;
sl@0
   358
			pOidData->Length = MAX_OID_DATA;
sl@0
   359
sl@0
   360
			if (PacketRequest(lpAdapter, FALSE , pOidData)  &&
sl@0
   361
				*((UINT*)pOidData->Data) == NdisMediaStateConnected)
sl@0
   362
			{
sl@0
   363
				pOidData->Oid    = OID_802_3_CURRENT_ADDRESS;
sl@0
   364
				pOidData->Length = MAX_OID_DATA;
sl@0
   365
			
sl@0
   366
				if (PacketRequest(lpAdapter, FALSE , pOidData))
sl@0
   367
				{
sl@0
   368
	  				mac[0] = pOidData->Data[0];
sl@0
   369
	  				mac[1] = pOidData->Data[1];
sl@0
   370
	  				mac[2] = pOidData->Data[2];
sl@0
   371
	  				mac[3] = pOidData->Data[3];
sl@0
   372
	  				mac[4] = pOidData->Data[4];
sl@0
   373
	  				mac[5] = pOidData->Data[5];
sl@0
   374
sl@0
   375
					retVal = 1;
sl@0
   376
				}
sl@0
   377
			}
sl@0
   378
		}
sl@0
   379
sl@0
   380
		free(pOidData);
sl@0
   381
	
sl@0
   382
		PacketCloseAdapter(lpAdapter);
sl@0
   383
	}
sl@0
   384
sl@0
   385
	return retVal;
sl@0
   386
} // get_adapter_speed_and_mac
sl@0
   387
sl@0
   388
sl@0
   389
int replace_in_inifile(char * entry_str, char* value, BOOL valUnicode)
sl@0
   390
{
sl@0
   391
	int err = 0; // 0 - ok, negative sth wrong
sl@0
   392
sl@0
   393
	int replaced = 0;
sl@0
   394
	int len = strlen(entry_str);
sl@0
   395
sl@0
   396
	FILE *	file;
sl@0
   397
	FILE *	tmp_file;
sl@0
   398
sl@0
   399
	char*  s = malloc(MAX_LINE);
sl@0
   400
	char *line = malloc(MAX_LINE);
sl@0
   401
sl@0
   402
	if ( NULL == (tmp_file = fopen(EPOC_INI_FILE_TEMP, "w")) ) 
sl@0
   403
	{
sl@0
   404
		printf( "Could not create '%s'\n", EPOC_INI_FILE_TEMP );
sl@0
   405
		return -1;
sl@0
   406
	}
sl@0
   407
sl@0
   408
	if ( NULL == (file  = fopen(EPOC_INI_FILE, "r+")) )
sl@0
   409
	{
sl@0
   410
		fclose( tmp_file );
sl@0
   411
		remove( EPOC_INI_FILE_TEMP  );
sl@0
   412
		printf( "Could not open '%s'\n", EPOC_INI_FILE );
sl@0
   413
		return -1;
sl@0
   414
	}
sl@0
   415
sl@0
   416
	rewind(file);
sl@0
   417
	
sl@0
   418
	
sl@0
   419
	while( fgets(line, MAX_LINE, file) != NULL)
sl@0
   420
    {
sl@0
   421
		if (sscanf( line, "%s", s ) > 0) // to trim blank chars
sl@0
   422
		{
sl@0
   423
			s[len] = '\0';
sl@0
   424
			if( 0 == strcmp(entry_str, s))
sl@0
   425
			{
sl@0
   426
				fprintf(tmp_file, "%s=", entry_str);
sl@0
   427
				
sl@0
   428
				if( valUnicode )
sl@0
   429
				{
sl@0
   430
					fwprintf(tmp_file, L"%s\n", value);
sl@0
   431
				}
sl@0
   432
				else
sl@0
   433
				{
sl@0
   434
					fprintf(tmp_file, "%s\n", value);
sl@0
   435
				}
sl@0
   436
				
sl@0
   437
				replaced = 1;
sl@0
   438
			}
sl@0
   439
			else
sl@0
   440
			{
sl@0
   441
				if( EOF == fputs(line, tmp_file) )
sl@0
   442
				{
sl@0
   443
					err = -1;
sl@0
   444
					break;
sl@0
   445
				}
sl@0
   446
			}
sl@0
   447
		}
sl@0
   448
	}
sl@0
   449
        
sl@0
   450
	free(line);
sl@0
   451
	free(s); 
sl@0
   452
sl@0
   453
	if( (0 == replaced) && (0 == err) )
sl@0
   454
	{
sl@0
   455
		// no entry encountered - add new
sl@0
   456
		if( 0 != fseek( tmp_file, 0, SEEK_END ) )
sl@0
   457
		{
sl@0
   458
			err = -1;
sl@0
   459
		}
sl@0
   460
	
sl@0
   461
		fprintf( tmp_file, "\n%s=", entry_str);
sl@0
   462
		if ( valUnicode )
sl@0
   463
		{
sl@0
   464
			fwprintf( tmp_file, L"%s\n", value);
sl@0
   465
		}
sl@0
   466
		else
sl@0
   467
		{
sl@0
   468
			fprintf( tmp_file, "%s\n", value);
sl@0
   469
		}
sl@0
   470
	}
sl@0
   471
sl@0
   472
sl@0
   473
	if ( 0 != fclose(file ) )
sl@0
   474
	{
sl@0
   475
		printf( "Could not close %s file\n", EPOC_INI_FILE );
sl@0
   476
		return -1;
sl@0
   477
	}
sl@0
   478
sl@0
   479
	if ( 0 != fclose( tmp_file ) )
sl@0
   480
	{
sl@0
   481
		printf( "Could not close %s file\n", EPOC_INI_FILE_TEMP );
sl@0
   482
		return -1;
sl@0
   483
	}
sl@0
   484
sl@0
   485
sl@0
   486
	if( remove( EPOC_INI_FILE  ) == -1 )
sl@0
   487
	{
sl@0
   488
		printf( "Could not overwrite %s file\n", EPOC_INI_FILE );
sl@0
   489
		return -1;
sl@0
   490
	}
sl@0
   491
	
sl@0
   492
	if( rename( EPOC_INI_FILE_TEMP, EPOC_INI_FILE ) != 0 )
sl@0
   493
	{
sl@0
   494
		printf( "\nCould not rename '%s' to '%s'\n", EPOC_INI_FILE_TEMP, EPOC_INI_FILE );
sl@0
   495
		return -1;
sl@0
   496
	}	
sl@0
   497
		
sl@0
   498
	return 0;
sl@0
   499
} // replace_in_inifile