فهرست منبع

Improved NetBIOS name server implementation

Tal Aloni 8 سال پیش
والد
کامیت
0241d5c055
4فایلهای تغییر یافته به همراه92 افزوده شده و 35 حذف شده
  1. 29 15
      SMBLibrary/Server/NameServer.cs
  2. 54 0
      SMBServer/NetworkInterfaceHelper.cs
  3. 1 0
      SMBServer/SMBServer.csproj
  4. 8 20
      SMBServer/ServerUI.cs

+ 29 - 15
SMBLibrary/Server/NameServer.cs

@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
+/* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. 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);
+        }
     }
 }

+ 54 - 0
SMBServer/NetworkInterfaceHelper.cs

@@ -0,0 +1,54 @@
+/* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. 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<IPAddress> GetHostIPAddresses()
+        {
+            List<IPAddress> result = new List<IPAddress>();
+            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;
+        }
+    }
+}

+ 1 - 0
SMBServer/SMBServer.csproj

@@ -39,6 +39,7 @@
     <Compile Include="DirectoryFileSystem\DirectoryFileSystem.cs" />
     <Compile Include="DirectoryFileSystem\StreamWatcher.cs" />
     <Compile Include="DirectoryFileSystem\Win32Native.cs" />
+    <Compile Include="NetworkInterfaceHelper.cs" />
     <Compile Include="ServerUI.cs">
       <SubType>Form</SubType>
     </Compile>

+ 8 - 20
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<IPAddress> localIPs = GetHostIPAddresses();
+            List<IPAddress> localIPs = NetworkInterfaceHelper.GetHostIPAddresses();
             KeyValuePairList<string, IPAddress> list = new KeyValuePairList<string, IPAddress>();
             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<IPAddress> GetHostIPAddresses()
-        {
-            List<IPAddress> result = new List<IPAddress>();
-            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 ");