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