SqlCustomFunctions/IPFunctions.cs

143 lines
3.8 KiB
C#

using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;
using System.Net;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlTypes;
using System.Numerics;
namespace SqlCustomFunctions
{
public static class IPFunctions
{
[Microsoft.SqlServer.Server.SqlFunction()]
static public byte[] ipIPV6toBIN16(SqlString IP)
{
BigInteger rv = new BigInteger();
try
{
IPAddress ipAddress = null;//IPAddress.TryParse(IPV6Address, out _);
if (IPAddress.TryParse(IP.ToString(), out ipAddress) && ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
{
byte[] addressBytes = ipAddress.GetAddressBytes();
// flip big-endian(network order) to little-endian
if (BitConverter.IsLittleEndian)
Array.Reverse(addressBytes);
rv = new BigInteger(addressBytes);
}
}
catch //(Exception ex)
{
rv = 0;
}
return rv.ToByteArray();
}
[Microsoft.SqlServer.Server.SqlFunction()]
static public SqlString ipBIN16toIPV6(byte[] IP)
{
SqlString rv = string.Empty;
try
{
byte[] paddedBytes = new byte[16];
if (IP.Length > 16)
{
// Truncate to 16 bytes (take the most significant bytes for IPv6)
Array.Copy(IP, IP.Length - 16, paddedBytes, 0, 16);
}
else if (IP.Length < 16)
{
// Pad with leading zeros (for smaller numbers)
Array.Copy(IP, 0, paddedBytes, 16 - IP.Length, IP.Length);
}
else
{
Array.Copy(IP, paddedBytes, 16);
}
// flip big-endian(network order) to little-endian
if (BitConverter.IsLittleEndian)
Array.Reverse(paddedBytes);
IPAddress ipAddress = new IPAddress(paddedBytes);
rv = ipAddress.ToString();
}
catch //(Exception ex)
{
rv = string.Empty;
}
return rv;
}
[Microsoft.SqlServer.Server.SqlFunction()]
static public byte[] ipIPV4toBIN4(SqlString IP)
{
var rv = new byte[] { 0, 0, 0, 0 };
try
{
IPAddress ipAddress = null;
if (IPAddress.TryParse(IP.ToString(), out ipAddress) && ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
byte[] addressBytes = ipAddress.GetAddressBytes();
// flip big-endian(network order) to little-endian
// -- Can't do this, because it would break legacy code! --
//if (BitConverter.IsLittleEndian)
// Array.Reverse(addressBytes);
rv = addressBytes; //BitConverter.ToUInt32(addressBytes, 0);
}
}
catch //(Exception)
{
rv = new byte[] { 0, 0, 0, 0 };
}
return rv;
}
[Microsoft.SqlServer.Server.SqlFunction()]
static public SqlString ipBIN4toIPV4(byte[] IP)
{
SqlString rv = string.Empty;
try
{
byte[] paddedBytes = new byte[4];
if (IP.Length > 4)
{
// Truncate to 16 bytes (take the most significant bytes for IPv6)
Array.Copy(IP, IP.Length - 4, paddedBytes, 0, 4);
}
else if (IP.Length < 4)
{
// Pad with leading zeros (for smaller numbers)
Array.Copy(IP, 0, paddedBytes, 4 - IP.Length, IP.Length);
}
else
{
Array.Copy(IP, paddedBytes, 4);
}
// flip big-endian(network order) to little-endian
// -- Can't do this, because it would break legacy code! --
//if (BitConverter.IsLittleEndian)
// Array.Reverse(paddedBytes);
IPAddress ipAddress = new IPAddress(paddedBytes);
rv = ipAddress.ToString();
}
catch //(Exception ex)
{
rv = string.Empty;
}
return rv;
}
}
}