Last active
October 11, 2016 15:52
-
-
Save murilopontes/9678872 to your computer and use it in GitHub Desktop.
Windows TAP Interface
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Win32; | |
using System; | |
using System.Diagnostics; | |
using System.IO; | |
using System.IO.Ports; | |
using System.Runtime.InteropServices; | |
namespace WindowsTapSpace | |
{ | |
//change this in app.manifest | |
/* <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> */ | |
class WindowsTapTest | |
{ | |
// | |
private const uint METHOD_BUFFERED = 0; | |
private const uint FILE_ANY_ACCESS = 0; | |
private const uint FILE_DEVICE_UNKNOWN = 0x00000022; | |
private const int FILE_ATTRIBUTE_SYSTEM = 0x4; | |
private const int FILE_FLAG_OVERLAPPED = 0x40000000; | |
// | |
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] | |
static extern IntPtr CreateFile( | |
string filename, | |
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess, | |
[MarshalAs(UnmanagedType.U4)]FileShare fileshare, | |
int securityattributes, | |
[MarshalAs(UnmanagedType.U4)]FileMode creationdisposition, | |
int flags, | |
IntPtr template); | |
// | |
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] | |
static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, | |
IntPtr lpInBuffer, uint nInBufferSize, | |
IntPtr lpOutBuffer, uint nOutBufferSize, | |
out int lpBytesReturned, IntPtr lpOverlapped); | |
// | |
private static uint CTL_CODE(uint DeviceType, uint Function, uint Method, uint Access) | |
{ | |
return ((DeviceType << 16) | (Access << 14) | (Function << 2) | Method); | |
} | |
// | |
static uint TAP_WIN_CONTROL_CODE(uint request, uint method) | |
{ | |
return CTL_CODE(FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS); | |
} | |
static string GetDeviceGuid() | |
{ | |
const string AdapterKey = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"; | |
RegistryKey regAdapters = Registry.LocalMachine.OpenSubKey(AdapterKey); | |
string[] keyNames = regAdapters.GetSubKeyNames(); | |
string devGuid = ""; | |
foreach (string x in keyNames) | |
{ | |
try | |
{ | |
RegistryKey regAdapter = regAdapters.OpenSubKey(x); | |
object id = regAdapter.GetValue("ComponentId"); | |
if (id != null && id.ToString() == "tap0801") devGuid = regAdapter.GetValue("NetCfgInstanceId").ToString(); | |
if (id != null && id.ToString() == "tap0901") devGuid = regAdapter.GetValue("NetCfgInstanceId").ToString(); | |
} | |
catch (Exception ex) | |
{ | |
} | |
} | |
Console.WriteLine("devGuid=" + devGuid); | |
return devGuid; | |
} | |
static string HumanName(string guid) | |
{ | |
const string ConnectionKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"; | |
if (guid != "") | |
{ | |
RegistryKey regConnection = Registry.LocalMachine.OpenSubKey(ConnectionKey + "\\" + guid + "\\Connection"); | |
object id = regConnection.GetValue("Name"); | |
if (id != null) return id.ToString(); | |
} | |
return ""; | |
} | |
static FileStream Tap; | |
[STAThread] | |
static void Main(string[] args) | |
{ | |
//tap ioctls | |
uint TAP_WIN_IOCTL_GET_MAC = TAP_WIN_CONTROL_CODE(1, METHOD_BUFFERED); | |
uint TAP_WIN_IOCTL_GET_VERSION = TAP_WIN_CONTROL_CODE(2, METHOD_BUFFERED); | |
uint TAP_WIN_IOCTL_GET_MTU = TAP_WIN_CONTROL_CODE(3, METHOD_BUFFERED); | |
uint TAP_WIN_IOCTL_GET_INFO = TAP_WIN_CONTROL_CODE(4, METHOD_BUFFERED); | |
uint TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT = TAP_WIN_CONTROL_CODE(5, METHOD_BUFFERED); | |
uint TAP_WIN_IOCTL_SET_MEDIA_STATUS = TAP_WIN_CONTROL_CODE(6, METHOD_BUFFERED); | |
uint TAP_WIN_IOCTL_CONFIG_DHCP_MASQ = TAP_WIN_CONTROL_CODE(7, METHOD_BUFFERED); | |
uint TAP_WIN_IOCTL_GET_LOG_LINE = TAP_WIN_CONTROL_CODE(8, METHOD_BUFFERED); | |
uint TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT = TAP_WIN_CONTROL_CODE(9, METHOD_BUFFERED); | |
uint TAP_WIN_IOCTL_CONFIG_TUN = TAP_WIN_CONTROL_CODE(10, METHOD_BUFFERED); | |
//get first tap interface | |
const string UsermodeDeviceSpace = "\\\\.\\Global\\"; | |
string devGuid = GetDeviceGuid(); | |
Console.WriteLine("interface-human-name=" + HumanName(devGuid)); | |
//create handle to tap interface | |
IntPtr ptr = CreateFile(UsermodeDeviceSpace + devGuid + ".tap", FileAccess.ReadWrite, FileShare.ReadWrite, 0, FileMode.Open, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, IntPtr.Zero); | |
//create stream to tap interface | |
Tap = new FileStream(ptr, FileAccess.ReadWrite, true, 4096, true); | |
//create buffer to read packets from tap interface | |
byte[] buf = new byte[4096]; | |
//set tap interface up | |
int len; | |
IntPtr pstatus = Marshal.AllocHGlobal(4); | |
Marshal.WriteInt32(pstatus, 1); | |
DeviceIoControl(ptr, TAP_WIN_IOCTL_SET_MEDIA_STATUS, pstatus, 4, pstatus, 4, out len, IntPtr.Zero); | |
//configure ipv4 of tap interface | |
string arg = "interface ip set address \"" + HumanName(devGuid) + "\" dhcp"; | |
Console.WriteLine(arg); | |
Process p = new Process(); | |
ProcessStartInfo psi = new ProcessStartInfo("netsh", arg); | |
p.StartInfo = psi; | |
p.Start(); | |
//configure ipv6 of tap interface | |
string arg2 = "interface ipv6 set address \"" + HumanName(devGuid) + "\" 2001::6969 advertise=enabled"; | |
Console.WriteLine(arg2); | |
Process p2 = new Process(); | |
ProcessStartInfo psi2 = new ProcessStartInfo("netsh", arg2); | |
p2.StartInfo = psi2; | |
p2.Start(); | |
//serial connection to embedded system | |
System.IO.Ports.SerialPort serial_port = new System.IO.Ports.SerialPort(); | |
serial_port.PortName = "COM1"; | |
serial_port.BaudRate = 115200; | |
serial_port.DataReceived += port_DataReceived; | |
serial_port.Open(); | |
while (true) | |
{ | |
//async read from windows network kernel | |
int BytesRead = Tap.Read(buf, 0, buf.Length); | |
Console.WriteLine("from-windows=" + BytesRead + "=>" + BitConverter.ToString(buf, 0, BytesRead)); | |
//write to serial connected in embedded system | |
serial_port.Write(buf, 0, BytesRead); | |
} | |
} | |
//read from serial connected in embedded system | |
static void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) | |
{ | |
SerialPort sp = (SerialPort)sender; | |
string indata = sp.ReadExisting(); | |
byte[] bin_from_stm32 = System.Text.Encoding.ASCII.GetBytes(indata); | |
Console.WriteLine("from-embedded=" + bin_from_stm32.Length + "=>" + BitConverter.ToString(bin_from_stm32, 0, bin_from_stm32.Length)); | |
//mininum valid packet size for windows kernel | |
if (bin_from_stm32.Length >= 20) | |
{ | |
//async write to windows network kernel | |
Tap.Write(bin_from_stm32, 0, bin_from_stm32.Length); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment