broadcast-relay.pl - überträgt Broadcasts von einem Subnetz in ein anderes
Top
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
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
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
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
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
Das Benutzen dieses Scripts unterliegt der eigenen Verantwortung! Ich übernehme keinerlei Gewährleistung für etwaige Schäden!
Top
A. Nadobnik
Top
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 |