Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : Tool für broadcastweiterleitung streikt



zippelmann
03-01-2005, 14:08
Moin ich versuche seit geraumer Zeit über n VPN zu daddeln. Leider arbeiten die games mit Broadcasts die nicht einfach weitergeleitet werden. Aber dafür gibts ne kleine Lösung. Hab ich in der ct entdeckt.

Das teil nennt sich bcrelay und soll genau die Aufgabe erfüllen. Leider funzt das nicht so ganz. Das tool sucht aktive interfaces und genau da ist der haken. Es findet wohl keine. Ob 2.4er oder 2.6er Kernel spielt dabei keine rolle.



#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <regex.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>

// A broadcast packet repeater. This packet repeater (currently designed for
// udp packets) will listen for broadcast packets on a particular port.
// When it receives the packets, it will then re-broadcast the packet.
//
// Written by TheyCallMeLuc(at)yahoo.com.au
// I accept no responsiblity for the function of this program if you
// choose to use it.
//
// This software is completely free. You can use and/or modify this
// software at your hearts content. You are free to redistribute it as
// long as it is accompanied with the source and my credit is included.

// Fixed two minor bugs, so that it compiles (ju@ct.heise.de):
// - changed MAXIF from "const int" to "#define"
// - included instance name "head" in definition of struct packet


const time_t TIMEOUT = 30; // Rescan interface bus after TIMEOUT seconds
#define MAXIF 255 // Maximum interfaces to use

struct packet {
struct iphdr ip;
union {
struct udphdr udp;
struct tcphdr tcp;
} head;
char data[ETHERMTU];
};

char *discoverActiveInterfaces(int s, char *regex);


int
main(int argc, char **argv) {
socklen_t salen = sizeof(struct sockaddr_ll);
int i, s, len, interface, port;
struct sockaddr_ll sa;
time_t lasttime = 0;
char *iflist = NULL; // We initialise this after the 1st packet
struct packet p;

if (argc != 3) {
fprintf(stderr, "usage: %s port regex\n", *argv);
fprintf(stderr, "\tWhere regex expression used to match");
fprintf(stderr, " interface names. see regex(7)\n");
fprintf(stderr, "e.g. %s 6112 \"eth1|ipsec\"\n", *argv);
return 0;
}

// Become Daemon. Return pid of child.
if ((i = fork()))
return i;

// Save the port number in network byte order
port = htons(atoi(argv[1]));

// Create Socket and listen to ALL ethernet traffic.
if ((s = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 0)
return fprintf(stderr, "%s: Error creating socket\n", *argv);

// Main loop
while ((len = recvfrom(s, &p, sizeof(p), 0,
(struct sockaddr *)&sa, &salen)) > 0) {

// Ignore packets that are not UDP Broadcasts on our given port
if (p.ip.protocol != IPPROTO_UDP || p.ip.daddr != INADDR_BROADCAST ||
p.head.udp.dest != port)
continue;

// Check for new interfaces after TIMEOUT seconds
if (time(NULL) - lasttime > TIMEOUT) {
iflist = discoverActiveInterfaces(s, argv[2]);
time(&lasttime);
}

// Make sure the packet is coming from a valid interface
if (strchr(iflist, sa.sll_ifindex) == NULL)
continue;

// Now forward the packet to every other interface in our list.
interface = sa.sll_ifindex;
for (i = 0; iflist[i]; i++) {
// Skip the interface the packet came in on
if (iflist[i] == interface)
continue;

sa.sll_ifindex = iflist[i];
sendto(s, &p, len, 0, (struct sockaddr *)&sa, salen);
}
}

// Finish up. When do we get here?
close(s);

return 0;
}

// Discover active interfaces
char *
discoverActiveInterfaces(int s, char *regex) {
static char iflist[MAXIF+1]; // Allow for MAXIF interfaces
static struct ifconf ifs;
int i, cntr = 0;
regex_t preg;

regcomp(&preg, regex, REG_ICASE|REG_EXTENDED);
ifs.ifc_len = MAXIF*sizeof(struct ifreq);
ifs.ifc_req = malloc(ifs.ifc_len);
ioctl(s, SIOCGIFCONF, &ifs); // Discover active interfaces
for (i = 0; i * sizeof(struct ifreq) < ifs.ifc_len && cntr < MAXIF; i++)
if (regexec(&preg, ifs.ifc_req[i].ifr_name, 0, NULL, 0) == 0) {
ioctl(s, SIOCGIFINDEX, &ifs.ifc_req[i]); // Discover interface index
iflist[cntr++] = (char)ifs.ifc_req[i].ifr_ifindex;
}
iflist[cntr] = '\0'; // Terminate list
free(ifs.ifc_req); // Stop that leak.

return iflist;
}


Habt ihr vielleicht noch ne idee ?