mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-04-29 18:27:48 +02:00
Improved NetBIOS name server implementation
This commit is contained in:
parent
dd8e867693
commit
0241d5c055
4 changed files with 92 additions and 35 deletions
|
@ -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
SMBServer/NetworkInterfaceHelper.cs
Normal file
54
SMBServer/NetworkInterfaceHelper.cs
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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 ");
|
||||
|
|
Loading…
Add table
Reference in a new issue