Skip to content

Instantly share code, notes, and snippets.

@gamemann
Created March 19, 2020 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gamemann/8d9d434c7f3471e8a7878c7e390d3a45 to your computer and use it in GitHub Desktop.
Save gamemann/8d9d434c7f3471e8a7878c7e390d3a45 to your computer and use it in GitHub Desktop.
Testing sending outbound packets inside network namespace via AF_PACKET sockets
#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