socket.c (3775B)
1 #include <fcntl.h> 2 #include <linux/if_arp.h> 3 #include <linux/if_packet.h> 4 #include <linux/if_tun.h> 5 #include <linux/if.h> 6 #include <netinet/in.h> 7 #include <string.h> 8 #include <strings.h> 9 #include <sys/ioctl.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <sys/socket.h> 13 #include <unistd.h> 14 15 #include "socket.h" 16 17 unsigned char * iface_mac(char * ifname) { 18 unsigned char *mac = calloc(1, ETH_ALEN); 19 struct ifreq ifr; 20 int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 21 ifr.ifr_addr.sa_family = AF_INET; 22 strncpy(ifr.ifr_name , ifname , IFNAMSIZ-1); 23 ioctl(sockfd, SIOCGIFHWADDR, &ifr); 24 close(sockfd); 25 memcpy(mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN); 26 return mac; 27 } 28 29 int iface_idx(int sockfd, char * ifname) { 30 struct ifreq ifr; 31 bzero(&ifr, sizeof(ifr)); 32 33 // Get interface index 34 strncpy((char *)ifr.ifr_name, ifname, IFNAMSIZ); 35 if ((ioctl(sockfd, SIOCGIFINDEX, &ifr)) == -1) { 36 fprintf(stderr, "Error getting interface index for %s\n", ifname); 37 perror("Error getting interface index"); 38 close(sockfd); 39 return -1; 40 } 41 42 return ifr.ifr_ifindex; 43 } 44 45 int if_ioctl(int cmd, struct ifreq* req) { 46 int ret, sock; 47 sock = socket(AF_INET, SOCK_PACKET, 0); 48 if (sock < 0) { 49 return -1; 50 } 51 ret = ioctl(sock, cmd, req); 52 close(sock); 53 return ret; 54 } 55 56 int sockraw_open(char * ifname) { 57 struct ifreq ifr; 58 59 // Open socket (P_ALL, due to custom ethertype field) 60 int sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 61 if (sockfd < 0) { 62 perror("Error opening socket"); 63 close(sockfd); 64 return -1; 65 } 66 67 // Old bind to socket 68 struct sockaddr_ll sll; 69 bzero(&sll, sizeof(sll)); 70 sll.sll_family = AF_PACKET; 71 sll.sll_ifindex = iface_idx(sockfd, ifname); 72 sll.sll_protocol = htons(ETH_P_ALL); 73 if (sll.sll_ifindex < 0) { 74 // Error already printed, not reprinting 75 return -1; 76 } 77 if((bind(sockfd, (struct sockaddr *)&sll, sizeof(sll))) == -1) { 78 perror("Error binding raw socket to interface"); 79 close(sockfd); 80 return -1; 81 } 82 83 // Get current iface configuration 84 memset(&ifr, 0, sizeof(ifr)); 85 strcpy(ifr.ifr_name, ifname); 86 if (if_ioctl(SIOCGIFFLAGS, &ifr) < 0) { 87 perror("Get interface flags"); 88 } 89 90 // Set iface to promiscuous mode 91 ifr.ifr_flags |= IFF_PROMISC; 92 if (if_ioctl(SIOCSIFFLAGS, &ifr) < 0) { 93 perror("Configure interface promiscuous mode"); 94 } 95 96 // Return the prepared socket 97 return sockfd; 98 } 99 100 int tap_alloc(char * ifname, unsigned char * mac) { 101 struct ifreq ifr; 102 int fd, err; 103 104 if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) { 105 perror("Open tun"); 106 return -1; 107 } 108 109 // Bring up the interface 110 memset(&ifr, 0, sizeof(ifr)); 111 ifr.ifr_flags = IFF_TAP | IFF_NO_PI; 112 if( *ifname ) { 113 strncpy(ifr.ifr_name, ifname, IFNAMSIZ); 114 } 115 if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ 116 perror("Open tun"); 117 close(fd); 118 return err; 119 } 120 strcpy(ifname, ifr.ifr_name); 121 122 // Set the interface's mac address 123 if ( mac ) { 124 // TODO: random, copied or specific mac address pulled from ini 125 memset(&ifr, 0, sizeof(ifr)); 126 strcpy(ifr.ifr_name, ifname); 127 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; 128 memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ALEN); 129 if ((err = if_ioctl(SIOCSIFHWADDR, &ifr)) < 0) { 130 perror("Set if hwaddr"); 131 close(fd); 132 return err; 133 } 134 } 135 136 // Fetch the current flags 137 memset(&ifr, 0, sizeof(ifr)); 138 strcpy(ifr.ifr_name, ifname); 139 if (if_ioctl(SIOCGIFFLAGS, &ifr) < 0) { 140 perror("failed to get the interface flags"); 141 close(fd); 142 return err; 143 } 144 145 // Bring up the interface 146 if (!(ifr.ifr_flags & IFF_UP)) { 147 ifr.ifr_flags |= IFF_UP; 148 if (if_ioctl(SIOCSIFFLAGS, &ifr) < 0) { 149 perror("failed to get the interface flags"); 150 close(fd); 151 return err; 152 } 153 } 154 155 return fd; 156 }