linux - Is raw socket on loopback interface possible? -
we trying communicate server listening on linux loopback interface via raw socket , seems server not single packet us. packets send visible in wireshark.
is raw socket on loopback possible @ all? (please, don't ask why need it: it's complicated explain here)
edit: how open it
_i_rawsocket = socket( pf_packet, sock_raw, htons(eth_p_all))) memset( &ifr, 0, sizeof( ifr ) ); strcpy( ifr.ifr_ifrn.ifrn_name, _interfacename); ioctl( _i_rawsocket, siocgifindex, &ifr ) memset( &sll, 0, sizeof( sll ) ); sll.sll_family = af_packet; sll.sll_ifindex = ifr.ifr_ifindex; sll.sll_protocol = htons( eth_p_all ); bind( _i_rawsocket, (struct sockaddr *) &sll, sizeof( sll ))
the server lighttpd , it's reachable via normal socket on localhost. netstat --raw prints empty table i'm absolutely sure have 2 functional raw sockets on normal eth devices.
raw sockets behave particularly fizzy bind() , connect(), can't confirm issue lies them. suggest follow more straightforward approach:
sender
#include <sys/socket.h> #include <sys/types.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #define dest "127.0.0.1" int main(int argc, char **argv) { int s; struct sockaddr_in dst_addr; char packet[50]; struct iphdr *ip = (struct iphdr *)packet; if((s = socket(af_inet, sock_raw, ipproto_raw)) < 0) { perror("error:"); exit(exit_failure); } dst_addr.sin_family = af_inet; dst_addr.sin_port = 0; /* not needed in sock_raw */ inet_pton(af_inet, dest, (struct in_addr *)&dst_addr.sin_addr.s_addr); memset(dst_addr.sin_zero, 0, sizeof(dst_addr.sin_zero)); memset(packet, 'a', sizeof(packet)); /* payload */ ip->ihl = 5; ip->version = 4; ip->tos = 0; ip->tot_len = htons(40); ip->frag_off = 0; /* nf */ ip->ttl = 64; ip->protocol = ipproto_raw; /* has ipproto_raw */ ip->check = 0; ip->saddr = dst_addr.sin_addr.s_addr; ip->daddr = dst_addr.sin_addr.s_addr; while(42) { sleep(5); if (sendto(s, packet, sizeof(packet), 0, (struct sockaddr *)&dst_addr, (socklen_t)sizeof(dst_addr)) < 0) perror("uh oh:"); } return(0); }
receiver
#include <sys/socket.h> #include <sys/types.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int s; struct sockaddr_in src_addr; char packet[50]; if ((s = socket(af_inet, sock_raw, ipproto_raw)) < 0) { perror("error:"); exit(exit_failure); } memset(packet, 0, sizeof(packet)); socklen_t *len = (socklen_t *)sizeof(src_addr); int fromlen = sizeof(src_addr); while(42) { if (recvfrom(s, &packet, sizeof(packet), 0, (struct sockaddr *)&src_addr, &fromlen) < 0) perror("uh oh:"); int = sizeof(struct iphdr); /* print payload */ for(; < sizeof(packet); i++) { printf("%c", packet[i]); } printf("\n"); } return(0); }
i hope these behave want them to. read man 7 raw
gory details of why works , more importantly man 7 packet
if want extend it. also, take note ipproto_raw implies ip_hdrincl socket option, why we're constructing ip header ourselves - although ip checksum , total length computed , filled in kernel, still.
edit: in addition, if wanted raw socket send valid data application lighttpd, you'd have match protocol
argument socket()
provide valid values ip header fields. proper ethernet header not mandatory - important field filled kernel stack.
Comments
Post a Comment