In Linux, one use socket(family, type, protocol) to create a socket. Some tips about raw socket:
1. To capture packets with Ethernet header, use family AF_PACKET
2. PF_PACKET is the same as AF_PACKET. Actually PF_* is the same as AF_*. AF_ prefix is the new way of calling them. (Address Family)
3. When using PF_PACKET, type can either be SOCK_RAW or SOCK_DGRAM
4. protocol can be ETH_P_IP, ETH_P_ALL, etc. The complete list is under Linux source tree include/uapi/linux/if_ether.h
5. IMPORTANT ETH_P_ALL captures all incoming and outgoing packets. Other protocols only capture incoming packets. (See this question: http://stackoverflow.com/questions/20864962/does-capturing-outgoing-frames-using-linux-raw-socket-requires-eth-p-all)
Also remember to bind the raw socket to the particular network interface. Man 7 af_packet for details.
I am unable to intercept the outgoing packet despite using ETH_P_ALL. Can you suggest the exact steps here, please?
ReplyDeleteThis is my code:
if ((raw_sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
fprintf(stderr, "Socket error!\n");
return DR_SOCKET_FAILURE;
}
strncpy(interface_request.ifr_name, dev, IFNAMSIZ);
/* get the current lags the device */
if (ioctl(sock_fd, SIOCGIFFLAGS, &interface_request) == -1) {
fprintf(stderr, "Unable to get the interface index!\n");
return DR_IOCTL_FAILED;
}
/* set the old flags with promiscuous mode */
interface_request.ifr_flags |= IFF_PROMISC;
if (ioctl(sock_fd, SIOCSIFFLAGS, &interface_request) == -1) {
fprintf(stderr, "Unable to set the promiscuous mode!\n");
return DR_IOCTL_FAILED;
}
if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt)
== -1) {
fprintf(stderr, "Unable to set the reuse address!\n");
return DR_SET_SOCK_OPT_FAILED;
}
/* configure the device */
if (ioctl(sock_fd, SIOCGIFINDEX, &interface_request) == -1) {
fprintf(stderr, "Unable to get the interface index!\n");
return DR_IOCTL_FAILED;
}
interface_idx = interface_request.ifr_ifindex;
fprintf(stderr, "Index: %d\n", interface_idx);
sock_addr.sll_family = AF_PACKET;
//sock_addr.sll_protocol = htons(0x800);
sock_addr.sll_protocol = htons(ETH_P_ALL);
sock_addr.sll_ifindex = interface_idx;
if (bind(sock_fd, (struct sockaddr*) &sock_addr, sizeof(sock_addr)) < 0) {
printf("Unable to bind!");
return DR_BIND_FAILED;
}
I suggest you ask on the stackoverflow page. I think you will get more help there.
ReplyDelete