First public contribution.
2 * Copyright (c) 1995-2007 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
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.
30 * Desired design of maximum size and alignment.
31 * These are implementation specific.
33 #define _SS_MAXSIZE 128 // Maximum size.
34 #define _SS_ALIGNSIZE (sizeof(__int64)) // Desired alignment.
37 * Definitions used for sockaddr_storage structure paddings design.
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.
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).
47 #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (short))
48 #define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (short) + _SS_PAD1SIZE \
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.
64 // Forward declare struct _RPC_ASYNC_STATE, to avoid a warning in rpcasync.h
65 struct _RPC_ASYNC_STATE;
68 // The dance with warnings is necessary to avoid warnings such as
70 // \MSVC6\VC98\include\qos.h(236) : warning C4201: nonstandard extension used :
71 // nameless struct/union
73 // when we compile at warning level 4.
76 #pragma warning(disable:4514)
77 #pragma warning(push,3)
91 #define EPOC_INI_FILE "ethernet.ini"
93 #define EPOC_INI_FILE_TEMP "__temp__ethernet__.ini"
95 #define ETHER_NIF_ENTRY "ETHER_NIF"
96 #define ETHER_MAC_ENTRY "ETHER_MAC"
97 #define ETHER_SPEED_ENTRY "ETHER_SPEED"
101 #define MAX_OID_DATA 256
103 #define MAX_ADAPTER_LEN 1024
104 #define MAX_ADAPTERS 10
106 #define OID_802_3_CURRENT_ADDRESS 0x01010102
110 // Global list of supported adapter names.
112 char AdapterList[MAX_ADAPTERS][MAX_ADAPTER_LEN];
116 // Replace or write new 'value' for 'entry' in epoc.ini file
117 // returns 0 if ok, negative value if sth wrong
119 int replace_in_inifile(char * entry, char* value, BOOL valUnicode );
123 // Gets the adapter speed and mac address. Returns 0 if no mac is available,
124 // otherwise returns non-zero if successful.
126 int get_adapter_speed_and_mac(char* adapterName, UINT* speed, unsigned char* mac);
131 int main(int argc, char* argv[])
133 char err[PCAP_ERRBUF_SIZE + 1];
136 // string that contains a list of the network adapters
137 pcap_if_t *adapterlist, *adapter;
139 int adapters=0, adapterToUse, i;
141 unsigned char mac[6];
145 char speed_value[10];
146 char *MAC_value = malloc( 13*sizeof(char) );
147 char *temp2 = malloc( 13*sizeof(char) );
148 int interfaceArg = 0;
151 if ( argc>1 && argv[1] )
153 interfaceArg = atoi(argv[1])%10;
154 MACmode = atoi(argv[1])/10; //used for set ethernet/WLAN MAC address
156 //printf("interfaceArg=%d, MACmode=%d\n", interfaceArg, MACmode);
159 // Obtain the name of the adapters installed on this machine.
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.
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.
170 printf("\nAdapters installed:\n");
172 if(pcap_findalldevs(&adapterlist, err) < 0)
174 printf("Error - pcap_findalldevs: %s\n", err);
177 for(adapter = adapterlist; adapter; adapter = adapter->next)
179 memcpy(AdapterList[adapters], adapter->name, strlen(adapter->name));
180 if(get_adapter_speed_and_mac(AdapterList[adapters], &speed_Mbps, mac))
182 printf("\n%3d - %s\n", adapters+1, AdapterList[adapters]);
187 printf("\nN/A - %s\n",AdapterList[adapters]);
189 printf(" %s\n", adapter->description);
195 if((interfaceArg>adapters)||(interfaceArg<1) )
199 printf("Select the number of the adapter to use : ");
200 scanf("%d",&adapterToUse);
201 if (adapterToUse > adapters || adapterToUse < 1)
203 printf("\nThe number must be between 1 and %d\n",adapters);
205 } while (adapterToUse > adapters || adapterToUse < 1);
209 adapterToUse = interfaceArg;
214 adapterToUse = adapters;
219 speed_value[0] = '\0';
222 // Open the adapter if available...
224 if (adapterToUse > 0 && adapterToUse <= adapters)
226 printf("\nUsing adapter %d\n", adapterToUse);
228 if (get_adapter_speed_and_mac(AdapterList[adapterToUse-1], &speed_Mbps, mac))
232 printf("Could not read Ethernet card's speed\n");
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]);
238 if(MACmode == 0) //ethernet MAC
240 mac[0] += 2; // changing address from global to local
245 strcpy( temp2, MAC_value);
249 sprintf( MAC_value, "%s%x", temp2, mac[i]);
253 sprintf( MAC_value, "%s0%x", temp2, mac[i]);
259 printf("Problem with opening adapter (packet.lib issue)\n");
265 printf("\nNo supported adapters found\n");
269 // Write the settings to the INI file...
271 printf("Writing settings to %s.\n\n", EPOC_INI_FILE);
273 inifile = fopen(EPOC_INI_FILE, "a"); // to create if does exist
274 if ( NULL != inifile )
280 printf("Can't create or access %s.\n\n", EPOC_INI_FILE);
284 if ( 0 != replace_in_inifile( ETHER_NIF_ENTRY, AdapterList[adapterToUse-1], FALSE ) )
286 printf("Couldn't write adapter name to %s file\n", EPOC_INI_FILE);
291 if ( 0 != replace_in_inifile( ETHER_MAC_ENTRY, MAC_value, FALSE ) )
293 printf("Couldn't write MAC address to %s file\n", EPOC_INI_FILE);
298 if( 0 != speed_Mbps )
300 sprintf( speed_value, "%dMbps", speed_Mbps);
303 if ( 0 != replace_in_inifile( ETHER_SPEED_ENTRY, speed_value, FALSE ) )
305 printf("Couldn't write speed value to %s file\n", EPOC_INI_FILE);
309 //printf("Netcards has written settings to %s.\n\n", EPOC_INI_FILE);
312 pcap_freealldevs(adapterlist);
318 int get_adapter_speed_and_mac(char* adapterName, UINT* speed, unsigned char* mac)
324 // Open the adapter and get the speed and MAC address...
326 lpAdapter = PacketOpenAdapter(adapterName);
330 PPACKET_OID_DATA pOidData = malloc(sizeof(PACKET_OID_DATA) + MAX_OID_DATA);
333 // Get the link speed first. We use this method rather than call
334 // PacketGetNetType() as it works better with PCAP3.1...
336 pOidData->Oid = OID_GEN_LINK_SPEED;
337 pOidData->Length = MAX_OID_DATA;
339 if (PacketRequest(lpAdapter, FALSE , pOidData))
341 *speed = *((UINT*)pOidData->Data) / 10000; // OID is in 100 bps units.
349 // Check the adapter is 802.3 based, cable connected and has a MAC address.
351 pOidData->Oid = OID_GEN_MEDIA_IN_USE;
352 pOidData->Length = MAX_OID_DATA;
354 if (PacketRequest(lpAdapter, FALSE , pOidData) &&
355 *((UINT*)pOidData->Data) == NdisMedium802_3)
357 pOidData->Oid = OID_GEN_MEDIA_CONNECT_STATUS;
358 pOidData->Length = MAX_OID_DATA;
360 if (PacketRequest(lpAdapter, FALSE , pOidData) &&
361 *((UINT*)pOidData->Data) == NdisMediaStateConnected)
363 pOidData->Oid = OID_802_3_CURRENT_ADDRESS;
364 pOidData->Length = MAX_OID_DATA;
366 if (PacketRequest(lpAdapter, FALSE , pOidData))
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];
382 PacketCloseAdapter(lpAdapter);
386 } // get_adapter_speed_and_mac
389 int replace_in_inifile(char * entry_str, char* value, BOOL valUnicode)
391 int err = 0; // 0 - ok, negative sth wrong
394 int len = strlen(entry_str);
399 char* s = malloc(MAX_LINE);
400 char *line = malloc(MAX_LINE);
402 if ( NULL == (tmp_file = fopen(EPOC_INI_FILE_TEMP, "w")) )
404 printf( "Could not create '%s'\n", EPOC_INI_FILE_TEMP );
408 if ( NULL == (file = fopen(EPOC_INI_FILE, "r+")) )
411 remove( EPOC_INI_FILE_TEMP );
412 printf( "Could not open '%s'\n", EPOC_INI_FILE );
419 while( fgets(line, MAX_LINE, file) != NULL)
421 if (sscanf( line, "%s", s ) > 0) // to trim blank chars
424 if( 0 == strcmp(entry_str, s))
426 fprintf(tmp_file, "%s=", entry_str);
430 fwprintf(tmp_file, L"%s\n", value);
434 fprintf(tmp_file, "%s\n", value);
441 if( EOF == fputs(line, tmp_file) )
453 if( (0 == replaced) && (0 == err) )
455 // no entry encountered - add new
456 if( 0 != fseek( tmp_file, 0, SEEK_END ) )
461 fprintf( tmp_file, "\n%s=", entry_str);
464 fwprintf( tmp_file, L"%s\n", value);
468 fprintf( tmp_file, "%s\n", value);
473 if ( 0 != fclose(file ) )
475 printf( "Could not close %s file\n", EPOC_INI_FILE );
479 if ( 0 != fclose( tmp_file ) )
481 printf( "Could not close %s file\n", EPOC_INI_FILE_TEMP );
486 if( remove( EPOC_INI_FILE ) == -1 )
488 printf( "Could not overwrite %s file\n", EPOC_INI_FILE );
492 if( rename( EPOC_INI_FILE_TEMP, EPOC_INI_FILE ) != 0 )
494 printf( "\nCould not rename '%s' to '%s'\n", EPOC_INI_FILE_TEMP, EPOC_INI_FILE );
499 } // replace_in_inifile