Created
March 19, 2020 14:24
-
-
Save gamemann/8d9d434c7f3471e8a7878c7e390d3a45 to your computer and use it in GitHub Desktop.
Testing sending outbound packets inside network namespace via AF_PACKET sockets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <netinet/ip.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <net/if.h> | |
#include <linux/if.h> | |
#include <linux/if_packet.h> | |
#include <linux/tcp.h> | |
#include <linux/udp.h> | |
#include <linux/icmp.h> | |
#include <net/ethernet.h> | |
#include <string.h> | |
#include <error.h> | |
#include <errno.h> | |
#include <inttypes.h> | |
#include <pthread.h> | |
#include <sys/sysinfo.h> | |
#include <sys/ioctl.h> | |
#include <signal.h> | |
#include <ctype.h> | |
#define REDIRECT_HEADER | |
#include "csum.h" | |
#define MAX_PCKT_LENGTH 65535 | |
static int cont = 1; | |
static unsigned char sMAC[ETH_ALEN]; | |
static unsigned char dMAC[ETH_ALEN]; | |
void signHdl(int tmp) | |
{ | |
cont = 0; | |
} | |
void GetGatewayMAC() | |
{ | |
char cmd[] = "ip neigh | grep \"$(ip -4 route list 0/0|cut -d' ' -f3) \"|cut -d' ' -f5|tr '[a-f]' '[A-F]'"; | |
FILE *fp = popen(cmd, "r"); | |
if (fp != NULL) | |
{ | |
char line[18]; | |
if (fgets(line, sizeof(line), fp) != NULL) | |
{ | |
sscanf(line, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &dMAC[0], &dMAC[1], &dMAC[2], &dMAC[3], &dMAC[4], &dMAC[5]); | |
} | |
pclose(fp); | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
if (argc < 4) | |
{ | |
perror("main"); | |
exit(1); | |
} | |
int sockfd; | |
struct sockaddr_ll a; | |
a.sll_family = PF_PACKET; | |
a.sll_ifindex = if_nametoindex(argv[1]); | |
a.sll_protocol = htons(ETH_P_IP); | |
a.sll_halen = ETH_ALEN; | |
sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP)); | |
if (sockfd < 0) | |
{ | |
perror("socket"); | |
exit(1); | |
} | |
struct ifreq ifr; | |
memset(&ifr, 0, sizeof(ifr)); | |
strcpy(ifr.ifr_name, argv[1]); | |
if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) != 0) | |
{ | |
perror("ioctl"); | |
exit(1); | |
} | |
memcpy(a.sll_addr, ifr.ifr_addr.sa_data, ETH_ALEN); | |
memcpy(sMAC, a.sll_addr, ETH_ALEN); | |
GetGatewayMAC(); | |
if (bind(sockfd, (struct sockaddr *)&a, sizeof(a)) < 0) | |
{ | |
perror("bind"); | |
exit(1); | |
} | |
printf("Source MAC => "); | |
for(uint8_t i = 0; i < ETH_ALEN; i++) | |
{ | |
printf("%02x", sMAC[i]); | |
if (i != 5) | |
{ | |
printf(":"); | |
} | |
} | |
printf("\n"); | |
printf("Destination MAC => "); | |
for(uint8_t i = 0; i < ETH_ALEN; i++) | |
{ | |
printf("%02x", dMAC[i]); | |
if (i != 5) | |
{ | |
printf(":"); | |
} | |
} | |
printf("\n\n"); | |
signal(SIGINT, signHdl); | |
while (cont) | |
{ | |
char buffer[MAX_PCKT_LENGTH]; | |
struct ethhdr *ethhdr = (struct ethhdr *) (buffer); | |
struct iphdr *iphdr = (struct iphdr *) (buffer + sizeof(struct ethhdr)); | |
struct udphdr *udphdr = (struct udphdr *) (buffer + sizeof(struct ethhdr) + sizeof(struct iphdr)); | |
// Eth | |
memcpy(ethhdr->h_source, sMAC, ETH_ALEN); | |
memcpy(ethhdr->h_dest, dMAC, ETH_ALEN); | |
ethhdr->h_proto = htons(ETH_P_IP); | |
// IP | |
iphdr->ihl = 5; | |
iphdr->version = 4; | |
iphdr->id = rand(); | |
iphdr->protocol = IPPROTO_UDP; | |
iphdr->frag_off = 0; | |
iphdr->tos = 0x0; | |
iphdr->ttl = 64; | |
iphdr->saddr = inet_addr(argv[2]); | |
iphdr->daddr = inet_addr(argv[3]); | |
iphdr->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr)); | |
iphdr->check = 0; | |
iphdr->check = ip_fast_csum(iphdr, iphdr->ihl); | |
// UDP | |
udphdr->source = htons(15000); | |
udphdr->dest = htons(25000); | |
udphdr->len = htons(sizeof(struct udphdr)); | |
udphdr->check = 0; | |
udphdr->check = csum_tcpudp_magic(iphdr->saddr, iphdr->daddr, sizeof(struct udphdr), IPPROTO_UDP, csum_partial(udphdr, sizeof(struct udphdr), 0)); | |
uint16_t sent; | |
if ((sent = write(sockfd, buffer, ntohs(iphdr->tot_len) + sizeof(struct ethhdr))) < 0) | |
{ | |
perror("write"); | |
} | |
printf("Sent %d (%lu)\n", sent, ntohs(iphdr->tot_len) + sizeof(struct ethhdr)); | |
sleep(1); | |
} | |
close(sockfd); | |
exit(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment