Raw Socket auf ein Interface binden

tharem

Grünschnabel
Hi

ich muss mich zur Zeit mit Socket-Programmierung herumschlagen. Es soll eine Art Filter auf Low Level Ebene erstellt werden.

Soweit funktioniert auch alles mit einem RAW SOCKET.... nur das Problem ist, dass er jetzt von allen Netzwerkinterfaces liest (der Rechner hier hat 4 Netzwerkkarten) mich interessiert aber nur der Traffic von einer Karte.

Weiß jemand wie ich einen RAW SOCKET so einstelle, dass er nur von einer Karte empfängt. Beim Senden von Packeten muss man ja auch ein bestimmtes Interface angeben, dann muss das doch auch beim Empfangen gehen. Ich habe schon einige Sachen nachgeschaut (ioctl, setsockopt, bind) aber habe noch nichts relevantes gefunden.

Ich kann auch nicht die MAC-Adresse im Paket überprüfen und daher eine Zuordnung vornehmen, weil die Karte im promiscuous-mode laufen soll.

Bin für jeden Hinweis dankbar.
Ciao

Bisher läuft es kurzgefasst ungefähr so:
Code:
int sock;
struct ifreq ifinfo;
char packet[PACKETSIZE];
struct ethhdr *eth = (struct ethhdr *) packet;

sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

strcpy(ifinfo.ifr_name, "eth1");
ioctl(sock, SIOCGIFFLAGS, &ifinfo);
ifinfo.ifr_ifru.ifru_flags |= IFF_PROMISC;
ioctl(sock, SIOCSIFFLAGS, &ifinfo);

while(1) {
	read(sock, packet, PACKETSIZE);
	printf("src-mac:%s\n", ether_ntoa((struct ether_addr*)eth->h_source));
}
 
Hi Tom,

danke für den Link... aber ich habe in der pdf-Datei nur eine Stelle gefunden wo bind() benutzt wird:
Code:
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = PORT;
bind(sock_1, &server, sizeof(struct sockaddr_in))
und da wird der Socket mit einem Port verkoppelt, nicht aber mit einer speziellen Netzwerkkarte.

Ich habe mittlerweile aber etwas andere über bind() herausgefunden. (siehe: man 7 packet)
Man kann dort einfach eine andere Struktur übergeben wo man ein Interface-Index angeben kann. Allerdings wenn ich das ausführe kommt auf meinem Socket garkein Traffic mehr an.

Ich bin also weiter auf der Suche :confused:

Gruß Martin
 
Ich habs gefunden. Jedenfalls laut den ersten Tests nach zu urteilen ;)
Für alle die es interessiert:
Code:
int sock;
struct ifreq ifinfo;
struct sockaddr_ll sockinfo;

/* open socket */
sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

/* get interface index number */
memset(&ifinfo, 0, sizeof(ifinfo));
strcpy(ifinfo.ifr_name, "eth1");
ioctl(sock, SIOCGIFINDEX, &ifinfo);

/* set sockinfo pointing to interface */
memset(&sockinfo, 0, sizeof(sockinfo));
sockinfo.sll_family = PF_PACKET;
sockinfo.sll_protocol = htons(ETH_P_ALL);
sockinfo.sll_ifindex = ifinfo.ifr_ifindex;

/* bind socket to specific interface */
bind(sock, (struct sockaddr*)&sockinfo, sizeof(sockinfo));

Danke nochmal Tom, dass du darauf beharrt hast, dass es mit bind gehen muss.
 
Zurück