Last active
August 29, 2015 14:16
-
-
Save dterei/b75a69be63c707f800c3 to your computer and use it in GitHub Desktop.
Send packet via macvtap device
This file contains hidden or 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 <string.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <arpa/inet.h> | |
#include <netinet/ether.h> | |
#include <netinet/ip.h> | |
#include <netinet/udp.h> | |
#include <net/if.h> | |
#include <netinet/in.h> | |
#define ETH_HDRLEN ETH_HLEN | |
#define IP4_HDRLEN (sizeof(struct iphdr)) | |
#define UDP_HDRLEN (sizeof(struct udphdr)) | |
#define HOST_IF "mvt1" | |
#define HOST_IP "10.0.1.54" | |
#define DEST_IP "179.32.32.11" | |
#define HOST_PORT 7000 | |
#define DEST_PORT 8000 | |
#define MAC_SRC { 0xbc, 0xae, 0xc5, 0x44, 0x3d, 0x46 } │··································· | |
#define MAC_DST { 0x52, 0x54, 0x00, 0x26, 0xc1, 0x45 } | |
#define PAYLOAD "Hello World!\n" | |
void usage(char* proc) | |
{ | |
printf("usage: %s [vtap device]\n", proc); | |
} | |
size_t build_packet(uint8_t *pkt, size_t pkt_buf_len) | |
{ | |
// Sizes | |
size_t hdr_len = ETH_HDRLEN + IP4_HDRLEN + UDP_HDRLEN; | |
uint16_t data_len = strlen(PAYLOAD); | |
size_t pkt_len = hdr_len + data_len; | |
if (pkt_len > pkt_buf_len) { | |
fprintf(stderr, "packet buffer too small! (%lu vs %lu)\n", pkt_len, pkt_buf_len); | |
exit(EXIT_FAILURE); | |
} | |
// Packet | |
struct ether_header *ethhdr = (struct ether_header *) pkt; | |
struct iphdr *iphdr = (struct iphdr *) (pkt + ETH_HDRLEN); | |
struct udphdr *udphdr = (struct udphdr *) (pkt + ETH_HDRLEN + IP4_HDRLEN); | |
uint8_t *payload = pkt + hdr_len; | |
// Ethernet header | |
uint8_t mac_dest[] = MAC_DST; | |
ethhdr->ether_dhost[0] = mac_dest[0]; | |
ethhdr->ether_dhost[1] = mac_dest[1]; | |
ethhdr->ether_dhost[2] = mac_dest[2]; | |
ethhdr->ether_dhost[3] = mac_dest[3]; | |
ethhdr->ether_dhost[4] = mac_dest[4]; | |
ethhdr->ether_dhost[5] = mac_dest[5]; | |
uint8_t mac_source[] = MAC_SRC; | |
ethhdr->ether_shost[0] = mac_src[0]; | |
ethhdr->ether_shost[1] = mac_src[1]; | |
ethhdr->ether_shost[2] = mac_src[2]; | |
ethhdr->ether_shost[3] = mac_src[3]; | |
ethhdr->ether_shost[4] = mac_src[4]; | |
ethhdr->ether_shost[5] = mac_src[5]; | |
ethhdr->ether_type = htons(ETH_P_IP); | |
// IPv4 header | |
iphdr->version = 4; | |
iphdr->ihl = 5; | |
iphdr->tos = 0; | |
iphdr->tot_len = htons(IP4_HDRLEN + UDP_HDRLEN + data_len); | |
iphdr->id = htons(8318); | |
iphdr->frag_off = 0; | |
iphdr->ttl = 255; | |
iphdr->protocol = IPPROTO_UDP; | |
iphdr->check = 0; | |
iphdr->saddr = inet_addr(HOST_IP); | |
iphdr->daddr = inet_addr(DEST_IP); | |
// IP Checksum | |
iphdr->check = internet_checksum(pkt + ETH_HDRLEN, IP4_HDRLEN); | |
// UDP header | |
udphdr->source = htons(HOST_PORT); | |
udphdr->dest = htons(DEST_PORT); | |
udphdr->len = htons(UDP_HDRLEN + data_len); | |
udphdr->check = 0; | |
// Payload | |
memcpy (payload, PAYLOAD, data_len); | |
return pkt_len; | |
} | |
int tap_set_sndbuf(int fd) | |
{ | |
int sndbuf = 1024 * 1024; | |
if (ioctl(fd, TUNSETSNDBUF, &sndbuf) < 0) { | |
perror("ioctl(TUNSETSNDBUF)"); | |
return -1; | |
} | |
return 0; | |
} | |
int main(int argc, char* argv[]) | |
{ | |
int err, vtap; | |
uint8_t pkt[IP_MAXPACKET]; | |
size_t pkt_len; | |
if (argc != 2) { | |
usage(argv[0]); | |
exit(EXIT_FAILURE); | |
} | |
// open ('/dev/tap3', ...); | |
if ((vtap = open(argv[1], O_RDWR)) < 0) { | |
perror("Failure to open vtap device"); | |
exit(EXIT_FAILURE); | |
} | |
if (tap_set_sndbuf(vtap) < 0) { | |
exit(EXIT_FAILURE); | |
} | |
// Build packet | |
pkt_len = build_packet(pkt, IP_MAXPACKET); | |
if (pkt_len < 0) { | |
perror("build_packet()"); | |
exit(EXIT_FAILURE); | |
} | |
// Send packet | |
if ((err = write(vtap, pkt, pkt_len)) < 0) { | |
perror("write()"); | |
printf("err: %d\n", errno); | |
exit(EXIT_FAILURE); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment