diff --git a/SMBLibrary/Server/NameServer.cs b/SMBLibrary/Server/NameServer.cs index f5f5d1c..16df7f6 100644 --- a/SMBLibrary/Server/NameServer.cs +++ b/SMBLibrary/Server/NameServer.cs @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 Tal Aloni . All rights reserved. +/* Copyright (C) 2014-2017 Tal Aloni . All rights reserved. * * You can redistribute this program and/or modify it under the terms of * the GNU Lesser Public License as published by the Free Software Foundation, @@ -24,12 +24,25 @@ namespace SMBLibrary.Server public const string WorkgroupName = "WORKGROUP"; private IPAddress m_serverAddress; + private IPAddress m_broadcastAddress; private UdpClient m_client; private bool m_listening; - public NameServer(IPAddress serverAddress) + public NameServer(IPAddress serverAddress, IPAddress subnetMask) { + if (serverAddress.AddressFamily != AddressFamily.InterNetwork) + { + throw new ArgumentException("NetBIOS name service can only supply IPv4 addresses"); + } + + if (IPAddress.Equals(serverAddress, IPAddress.Any)) + { + // When registering a NetBIOS name, we must supply the client with a usable IPAddress. + throw new ArgumentException("NetBIOS name service requires an IPAddress that is associated with a specific network interface"); + } + m_serverAddress = serverAddress; + m_broadcastAddress = GetBroadcastAddress(serverAddress, subnetMask); } public void Start() @@ -53,7 +66,6 @@ namespace SMBLibrary.Server m_client.Close(); } - private void ReceiveCallback(IAsyncResult result) { if (!m_listening) @@ -66,7 +78,6 @@ namespace SMBLibrary.Server try { buffer = m_client.EndReceive(result, ref remoteEP); - m_client.BeginReceive(ReceiveCallback, null); } catch (ObjectDisposedException) { @@ -109,7 +120,6 @@ namespace SMBLibrary.Server response.Addresses.Add(m_serverAddress.GetAddressBytes(), nameFlags); byte[] responseBytes = response.GetBytes(); m_client.Send(responseBytes, responseBytes.Length, remoteEP); - } } else // NBStat @@ -162,20 +172,11 @@ namespace SMBLibrary.Server RegisterName(request3); } - private IPAddress GetLocalSubnetBroadcastAddress(IPAddress address) - { - byte[] broadcastAddress = m_serverAddress.GetAddressBytes(); - broadcastAddress[3] = 0xFF; - return new IPAddress(broadcastAddress); - } - private void RegisterName(NameRegistrationRequest request) { byte[] packet = request.GetBytes(); - IPAddress broadcastAddress = GetLocalSubnetBroadcastAddress(m_serverAddress); - - IPEndPoint broadcastEP = new IPEndPoint(broadcastAddress, NetBiosNameServicePort); + IPEndPoint broadcastEP = new IPEndPoint(m_broadcastAddress, NetBiosNameServicePort); for (int index = 0; index < 4; index++) { try @@ -192,5 +193,18 @@ namespace SMBLibrary.Server } } } + + public static IPAddress GetBroadcastAddress(IPAddress address, IPAddress subnetMask) + { + byte[] ipAdressBytes = address.GetAddressBytes(); + byte[] subnetMaskBytes = subnetMask.GetAddressBytes(); + + byte[] broadcastAddress = new byte[ipAdressBytes.Length]; + for (int i = 0; i < broadcastAddress.Length; i++) + { + broadcastAddress[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i] ^ 255)); + } + return new IPAddress(broadcastAddress); + } } } diff --git a/SMBServer/NetworkInterfaceHelper.cs b/SMBServer/NetworkInterfaceHelper.cs new file mode 100644 index 0000000..ddf602f --- /dev/null +++ b/SMBServer/NetworkInterfaceHelper.cs @@ -0,0 +1,54 @@ +/* Copyright (C) 2014-2017 Tal Aloni . All rights reserved. + * + * You can redistribute this program and/or modify it under the terms of + * the GNU Lesser Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + */ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using System.Net.NetworkInformation; +using Utilities; + +namespace SMBServer +{ + public class NetworkInterfaceHelper + { + public static List GetHostIPAddresses() + { + List result = new List(); + foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces()) + { + IPInterfaceProperties ipProperties = netInterface.GetIPProperties(); + foreach (UnicastIPAddressInformation addressInfo in ipProperties.UnicastAddresses) + { + if (addressInfo.Address.AddressFamily == AddressFamily.InterNetwork) + { + result.Add(addressInfo.Address); + } + } + } + return result; + } + + public static IPAddress GetSubnetMask(IPAddress ipAddress) + { + foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces()) + { + IPInterfaceProperties ipProperties = netInterface.GetIPProperties(); + foreach (UnicastIPAddressInformation addressInfo in ipProperties.UnicastAddresses) + { + if (addressInfo.Address.AddressFamily == AddressFamily.InterNetwork) + { + if (IPAddress.Equals(addressInfo.Address, ipAddress)) + { + return addressInfo.IPv4Mask; + } + } + } + } + return null; + } + } +} diff --git a/SMBServer/SMBServer.csproj b/SMBServer/SMBServer.csproj index 274d8af..d39f1d9 100644 --- a/SMBServer/SMBServer.csproj +++ b/SMBServer/SMBServer.csproj @@ -39,6 +39,7 @@ + Form diff --git a/SMBServer/ServerUI.cs b/SMBServer/ServerUI.cs index 462fe57..22595a8 100644 --- a/SMBServer/ServerUI.cs +++ b/SMBServer/ServerUI.cs @@ -6,6 +6,7 @@ using System.Drawing; using System.IO; using System.Net; using System.Net.NetworkInformation; +using System.Net.Sockets; using System.Text; using System.Windows.Forms; using System.Xml; @@ -29,7 +30,7 @@ namespace SMBServer private void ServerUI_Load(object sender, EventArgs e) { - List localIPs = GetHostIPAddresses(); + List localIPs = NetworkInterfaceHelper.GetHostIPAddresses(); KeyValuePairList list = new KeyValuePairList(); list.Add("Any", IPAddress.Any); foreach (IPAddress address in localIPs) @@ -97,8 +98,12 @@ namespace SMBServer m_server.Start(); if (transportType == SMBTransportType.NetBiosOverTCP) { - m_nameServer = new NameServer(serverAddress); - m_nameServer.Start(); + if (serverAddress.AddressFamily == AddressFamily.InterNetwork && !IPAddress.Equals(serverAddress, IPAddress.Any)) + { + IPAddress subnetMask = NetworkInterfaceHelper.GetSubnetMask(serverAddress); + m_nameServer = new NameServer(serverAddress, subnetMask); + m_nameServer.Start(); + } } } catch (Exception ex) @@ -203,23 +208,6 @@ namespace SMBServer return doc; } - private static List GetHostIPAddresses() - { - List result = new List(); - foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces()) - { - IPInterfaceProperties ipProperties = netInterface.GetIPProperties(); - foreach (UnicastIPAddressInformation addressInfo in ipProperties.UnicastAddresses) - { - if (addressInfo.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) - { - result.Add(addressInfo.Address); - } - } - } - return result; - } - private void Server_OnLogEntry(object sender, LogEntry entry) { string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ");