VOID tapReadPermanentAddress(__in PTAP_ADAPTER_CONTEXT Adapter, __in NDIS_HANDLE ConfigurationHandle, __out MACADDR PermanentAddress) { NDIS_STATUS status; NDIS_CONFIGURATION_PARAMETER *configParameter; NDIS_STRING macKey = NDIS_STRING_CONST("MAC"); ANSI_STRING macString; BOOLEAN macFromRegistry = FALSE; // Read MAC parameter from registry. NdisReadConfiguration(&status, &configParameter, ConfigurationHandle, &macKey, NdisParameterString); if (status == NDIS_STATUS_SUCCESS) { if ((configParameter->ParameterType == NdisParameterString) && (configParameter->ParameterData.StringData.Length >= 12)) { if (RtlUnicodeStringToAnsiString(&macString, &configParameter->ParameterData.StringData, TRUE) == STATUS_SUCCESS) { macFromRegistry = ParseMAC(PermanentAddress, macString.Buffer); RtlFreeAnsiString(&macString); } } } if (!macFromRegistry) { // // There is no (valid) address stashed in the registry parameter. // // Make up a dummy mac address based on the ANSI representation of the // NetCfgInstanceId GUID. // GenerateRandomMac(PermanentAddress, MINIPORT_INSTANCE_ID(Adapter)); } }
int TUNTAP_SetMACAddr( char* pszNetDevName, char* pszMACAddr ) { struct hifr hifr; struct sockaddr* addr; MAC mac; if( !pszNetDevName || !*pszNetDevName ) { // "Invalid net device name %s" WRMSG( HHC00140, "E", pszNetDevName ? pszNetDevName : "NULL" ); return -1; } if( !pszMACAddr || ParseMAC( pszMACAddr, mac ) != 0 ) { // "Net device %s: Invalid MAC address %s" WRMSG( HHC00145, "E", pszNetDevName, pszMACAddr ? pszMACAddr : "NULL" ); return -1; } memset( &hifr, 0, sizeof( struct hifr ) ); strlcpy( hifr.hifr_name, pszNetDevName, sizeof(hifr.hifr_name)); addr = (struct sockaddr*)&hifr.hifr_hwaddr; memcpy( addr->sa_data, mac, IFHWADDRLEN ); addr->sa_family = 1; // ARPHRD_ETHER return TUNTAP_IOCtl( 0, SIOCSIFHWADDR, (char*)&hifr ); } // End of function TUNTAP_SetMACAddr()
int TUNTAP_SetMACAddr( char* pszNetDevName, char* pszMACAddr ) { struct hifr hifr; struct sockaddr* addr; MAC mac; memset( &hifr, 0, sizeof( struct hifr ) ); addr = (struct sockaddr*)&hifr.hifr_hwaddr; addr->sa_family = AF_UNIX; if( !pszNetDevName || !*pszNetDevName ) { WRMSG( HHC00140, "E", pszNetDevName ? pszNetDevName : "NULL" ); return -1; } strcpy( hifr.hifr_name, pszNetDevName ); if( !pszMACAddr || ParseMAC( pszMACAddr, mac ) != 0 ) { WRMSG( HHC00145, "E", pszNetDevName, pszMACAddr ? pszMACAddr : "NULL" ); return -1; } memcpy( addr->sa_data, mac, IFHWADDRLEN ); return TUNTAP_IOCtl( 0, SIOCSIFHWADDR, (char*)&hifr ); } // End of function TUNTAP_SetMACAddr()
static int ParseArgs( DEVBLK* pDEVBLK, PCTCBLK pCTCBLK, int argc, char** argv ) { struct in_addr addr; // Work area for addresses int iMTU; int i; MAC mac; // Work area for MAC address #if defined(OPTION_W32_CTCI) int iKernBuff; int iIOBuff; #endif // Housekeeping memset( &addr, 0, sizeof( struct in_addr ) ); memset( &mac, 0, sizeof( MAC ) ); // Set some initial defaults strcpy( pCTCBLK->szMTU, "1500" ); strcpy( pCTCBLK->szNetMask, "255.255.255.255" ); #if defined( OPTION_W32_CTCI ) strcpy( pCTCBLK->szTUNCharName, tt32_get_default_iface() ); #else strcpy( pCTCBLK->szTUNCharName, HERCTUN_DEV ); #endif #if defined( OPTION_W32_CTCI ) pCTCBLK->iKernBuff = DEF_CAPTURE_BUFFSIZE; pCTCBLK->iIOBuff = DEF_PACKET_BUFFSIZE; #endif // Initialize getopt's counter. This is necessary in the case // that getopt was used previously for another device. OPTRESET(); optind = 0; // Check for correct number of arguments if( argc < 2 ) { logmsg( _("HHCCT056E %4.4X: Incorrect number of parameters\n"), pDEVBLK->devnum ); return -1; } // Compatability with old format configuration files needs to be // maintained. Old format statements have the tun character device // name as the second argument on Linux, or CTCI-W32 as the first // argument on Windows. if( ( strncasecmp( argv[0], "/", 1 ) == 0 ) || ( strncasecmp( pDEVBLK->typname, "CTCI-W32", 8 ) == 0 ) ) { pCTCBLK->fOldFormat = 1; } else { // Build new argv list. // getopt_long used to work on old format configuration statements // because LCS was the first argument passed to the device // initialization routine (and was interpreted by getopt* // as the program name and ignored). Now that argv[0] is a valid // argument, we need to shift the arguments and insert a dummy // argv[0]; // Don't allow us to exceed the allocated storage (sanity check) if( argc > (MAX_ARGS-1) ) argc = (MAX_ARGS-1); for( i = argc; i > 0; i-- ) argv[i] = argv[i - 1]; argc++; argv[0] = pDEVBLK->typname; } // Parse any optional arguments if not old format while( !pCTCBLK->fOldFormat ) { int c; #if defined(HAVE_GETOPT_LONG) int iOpt; static struct option options[] = { { "dev", 1, NULL, 'n' }, #if defined( OPTION_W32_CTCI ) { "kbuff", 1, NULL, 'k' }, { "ibuff", 1, NULL, 'i' }, #endif { "mtu", 1, NULL, 't' }, { "netmask", 1, NULL, 's' }, { "mac", 1, NULL, 'm' }, { "debug", 0, NULL, 'd' }, { NULL, 0, NULL, 0 } }; c = getopt_long( argc, argv, "n" #if defined( OPTION_W32_CTCI ) ":k:i" #endif ":t:s:m:d", options, &iOpt ); #else /* defined(HAVE_GETOPT_LONG) */ c = getopt( argc, argv, "n" #if defined( OPTION_W32_CTCI ) ":k:i" #endif ":t:s:m:d"); #endif /* defined(HAVE_GETOPT_LONG) */ if( c == -1 ) // No more options found break; switch( c ) { case 'n': // Network Device #if defined( OPTION_W32_CTCI ) // This could be the IP or MAC address of the // host ethernet adapter. if( inet_aton( optarg, &addr ) == 0 ) { // Not an IP address, check for valid MAC if( ParseMAC( optarg, mac ) != 0 ) { logmsg( _("HHCCT050E %4.4X: Invalid adapter address %s\n"), pDEVBLK->devnum, optarg ); return -1; } } #endif // defined( OPTION_W32_CTCI ) // This is the file name of the special TUN/TAP character device if( strlen( optarg ) > sizeof( pCTCBLK->szTUNCharName ) - 1 ) { logmsg( _("HHCCT051E %4.4X: Invalid device name %s\n"), pDEVBLK->devnum, optarg ); return -1; } strcpy( pCTCBLK->szTUNCharName, optarg ); break; #if defined( OPTION_W32_CTCI ) case 'k': // Kernel Buffer Size (Windows only) iKernBuff = atoi( optarg ); if( iKernBuff * 1024 < MIN_CAPTURE_BUFFSIZE || iKernBuff * 1024 > MAX_CAPTURE_BUFFSIZE ) { logmsg( _("HHCCT052E %4.4X: Invalid kernel buffer size %s\n"), pDEVBLK->devnum, optarg ); return -1; } pCTCBLK->iKernBuff = iKernBuff * 1024; break; case 'i': // I/O Buffer Size (Windows only) iIOBuff = atoi( optarg ); if( iIOBuff * 1024 < MIN_PACKET_BUFFSIZE || iIOBuff * 1024 > MAX_PACKET_BUFFSIZE ) { logmsg( _("HHCCT053E %4.4X: Invalid DLL I/O buffer size %s\n"), pDEVBLK->devnum, optarg ); return -1; } pCTCBLK->iIOBuff = iIOBuff * 1024; break; #endif // defined( OPTION_W32_CTCI ) case 't': // MTU of point-to-point link (ignored if Windows) iMTU = atoi( optarg ); if( iMTU < 46 || iMTU > 65536 ) { logmsg( _("HHCCT054E %4.4X: Invalid MTU size %s\n"), pDEVBLK->devnum, optarg ); return -1; } strcpy( pCTCBLK->szMTU, optarg ); break; case 's': // Netmask of point-to-point link if( inet_aton( optarg, &addr ) == 0 ) { logmsg( _("HHCCT055E %4.4X: Invalid netmask %s\n"), pDEVBLK->devnum, optarg ); return -1; } strcpy( pCTCBLK->szNetMask, optarg ); break; case 'm': if( ParseMAC( optarg, mac ) != 0 ) { logmsg( _("HHCCT056E %4.4X: Invalid MAC address %s\n"), pDEVBLK->devnum, optarg ); return -1; } strcpy( pCTCBLK->szMACAddress, optarg ); break; case 'd': // Diagnostics pCTCBLK->fDebug = TRUE; break; default: break; } } // Shift past any options argc -= optind; argv += optind; i = 0; // Check for correct number of arguments if( argc == 0 ) { logmsg( _("HHCCT056E %4.4X: Incorrect number of parameters\n"), pDEVBLK->devnum ); return -1; } if( !pCTCBLK->fOldFormat ) { // New format has 2 and only 2 parameters (Though several options). if( argc != 2 ) { logmsg( _("HHCCT057E %4.4X: Incorrect number of parameters\n"), pDEVBLK->devnum ); return -1; } // Guest IP Address if( inet_aton( *argv, &addr ) == 0 ) { logmsg( _("HHCCT058E %4.4X: Invalid IP address %s\n"), pDEVBLK->devnum, *argv ); return -1; } strcpy( pCTCBLK->szGuestIPAddr, *argv ); argc--; argv++; // Driver IP Address if( inet_aton( *argv, &addr ) == 0 ) { logmsg( _("HHCCT059E %4.4X: Invalid IP address %s\n"), pDEVBLK->devnum, *argv ); return -1; } strcpy( pCTCBLK->szDriveIPAddr, *argv ); argc--; argv++; } else // if( pCTCBLK->fOldFormat ) { #if !defined( OPTION_W32_CTCI ) // All arguments are non-optional in linux old-format // Old format has 5 and only 5 arguments if( argc != 5 ) { logmsg( _("HHCCT060E %4.4X: Incorrect number of parameters\n"), pDEVBLK->devnum ); return -1; } // TUN/TAP Device if( **argv != '/' || strlen( *argv ) > sizeof( pCTCBLK->szTUNCharName ) - 1 ) { logmsg( _("HHCCT061E %4.4X: invalid device name %s\n"), pDEVBLK->devnum, *argv ); return -1; } strcpy( pCTCBLK->szTUNCharName, *argv ); argc--; argv++; // MTU Size iMTU = atoi( *argv ); if( iMTU < 46 || iMTU > 65536 ) { logmsg( _("HHCCT062E %4.4X: Invalid MTU size %s\n"), pDEVBLK->devnum, *argv ); return -1; } strcpy( pCTCBLK->szMTU, *argv ); argc--; argv++; // Guest IP Address if( inet_aton( *argv, &addr ) == 0 ) { logmsg( _("HHCCT063E %4.4X: Invalid IP address %s\n"), pDEVBLK->devnum, *argv ); return -1; } strcpy( pCTCBLK->szGuestIPAddr, *argv ); argc--; argv++; // Driver IP Address if( inet_aton( *argv, &addr ) == 0 ) { logmsg( _("HHCCT064E %4.4X: Invalid IP address %s\n"), pDEVBLK->devnum, *argv ); return -1; } strcpy( pCTCBLK->szDriveIPAddr, *argv ); argc--; argv++; // Netmask if( inet_aton( *argv, &addr ) == 0 ) { logmsg( _("HHCCT065E %4.4X: Invalid netmask %s\n"), pDEVBLK->devnum, *argv ); return -1; } strcpy( pCTCBLK->szNetMask, *argv ); argc--; argv++; if( argc > 0 ) { logmsg( _("HHCCT066E %4.4X: Incorrect number of parameters\n"), pDEVBLK->devnum ); return -1; } #else // defined( OPTION_W32_CTCI ) // There are 2 non-optional arguments in the Windows old-format: // Guest IP address and Gateway address. // There are also 2 additional optional arguments: // Kernel buffer size and I/O buffer size. while( argc > 0 ) { switch( i ) { case 0: // Non-optional arguments // Guest IP Address if( inet_aton( *argv, &addr ) == 0 ) { logmsg( _("HHCCT067E %4.4X: Invalid IP address %s\n"), pDEVBLK->devnum, *argv ); return -1; } strcpy( pCTCBLK->szGuestIPAddr, *argv ); argc--; argv++; // Destination (Gateway) Address if( inet_aton( *argv, &addr ) == 0 ) { // Not an IP address, check for valid MAC if( ParseMAC( *argv, mac ) != 0 ) { logmsg( _("HHCCT068E %4.4X: Invalid MAC address %s\n"), pDEVBLK->devnum, *argv ); return -1; } } strcpy( pCTCBLK->szTUNCharName, *argv ); // Kludge: This may look strange at first, but with // TunTap32, only the last 3 bytes of the "driver IP // address" is actually used. It's purpose is to // generate a unique MAC for the virtual interface. // Thus, having the same address for the adapter and // destination is not an issue. This used to be // generated from the guest IP address, I screwed up // TunTap32 V2. (JAP) // This also fixes the confusing error messages from // TunTap.c when a MAC is given for this argument. strcpy( pCTCBLK->szDriveIPAddr, pCTCBLK->szGuestIPAddr ); argc--; argv++; i++; continue; case 1: // Optional arguments from here on: // Kernel Buffer Size iKernBuff = atoi( *argv ); if( iKernBuff * 1024 < MIN_CAPTURE_BUFFSIZE || iKernBuff * 1024 > MAX_CAPTURE_BUFFSIZE ) { logmsg( _("HHCCT069E %4.4X: Invalid kernel buffer size %s\n"), pDEVBLK->devnum, *argv ); return -1; } pCTCBLK->iKernBuff = iKernBuff * 1024; argc--; argv++; i++; continue; case 2: // I/O Buffer Size iIOBuff = atoi( *argv ); if( iIOBuff * 1024 < MIN_PACKET_BUFFSIZE || iIOBuff * 1024 > MAX_PACKET_BUFFSIZE ) { logmsg( _("HHCCT070E %4.4X: Invalid DLL I/O buffer size %s\n"), pDEVBLK->devnum, *argv ); return -1; } pCTCBLK->iIOBuff = iIOBuff * 1024; argc--; argv++; i++; continue; default: logmsg( _("HHCCT071E %4.4X: Incorrect number of parameters\n"), pDEVBLK->devnum ); return -1; } } #endif // !defined( OPTION_W32_CTCI ) } return 0; }