--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32utils/netcards/netcards.c Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,499 @@
+/*
+* Copyright (c) 1995-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+/**
+@internalTechnology
+@file
+
+Implementation of the Netcards.exe adapter selection application.
+This version writes settings to an ethernet.ini file only. Those settings
+should be either copied into epoc.ini (EKA2) or extracted into correct setup
+files: ethermac.dat and etherdriver.dat (EKA1) using an appropriate tool.
+*/
+
+/*
+ * Desired design of maximum size and alignment.
+ * These are implementation specific.
+ */
+#define _SS_MAXSIZE 128 // Maximum size.
+#define _SS_ALIGNSIZE (sizeof(__int64)) // Desired alignment.
+
+/*
+ * Definitions used for sockaddr_storage structure paddings design.
+ */
+/**
+ * This version of netcards.c has been written to work and run on Windows 2000
+ * and Windows XP. It has been compiled against both WinPCap 4.0.
+ *
+ * We identify the version of the compiler from the macros set by E32PLAT.pm
+ * and if .NET assume that winsock2 will be used (although this is not needed).
+ */
+
+#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (short))
+#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (short) + _SS_PAD1SIZE \
+ + _SS_ALIGNSIZE))
+
+struct sockaddr_storage {
+ short ss_family; // Address family.
+ char __ss_pad1[_SS_PAD1SIZE]; // 6 byte pad, this is to make
+ // implementation specific pad up to
+ // alignment field that follows explicit
+ // in the data structure.
+ __int64 __ss_align; // Field to force desired structure.
+ char __ss_pad2[_SS_PAD2SIZE]; // 112 byte pad to achieve desired size;
+ // _SS_MAXSIZE value minus size of
+ // ss_family, __ss_pad1, and
+ // __ss_align fields is 112.
+};
+
+// Forward declare struct _RPC_ASYNC_STATE, to avoid a warning in rpcasync.h
+struct _RPC_ASYNC_STATE;
+
+// include WinPcap
+// The dance with warnings is necessary to avoid warnings such as
+//
+// \MSVC6\VC98\include\qos.h(236) : warning C4201: nonstandard extension used :
+// nameless struct/union
+//
+// when we compile at warning level 4.
+//
+
+#pragma warning(disable:4514)
+#pragma warning(push,3)
+#include "pcap.h"
+#pragma warning(pop)
+
+//other includes
+#include "packet32.h"
+#include "ntddndis.h"
+#include <windows.h>
+
+#include <stdio.h>
+#include <malloc.h>
+#include <conio.h>
+
+
+#define EPOC_INI_FILE "ethernet.ini"
+
+#define EPOC_INI_FILE_TEMP "__temp__ethernet__.ini"
+
+#define ETHER_NIF_ENTRY "ETHER_NIF"
+#define ETHER_MAC_ENTRY "ETHER_MAC"
+#define ETHER_SPEED_ENTRY "ETHER_SPEED"
+
+#define MAX_VALUE 80
+#define MAX_LINE 100
+#define MAX_OID_DATA 256
+
+#define MAX_ADAPTER_LEN 1024
+#define MAX_ADAPTERS 10
+
+#define OID_802_3_CURRENT_ADDRESS 0x01010102
+
+
+//
+// Global list of supported adapter names.
+//
+char AdapterList[MAX_ADAPTERS][MAX_ADAPTER_LEN];
+
+
+//
+// Replace or write new 'value' for 'entry' in epoc.ini file
+// returns 0 if ok, negative value if sth wrong
+//
+int replace_in_inifile(char * entry, char* value, BOOL valUnicode );
+
+
+//
+// Gets the adapter speed and mac address. Returns 0 if no mac is available,
+// otherwise returns non-zero if successful.
+//
+int get_adapter_speed_and_mac(char* adapterName, UINT* speed, unsigned char* mac);
+
+//
+// Main entry point.
+//
+int main(int argc, char* argv[])
+{
+ char err[PCAP_ERRBUF_SIZE + 1];
+
+
+ // string that contains a list of the network adapters
+ pcap_if_t *adapterlist, *adapter;
+
+ int adapters=0, adapterToUse, i;
+ UINT speed_Mbps = 0;
+ unsigned char mac[6];
+
+ FILE *inifile;
+
+ char speed_value[10];
+ char *MAC_value = malloc( 13*sizeof(char) );
+ char *temp2 = malloc( 13*sizeof(char) );
+ int interfaceArg = 0;
+ int MACmode = 0;
+
+ if ( argc>1 && argv[1] )
+ {
+ interfaceArg = atoi(argv[1])%10;
+ MACmode = atoi(argv[1])/10; //used for set ethernet/WLAN MAC address
+ }
+ //printf("interfaceArg=%d, MACmode=%d\n", interfaceArg, MACmode);
+
+ //
+ // Obtain the name of the adapters installed on this machine.
+ //
+ // The result of this function is obtained querying the registry,
+ // and therefore the format of the result in Windows NTx is different
+ // from the one in Windows 9x. Windows 9x uses the ASCII encoding method
+ // to store a string, while Windows NTx uses UNICODE.
+ //
+ // In addition different versions of PCAP vary this behaviour meaning
+ // that the returned data cannot be assumed to be one format or the
+ // other - in other words we must check it ourselves.
+ //
+ printf("\nAdapters installed:\n");
+
+ if(pcap_findalldevs(&adapterlist, err) < 0)
+ {
+ printf("Error - pcap_findalldevs: %s\n", err);
+ return (1);
+ }
+ for(adapter = adapterlist; adapter; adapter = adapter->next)
+ {
+ memcpy(AdapterList[adapters], adapter->name, strlen(adapter->name));
+ if(get_adapter_speed_and_mac(AdapterList[adapters], &speed_Mbps, mac))
+ {
+ printf("\n%3d - %s\n", adapters+1, AdapterList[adapters]);
+ adapters++;
+ }
+ else
+ {
+ printf("\nN/A - %s\n",AdapterList[adapters]);
+ }
+ printf(" %s\n", adapter->description);
+ }
+ printf("\n");
+
+ if (adapters>1)
+ {
+ if((interfaceArg>adapters)||(interfaceArg<1) )
+ {
+ do
+ {
+ printf("Select the number of the adapter to use : ");
+ scanf("%d",&adapterToUse);
+ if (adapterToUse > adapters || adapterToUse < 1)
+ {
+ printf("\nThe number must be between 1 and %d\n",adapters);
+ }
+ } while (adapterToUse > adapters || adapterToUse < 1);
+ }
+ else
+ {
+ adapterToUse = interfaceArg;
+ }
+ }
+ else
+ {
+ adapterToUse = adapters;
+ }
+
+ MAC_value[0] = '\0';
+ temp2[0] = '\0';
+ speed_value[0] = '\0';
+
+ //
+ // Open the adapter if available...
+ //
+ if (adapterToUse > 0 && adapterToUse <= adapters)
+ {
+ printf("\nUsing adapter %d\n", adapterToUse);
+
+ if (get_adapter_speed_and_mac(AdapterList[adapterToUse-1], &speed_Mbps, mac))
+ {
+ if (speed_Mbps == 0)
+ {
+ printf("Could not read Ethernet card's speed\n");
+ }
+
+ printf("Physical address read: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ if(MACmode == 0) //ethernet MAC
+ {
+ mac[0] += 2; // changing address from global to local
+ }
+
+ for( i=0; i<6; i++ )
+ {
+ strcpy( temp2, MAC_value);
+ if( mac[i] > 15 )
+ {
+ // has 2 hex digits
+ sprintf( MAC_value, "%s%x", temp2, mac[i]);
+ }
+ else
+ {
+ sprintf( MAC_value, "%s0%x", temp2, mac[i]);
+ }
+ }
+ }
+ else
+ {
+ printf("Problem with opening adapter (packet.lib issue)\n");
+ return (1);
+ }
+ }
+ else
+ {
+ printf("\nNo supported adapters found\n");
+ }
+
+ //
+ // Write the settings to the INI file...
+ //
+ printf("Writing settings to %s.\n\n", EPOC_INI_FILE);
+
+ inifile = fopen(EPOC_INI_FILE, "a"); // to create if does exist
+ if ( NULL != inifile )
+ {
+ fclose(inifile);
+ }
+ else
+ {
+ printf("Can't create or access %s.\n\n", EPOC_INI_FILE);
+ return (1);
+ }
+
+ if ( 0 != replace_in_inifile( ETHER_NIF_ENTRY, AdapterList[adapterToUse-1], FALSE ) )
+ {
+ printf("Couldn't write adapter name to %s file\n", EPOC_INI_FILE);
+ return (1);
+ }
+
+
+ if ( 0 != replace_in_inifile( ETHER_MAC_ENTRY, MAC_value, FALSE ) )
+ {
+ printf("Couldn't write MAC address to %s file\n", EPOC_INI_FILE);
+ return (1);
+ }
+
+
+ if( 0 != speed_Mbps )
+ {
+ sprintf( speed_value, "%dMbps", speed_Mbps);
+ }
+
+ if ( 0 != replace_in_inifile( ETHER_SPEED_ENTRY, speed_value, FALSE ) )
+ {
+ printf("Couldn't write speed value to %s file\n", EPOC_INI_FILE);
+ return (1);
+ }
+
+ //printf("Netcards has written settings to %s.\n\n", EPOC_INI_FILE);
+ free(MAC_value);
+ free(temp2);
+ pcap_freealldevs(adapterlist);
+
+ return (0);
+} // main
+
+
+int get_adapter_speed_and_mac(char* adapterName, UINT* speed, unsigned char* mac)
+{
+ LPADAPTER lpAdapter;
+ int retVal = 0;
+
+ //
+ // Open the adapter and get the speed and MAC address...
+ //
+ lpAdapter = PacketOpenAdapter(adapterName);
+
+ if (lpAdapter)
+ {
+ PPACKET_OID_DATA pOidData = malloc(sizeof(PACKET_OID_DATA) + MAX_OID_DATA);
+
+ //
+ // Get the link speed first. We use this method rather than call
+ // PacketGetNetType() as it works better with PCAP3.1...
+ //
+ pOidData->Oid = OID_GEN_LINK_SPEED;
+ pOidData->Length = MAX_OID_DATA;
+
+ if (PacketRequest(lpAdapter, FALSE , pOidData))
+ {
+ *speed = *((UINT*)pOidData->Data) / 10000; // OID is in 100 bps units.
+ }
+ else
+ {
+ *speed = 0;
+ }
+
+ //
+ // Check the adapter is 802.3 based, cable connected and has a MAC address.
+ //
+ pOidData->Oid = OID_GEN_MEDIA_IN_USE;
+ pOidData->Length = MAX_OID_DATA;
+
+ if (PacketRequest(lpAdapter, FALSE , pOidData) &&
+ *((UINT*)pOidData->Data) == NdisMedium802_3)
+ {
+ pOidData->Oid = OID_GEN_MEDIA_CONNECT_STATUS;
+ pOidData->Length = MAX_OID_DATA;
+
+ if (PacketRequest(lpAdapter, FALSE , pOidData) &&
+ *((UINT*)pOidData->Data) == NdisMediaStateConnected)
+ {
+ pOidData->Oid = OID_802_3_CURRENT_ADDRESS;
+ pOidData->Length = MAX_OID_DATA;
+
+ if (PacketRequest(lpAdapter, FALSE , pOidData))
+ {
+ mac[0] = pOidData->Data[0];
+ mac[1] = pOidData->Data[1];
+ mac[2] = pOidData->Data[2];
+ mac[3] = pOidData->Data[3];
+ mac[4] = pOidData->Data[4];
+ mac[5] = pOidData->Data[5];
+
+ retVal = 1;
+ }
+ }
+ }
+
+ free(pOidData);
+
+ PacketCloseAdapter(lpAdapter);
+ }
+
+ return retVal;
+} // get_adapter_speed_and_mac
+
+
+int replace_in_inifile(char * entry_str, char* value, BOOL valUnicode)
+{
+ int err = 0; // 0 - ok, negative sth wrong
+
+ int replaced = 0;
+ int len = strlen(entry_str);
+
+ FILE * file;
+ FILE * tmp_file;
+
+ char* s = malloc(MAX_LINE);
+ char *line = malloc(MAX_LINE);
+
+ if ( NULL == (tmp_file = fopen(EPOC_INI_FILE_TEMP, "w")) )
+ {
+ printf( "Could not create '%s'\n", EPOC_INI_FILE_TEMP );
+ return -1;
+ }
+
+ if ( NULL == (file = fopen(EPOC_INI_FILE, "r+")) )
+ {
+ fclose( tmp_file );
+ remove( EPOC_INI_FILE_TEMP );
+ printf( "Could not open '%s'\n", EPOC_INI_FILE );
+ return -1;
+ }
+
+ rewind(file);
+
+
+ while( fgets(line, MAX_LINE, file) != NULL)
+ {
+ if (sscanf( line, "%s", s ) > 0) // to trim blank chars
+ {
+ s[len] = '\0';
+ if( 0 == strcmp(entry_str, s))
+ {
+ fprintf(tmp_file, "%s=", entry_str);
+
+ if( valUnicode )
+ {
+ fwprintf(tmp_file, L"%s\n", value);
+ }
+ else
+ {
+ fprintf(tmp_file, "%s\n", value);
+ }
+
+ replaced = 1;
+ }
+ else
+ {
+ if( EOF == fputs(line, tmp_file) )
+ {
+ err = -1;
+ break;
+ }
+ }
+ }
+ }
+
+ free(line);
+ free(s);
+
+ if( (0 == replaced) && (0 == err) )
+ {
+ // no entry encountered - add new
+ if( 0 != fseek( tmp_file, 0, SEEK_END ) )
+ {
+ err = -1;
+ }
+
+ fprintf( tmp_file, "\n%s=", entry_str);
+ if ( valUnicode )
+ {
+ fwprintf( tmp_file, L"%s\n", value);
+ }
+ else
+ {
+ fprintf( tmp_file, "%s\n", value);
+ }
+ }
+
+
+ if ( 0 != fclose(file ) )
+ {
+ printf( "Could not close %s file\n", EPOC_INI_FILE );
+ return -1;
+ }
+
+ if ( 0 != fclose( tmp_file ) )
+ {
+ printf( "Could not close %s file\n", EPOC_INI_FILE_TEMP );
+ return -1;
+ }
+
+
+ if( remove( EPOC_INI_FILE ) == -1 )
+ {
+ printf( "Could not overwrite %s file\n", EPOC_INI_FILE );
+ return -1;
+ }
+
+ if( rename( EPOC_INI_FILE_TEMP, EPOC_INI_FILE ) != 0 )
+ {
+ printf( "\nCould not rename '%s' to '%s'\n", EPOC_INI_FILE_TEMP, EPOC_INI_FILE );
+ return -1;
+ }
+
+ return 0;
+} // replace_in_inifile