Andreas
Nadobnik
hidden page
   
   


NAME

broadcast-relay.pl - überträgt Broadcasts von einem Subnetz in ein anderes

Top


SYNOPSIS

      broadcast-relay.pl --server --bcaddr <BCADDR> --bcport <BCPORT> --srvport <SRVPORT>
      broadcast-relay.pl --client --srvaddr <SRVADDR> --bcport <BCPORT> --srvport <SRVPORT>

            <BCADDR>    = Broadcast-Adresse (z.B. 192.168.1.255)
            <BCPORT>    = Broadcast-Port (z.B. 7777)
            <SRVADDR>   = Server IP-Adresse (z.B. 192.168.1.1)
            <SRVPORT>   = Server Port  (z.B. 7776)

Top


DESCRIPTION

Netzwerk-Broadcasts können eine tolle Sache sein. Was gibt es einfacheres um mehrere Clients im Subnetz direkt mit Informationen zu versorgen. Viele Netzwerk-Spiele nutzen diese Möglichkeit. Nun ja, aber Broadcasts funktionieren eben normalerweise nur innerhalb des Subnetzes.

Ein Router der was auf sich hält lässt es nicht zu das Broadcasts des einen Subnetzes auch noch das andere Subnetz belasten. Mal ganz davon abgesehen das es nicht allzu trivial ist einem Router beizubringen auch Broadcasts zu routen, nicht jederman hat die Möglichkeit Veränderungen am Router vorzunehmen. Sei es weil es eine gekaufte "Black-Box" ist oder weil man gar nicht der Administrator des Routers ist.

Hier kommt nun mein broadcast-relay.pl ins Spiel...

Das Script broadcast-relay.pl muss in beiden Subnetzen gestartet werden. Dazu muss es einmal als Server und einmal als Client gestartet werden.

Der Client läuft in dem Subnetz in dem die "Original-Broadcasts" gesendet werden. Der Server dementsprechend in dem Subnetz in das die Broadcasts weitergeleitet werden sollen.

Der Client baut eine Verbindung mit dem Server auf und lauscht in einer Endlos-Schleife nach Broadcasts. Diese werden dann über die aufgebaute TCP-Verbindung zum Server uebertragen.

Der Server wartet auf eine Verbindung vom Client und sendet die vom Client empfangenen Pakete als Broadcasts auf einem frei definierbaren Port in das eigene Subnetz.

Top


WARNING

Broadcasts können erhebliche Netzwerklast verursachen. Nicht umsonst vermeidet man es Broadcasts zwischen Subnetzen zu routen. Vermeidet es vor allem das Script innerhalb nur eines Subnetzes zu testen. Ein einzelner Broadcast würde sonst ständig ins Subnetz wiederholt gesendet werden. Ein Zusammenbruch des Netzes wäre somit vorprogrammiert.

Top


EXAMPLES

      broadcast-relay.pl --server --bcaddr 192.168.1.255 --bcport 7777 --srvport 7776

      broadcast-relay.pl --client --srvaddr 192.168.1.1 --bcport 7777 --srvport 7776

Top


HISTORY

    0.0.1 - 2004-06-08: - Erste Version bestand noch aus zwei einzelnen Scripts

    0.1.0 - 2004-06-14: - Zusammenfassung der Einzelscripts zu Einem.
                        - Einige Parameterprüfungen hinzugefügt
    0.1.1 - 2004-06-17: - kleines Bugfixing

Top


DISCLAIMER

Das Benutzen dieses Scripts unterliegt der eigenen Verantwortung! Ich übernehme keinerlei Gewährleistung für etwaige Schäden!

Top


AUTHOR

A. Nadobnik

Top


Listing 1: broadcast-relay.pl

    001 #!/usr/bin/perl
    002 #
    003 #################
    004 #
    005 # Author:  Andreas Nadobnik
    006 # Written: 2004-06-08
    007 # Changed: 2004-06-17
    008 # Version: 0.1.1
    009 # Licence: GPL (www.gnu.org)
    010 #
    011 #################
    012 #
    013 # Dieses Script dient dazu Broadcasts aufzufangen, ueber TCP zu einem anderen
    014 # Subnetz zu uebertragen und dort wieder als Broadcasts zu senden.
    015 #
    016 # Der Client baut eine Verbindung mit dem broadcast-relay Server auf und
    017 # lauscht in einer Endlos-Schleife nach Broadcasts. Diese werden dann ueber
    018 # die aufgebaute TCP-Verbindung zum Server uebertragen.
    019 #
    020 # Der Server wartet auf eine Verbindung vom broadcast-relay Client und
    021 # sendet die vom Client gesendeten Pakete wieder als Broadcasts raus.
    022 #
    023 # Usage:
    024 #       broadcast-relay.pl --server --bcaddr <BCADDR> --bcport <BCPORT> --srvport <SRVPORT>
    025 #       broadcast-relay.pl --client --srvaddr <SRVADDR> --bcport <BCPORT> --srvport <SRVPORT>
    026 #
    027 #       <BCADDR>    = Broadcast-Adresse (z.B. 192.168.1.255)
    028 #       <BCPORT>    = Broadcast-Port (z.B. 7777)
    029 #       <SRVADDR>   = Server IP-Adresse (z.B. 192.168.1.1)
    030 #       <SRVPORT>   = Server Port  (z.B. 7776)
    031 #
    032 # Examples:
    033 #
    034 #       broadcast-relay.pl --server --bcaddr 192.168.1.255 --bcport 7777 --srvport 7776
    035 #     or
    036 #       broadcast-relay.pl --client --srvaddr 192.168.1.1 --bcport 7777 --srvport 7776
    037 #
    038 #################
    039
    040 use strict;
    041 use Getopt::Long;
    042 use IO::Socket;
    043
    044 my $bcast_port;
    045 my $bcast_addr;
    046 my $server_port;
    047 my $server_addr;
    048 my $role="";
    049 my $help;
    050
    051 GetOptions (	"bcport=i"	=> \$bcast_port,
    052 		"bcaddr=s"	=> \$bcast_addr,
    053 		"srvport=i"	=> \$server_port,
    054 		"srvaddr=s"	=> \$server_addr,
    055 		"help|h"	=> \$help,
    056 		"server"	=> sub {$role="server"},
    057 		"client"	=> sub {$role="client"});
    058
    059 my $MaxPacketSize = 65536;	# Maximale Groesse eines UDP-Packetes
    060
    061 usage(0) if $help;
    062
    063 if ($role eq "")
    064 {
    065 	print STDERR"\nERROR:\nYou must define a role (client|server) for this script!\n";
    066 	usage(1);
    067 }
    068
    069 if (($bcast_port < 1)||($bcast_port > 65535))
    070 {
    071 	print STDERR"\nERROR:\nThe broadcast port is illegal!\n";
    072 	usage(1);
    073 }
    074
    075 if (($server_port < 1)||($server_port > 65535))
    076 {
    077 	print STDERR"\nERROR:\nThe server port is illegal!\n";
    078 	usage(1);
    079 }
    080
    081 client() if ($role eq "client");
    082 server() if ($role eq "server");
    083
    084 exit(0);
    085
    086 sub client
    087 {
    088 	print "try to connect to server at $server_addr:$server_port\n";
    089
    090 	my $client_socket = new IO::Socket::INET (
    091 		PeerAddr => $server_addr,
    092 		PeerPort => $server_port,
    093 		Proto => 'tcp',
    094 		Timeout => 5)
    095 		 || die "no socket... $!\n";
    096
    097 	print "connected to server at $server_addr:$server_port\n";
    098 	print "listen for broadcasts on port $bcast_port\n";
    099 	print "press ctrl+c to end this script\n";
    100
    101 	while(1)
    102 	{
    103 		# Socket für den Empfang der UDP-Packete oeffnen
    104 		my $listener = new IO::Socket::INET (
    105 			LocalPort => 7777,
    106 			Proto => 'udp')
    107 			 || die "no listen socket... $!\n";
    108 		# Endlosschleife für den Enpfang der Broadcasts
    109 		while(1)
    110 		{
    111 			my $Msg = $listener->recv(my $daten,$MaxPacketSize,0);	# Packet empfangen
    112 			print $client_socket "$daten";
    113 		}
    114 		$listener->close();
    115 	}
    116 	$client_socket->close();
    117 }
    118
    119 sub server
    120 {
    121 	my $server_socket = new IO::Socket::INET (
    122 		LocalPort => $server_port,
    123 		Listen => &SOMAXCONN,
    124 		Proto => 'tcp',
    125 		Reuse => 1)
    126 		 || die "no socket... $!\n";
    127
    128 	print "waiting for clients on port $server_port (tcp)\n";
    129 	print "incoming data will be broadcastet to $bcast_addr:$bcast_port\n";
    130 	print "press ctrl+c to end this script\n";
    131
    132 	# In der Schleife auf eingehende Verbindungen warten...
    133 	while (my $client_socket = $server_socket->accept() )
    134 	{
    135 		$client_socket->autoflush(1);
    136 		my $hostname = gethostbyaddr($client_socket->peeraddr,AF_INET);
    137 		printf "[connection from %s]\n", $hostname || $client_socket->peerhost;
    138
    139 		while($client_socket->connected())
    140 		{
    141 			my $Msg = $client_socket->recv(my $daten,$MaxPacketSize,0);
    142
    143 			my $raddr = gethostbyname($bcast_addr);
    144 			my $them = pack_sockaddr_in($bcast_port, $raddr);
    145 			my $proto = getprotobyname('udp');
    146
    147 			socket(SOCK, AF_INET, SOCK_DGRAM, $proto) || die "socket : $!";
    148 			setsockopt(SOCK, SOL_SOCKET, SO_BROADCAST, 1) || die "setsockopt : $!";
    149
    150 			send(SOCK, $daten, 0, $them) || die "send : $!";
    151 			close SOCK;
    152 		}
    153 	}
    154
    155 	$server_socket->close();
    156 }
    157
    158 sub usage
    159 {
    160 	print <<ENDOFHELP;
    161
    162 Usage:
    163       broadcast-relay.pl --server --bcaddr <BCADDR> --bcport <BCPORT> --srvport <SRVPORT>
    164       broadcast-relay.pl --client --srvaddr <SRVADDR> --bcport <BCPORT> --srvport <SRVPORT>
    165
    166       <BCADDR>    = Broadcast-Adresse (z.B. 192.168.1.255)
    167       <BCPORT>    = Broadcast-Port (z.B. 7777)
    168       <SRVADDR>   = Server IP-Adresse (z.B. 192.168.1.1)
    169       <SRVPORT>   = Server Port  (z.B. 7776)
    170
    171 Examples:
    172
    173       broadcast-relay.pl --server --bcaddr 192.168.1.255 --bcport 7777 --srvport 7776
    174     or
    175       broadcast-relay.pl --client --srvaddr 192.168.1.1 --bcport 7777 --srvport 7776
    176
    177 ENDOFHELP
    178
    179 	exit(shift);
    180 }

Top

Visits: 2182 Valid HTML 4.01! Valid CSS! 2019-06-19 06:27:22