Monday 15 March 2010

sockets - C Program to receive and send the same packets out over another interface -



sockets - C Program to receive and send the same packets out over another interface -

i have linux scheme 2 physical interfaces. need intercept (read) incoming packets on 1 interface, read (or process) info , send out on other interface - middleman. able extract header fields , payload info packets not able set on wire again. how send packet on way through other interface?

// #includes struct sockaddr_in source,dest; int i,j,k; int main() { int saddr_size , data_size; struct sockaddr_in saddr; unsigned char *buffer=malloc(65535); int sock_raw = socket( af_packet , sock_raw , htons(eth_p_all)) ; if(sock_raw < 0) perror("setsockopt"); setsockopt(sock_raw , sol_socket , so_bindtodevice , "eth0" , strlen("eth0")+ 1 ); if(sock_raw < 0) { perror("socket error"); homecoming 1; } while(1) { saddr_size = sizeof (struct sockaddr); //receive packet data_size = recvfrom(sock_raw , buffer , 65536 , 0 ,(struct sockaddr *) &saddr , (socklen_t*)&saddr_size); if(data_size <0 ) { printf("recvfrom error , failed packets\n"); homecoming 1; } else{ printf("received %d bytes\n",data_size); //huge code process packet //send out through "eth1" here } } close(sock_raw); homecoming 0; }

just assume udp or icmp packets if makes easier explain (using simple "sendto" function maybe)- can handle sorting. not worry intended destination, want set packets on wire - delivery not important.

edit 1:

if gives me runtime error saying "invalid argument". doesn't matter if i'm sending buffer or "hello world".

bytes_sent=sendto(sock_raw, buffer, 65536, 0,(struct sockaddr *) &saddr ,saddr_size); if (bytes_sent < 0) { perror("sendto"); exit(1); }

edit 2 : allow me create simpler- have 2 pipes , b. balls roll in , receive them. want set them in pipe b , send them on way. ethernet bridges work in similar way - sending packets on interfaces involved. have used bridge if didn't have basic info packet headers. , i'm not @ modifying kernel bridge drivers.

edit 3 : i'll seek 1 lastly time different question. if have received finish raw packet source/destination addresses included in headers , all, how send anywhere (i don't care where) using sendto ? should add together info "struct sockaddr" in sendto phone call , or can utilize same 1 did in recvfrom phone call ?

i got work ! able send packets received on eth0 eth1 unchanged.

corrections:

"write" instead of "sendto" , although isn't advisable. a fresh socket sending only. it seems so_bindtodevice using setsockopt doesn't work had utilize bind function bind socket interface. struct sockaddr_in struct sockaddr_ll

i set in hurry there may redundant lines in there. don't know if daddr neccessry works there is. here's total code :

// #includes int main() { int saddr_size , data_size, daddr_size, bytes_sent; struct sockaddr_ll saddr, daddr; unsigned char *buffer=malloc(65535); int sock_raw = socket( af_packet , sock_raw , htons(eth_p_all)) ; //for receiving int sock = socket( pf_packet , sock_raw , ipproto_raw) ; //for sending memset(&saddr, 0, sizeof(struct sockaddr_ll)); saddr.sll_family = af_packet; saddr.sll_protocol = htons(eth_p_all); saddr.sll_ifindex = if_nametoindex("eth0"); if (bind(sock_raw, (struct sockaddr*) &saddr, sizeof(saddr)) < 0) { perror("bind failed\n"); close(sock_raw); } memset(&daddr, 0, sizeof(struct sockaddr_ll)); daddr.sll_family = af_packet; daddr.sll_protocol = htons(eth_p_all); daddr.sll_ifindex = if_nametoindex("eth1"); if (bind(sock, (struct sockaddr*) &daddr, sizeof(daddr)) < 0) { perror("bind failed\n"); close(sock); } struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth1"); if (setsockopt(sock, sol_socket, so_bindtodevice, (void *)&ifr, sizeof(ifr)) < 0) { perror("bind eth1"); } while(1) { saddr_size = sizeof (struct sockaddr); daddr_size = sizeof (struct sockaddr); //receive packet data_size = recvfrom(sock_raw , buffer , 65536 , 0 ,(struct sockaddr *) &saddr , (socklen_t*)&saddr_size); if(data_size <0 ) { printf("recvfrom error , failed packets\n"); homecoming 1; } else{ printf("received %d bytes\n",data_size); //huge code process packet (optional) //send same packet out bytes_sent=write(sock,buffer,data_size); printf("sent %d bytes\n",bytes_sent); if (bytes_sent < 0) { perror("sendto"); exit(1); } } } close(sock_raw); homecoming 0; }

thanks responded.

c sockets networking packet-capture

No comments:

Post a Comment