docusnap-dude
Goto Top

MS-SQL: Statement zum Berechnen von IP-Ranges

Hallo,

folgende Frage: hat jemand schon mal gebaut oder Gefunden:

Per Feldeditor (GUI) erstellte FIX-Values in einer Table:

IP-Bereich: 192.168.0.0
Subnetz: 255.255.255.0
Gateway: 192.168.0.254

Jetzt habe ich vor, per Trigger zu berechnen:
Erste IP: 192.168.0.1
Letzte IP: 192.168.0.253 (also eine runter vom Gateway)


Hat da jemand eine Idee wie man das baut?

Danke!

Content-ID: 1144098418

Url: https://administrator.de/contentid/1144098418

Ausgedruckt am: 19.11.2024 um 09:11 Uhr

ukulele-7
Lösung ukulele-7 11.08.2021 aktualisiert um 10:56:50 Uhr
Goto Top
Ja ich hab in meiner Sammlung noch ein Script mit dem schönen Namen IPv4_shit.sql:
--Funktion
CREATE FUNCTION dbo.test_convert_ipv4(@ipv4cidr_decimal VARCHAR(18))
RETURNS @t TABLE (
	ipv4_binary VARCHAR(32),
	ipv4_binary_net VARCHAR(32),
	ipv4_binary_host VARCHAR(32),
	ipv4cidr_decimal_net SMALLINT
)
AS
BEGIN
	DECLARE	@ipv4cidr_decimal_net SMALLINT,
			@ipv4_decimal VARCHAR(15)

	IF		@ipv4cidr_decimal LIKE '%/%'  
	BEGIN
		SET		@ipv4_decimal = left(@ipv4cidr_decimal,charindex('/',@ipv4cidr_decimal)-1) + '.'  
		SET		@ipv4cidr_decimal_net = convert(SMALLINT,right(@ipv4cidr_decimal,charindex('/',reverse(@ipv4cidr_decimal))-1))  
	END
	ELSE
	BEGIN
		SET		@ipv4_decimal = @ipv4cidr_decimal + '.'  
	END;

	WITH cte(ipv4,octet,number) AS (
		SELECT	right(@ipv4_decimal,datalength(@ipv4_decimal)-charindex('.',@ipv4_decimal)),  
				left(@ipv4_decimal,charindex('.',@ipv4_decimal)-1),  
				1
		UNION ALL
		SELECT	right(ipv4,datalength(ipv4)-charindex('.',ipv4)),  
				left(ipv4,charindex('.',ipv4)-1),  
				number + 1
		FROM	cte
		WHERE	number <= 3
		)
	INSERT INTO @t(ipv4_binary)
	SELECT	stuff((	SELECT	( CASE convert(INT,octet) & 128 WHEN 128 THEN '1' ELSE '0' END ) +  
							( CASE convert(INT,octet) & 64 WHEN 64 THEN '1' ELSE '0' END ) +  
							( CASE convert(INT,octet) & 32 WHEN 32 THEN '1' ELSE '0' END ) +  
							( CASE convert(INT,octet) & 16 WHEN 16 THEN '1' ELSE '0' END ) +  
							( CASE convert(INT,octet) & 8 WHEN 8 THEN '1' ELSE '0' END ) +  
							( CASE convert(INT,octet) & 4 WHEN 4 THEN '1' ELSE '0' END ) +  
							( CASE convert(INT,octet) & 2 WHEN 2 THEN '1' ELSE '0' END ) +  
							( CASE convert(INT,octet) & 1 WHEN 1 THEN '1' ELSE '0' END )  
					FROM	cte
					ORDER BY number
					FOR XML PATH (''))  
					,1,1,'')  

	IF		@ipv4cidr_decimal_net IS NOT NULL
	BEGIN
		UPDATE	@t
		SET		ipv4_binary_net = left(ipv4_binary,@ipv4cidr_decimal_net),
				ipv4_binary_host = right(ipv4_binary,32-@ipv4cidr_decimal_net),
				ipv4cidr_decimal_net = @ipv4cidr_decimal_net
	END

	RETURN;
END;

--Testdaten und Abfrage
WITH Netzwerkbereichsdefintionen(IP_Bereich,Name) AS (
	SELECT	'192.168.0.0/24','Standardnetz' UNION ALL  
	SELECT	'10.27.0.0/16','Servernetz' UNION ALL  
	SELECT	'172.16.4.0/24','DMZ'  
	), Geräteliste(Gerätename,IP_Adresse) AS (
	SELECT	'Server1','192.168.0.16' UNION ALL  
	SELECT	'Server2','10.27.0.12' UNION ALL  
	SELECT	'Server3','172.16.4.4' UNION ALL  
	SELECT	'Server4','10.27.0.13'  
	), Netzwerkbereichsdefintionen_erweitert(IP_Bereich,Name,ipv4_binary_net,ipv4cidr_decimal_net) AS (
	SELECT	IP_Bereich,Name,ipv4_binary_net,ipv4cidr_decimal_net
	FROM	Netzwerkbereichsdefintionen
	CROSS APPLY dbo.test_convert_ipv4(IP_Bereich)
	), Geräteliste_erweitert(IP_Adresse,Gerätename,ipv4_binary) AS (
	SELECT	IP_Adresse,Gerätename,ipv4_binary
	FROM	Geräteliste
	CROSS APPLY dbo.test_convert_ipv4(IP_Adresse)
	)
SELECT	*
FROM	 Netzwerkbereichsdefintionen_erweitert nets
LEFT JOIN Geräteliste_erweitert hosts
ON		nets.ipv4_binary_net = left(hosts.ipv4_binary,nets.ipv4cidr_decimal_net)
Die Aufgabenstellung kam aus einem anderen Forum, produktiv habe ich das noch nicht verwendet. Es ging darum IPv4 Adressen mit Netzen zu joinen.

Edit: Das Script ist von mir und ich wüsste jetzt nicht wie ich es performanter oder eleganter machen könnte. Das mit der Binär-Konvertierung war für mich damals neu, das ist noch nicht so intuitiv für mich face-wink
DocuSnap-Dude
DocuSnap-Dude 20.09.2021 um 11:42:11 Uhr
Goto Top
GEil! Danke dir!