1
0
mirror of https://code.semirocket.science/wrapsix synced 2024-11-21 13:31:02 +02:00

A bit of code cleanup

This commit is contained in:
Michal Zima 2012-07-03 11:15:10 +02:00
parent 707eb6159b
commit 59fdab7ed8
13 changed files with 159 additions and 68 deletions

View File

@ -115,8 +115,8 @@ int icmp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4,
eth6->type = htons(ETHERTYPE_IPV6); eth6->type = htons(ETHERTYPE_IPV6);
/* build IPv6 packet */ /* build IPv6 packet */
ip6->ver = 0x60; ip6->ver = 0x60 | (ip4->tos >> 4);
ip6->traffic_class = 0x0; ip6->traffic_class = ip4->tos << 4;
ip6->flow_label = 0x0; ip6->flow_label = 0x0;
ip6->len = htons(payload_size); ip6->len = htons(payload_size);
ip6->next_header = IPPROTO_ICMPV6; ip6->next_header = IPPROTO_ICMPV6;
@ -228,7 +228,8 @@ int icmp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
/* build IPv4 packet */ /* build IPv4 packet */
ip4->ver_hdrlen = 0x45; /* ver 4, header length 20 B */ ip4->ver_hdrlen = 0x45; /* ver 4, header length 20 B */
ip4->tos = 0x0; ip4->tos = ((ip6->ver & 0x0f) << 4) |
((ip6->traffic_class & 0xf0) >> 4);
ip4->len = htons(sizeof(struct s_ipv4) + htons(ip6->len)); ip4->len = htons(sizeof(struct s_ipv4) + htons(ip6->len));
ip4->id = 0x0; ip4->id = 0x0;
ip4->flags_offset = htons(IPV4_FLAG_DONT_FRAGMENT); ip4->flags_offset = htons(IPV4_FLAG_DONT_FRAGMENT);
@ -250,7 +251,6 @@ int icmp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
(unsigned char *) icmp); (unsigned char *) icmp);
/* send translated packet */ /* send translated packet */
printf("[Debug] transmitting\n");
transmit_ipv4(&ip4->ip_dest, packet, htons(ip4->len)); transmit_ipv4(&ip4->ip_dest, packet, htons(ip4->len));
/* clean-up */ /* clean-up */
@ -320,8 +320,7 @@ int icmp_ndp(struct s_ethernet *ethq, struct s_ipv6 *ipq,
/* ICMP */ /* ICMP */
icmp->type = ICMPV6_NDP_NA; icmp->type = ICMPV6_NDP_NA;
icmp->code = 0; /* code = checksum = 0 by memset */
icmp->checksum = 0;
/* NDP NA */ /* NDP NA */
ndp_na->flags = INNAF_S; ndp_na->flags = INNAF_S;

View File

@ -26,6 +26,15 @@
#include "udp.h" #include "udp.h"
#include "wrapper.h" #include "wrapper.h"
/**
* Processing of IPv4 packets.
*
* @param eth Ethernet header
* @param packet Packet data
*
* @return 0 for success
* @return 1 for failure
*/
int ipv4(struct s_ethernet *eth, char *packet) int ipv4(struct s_ethernet *eth, char *packet)
{ {
struct s_ipv4 *ip; struct s_ipv4 *ip;
@ -42,8 +51,6 @@ int ipv4(struct s_ethernet *eth, char *packet)
return 1; return 1;
} }
/* TODO: verify checksum */
/* compute sizes and get payload */ /* compute sizes and get payload */
header_size = (ip->ver_hdrlen & 0x0f) * 4; /* # of 4 byte words */ header_size = (ip->ver_hdrlen & 0x0f) * 4; /* # of 4 byte words */
data_size = htons(ip->len) - header_size; data_size = htons(ip->len) - header_size;
@ -52,21 +59,16 @@ int ipv4(struct s_ethernet *eth, char *packet)
switch (ip->proto) { switch (ip->proto) {
case IPPROTO_TCP: case IPPROTO_TCP:
printf("[Debug] IPv4 Protocol: TCP\n"); printf("[Debug] IPv4 Protocol: TCP\n");
tcp_ipv4(eth, ip, payload, data_size); return tcp_ipv4(eth, ip, payload, data_size);
break;
case IPPROTO_UDP: case IPPROTO_UDP:
printf("[Debug] IPv4 Protocol: UDP\n"); printf("[Debug] IPv4 Protocol: UDP\n");
udp_ipv4(eth, ip, payload, data_size); return udp_ipv4(eth, ip, payload, data_size);
break;
case IPPROTO_ICMP: case IPPROTO_ICMP:
printf("[Debug] IPv4 Protocol: ICMP\n"); printf("[Debug] IPv4 Protocol: ICMP\n");
icmp_ipv4(eth, ip, payload, data_size); return icmp_ipv4(eth, ip, payload, data_size);
break;
default: default:
printf("[Debug] IPv4 Protocol: unknown [%d/0x%x]\n", printf("[Debug] IPv4 Protocol: unknown [%d/0x%x]\n",
ip->proto, ip->proto); ip->proto, ip->proto);
return 1; return 1;
} }
return 0;
} }

View File

@ -26,6 +26,15 @@
#include "udp.h" #include "udp.h"
#include "wrapper.h" #include "wrapper.h"
/**
* Processing of IPv6 packets.
*
* @param eth Ethernet header
* @param packet Packet data
*
* @return 0 for success
* @return 1 for failure
*/
int ipv6(struct s_ethernet *eth, char *packet) int ipv6(struct s_ethernet *eth, char *packet)
{ {
struct s_ipv6 *ip; struct s_ipv6 *ip;
@ -45,21 +54,16 @@ int ipv6(struct s_ethernet *eth, char *packet)
switch (ip->next_header) { switch (ip->next_header) {
case IPPROTO_TCP: case IPPROTO_TCP:
printf("[Debug] IPv6 Protocol: TCP\n"); printf("[Debug] IPv6 Protocol: TCP\n");
tcp_ipv6(eth, ip, payload); return tcp_ipv6(eth, ip, payload);
break;
case IPPROTO_UDP: case IPPROTO_UDP:
printf("[Debug] IPv6 Protocol: UDP\n"); printf("[Debug] IPv6 Protocol: UDP\n");
udp_ipv6(eth, ip, payload); return udp_ipv6(eth, ip, payload);
break;
case IPPROTO_ICMPV6: case IPPROTO_ICMPV6:
printf("[Debug] IPv6 Protocol: ICMP\n"); printf("[Debug] IPv6 Protocol: ICMP\n");
icmp_ipv6(eth, ip, payload); return icmp_ipv6(eth, ip, payload);
break;
default: default:
printf("[Debug] IPv6 Protocol: unknown [%d/0x%x]\n", printf("[Debug] IPv6 Protocol: unknown [%d/0x%x]\n",
ip->next_header, ip->next_header); ip->next_header, ip->next_header);
return 1; return 1;
} }
return 0;
} }

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2011 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2012 Michal Zima <xhire@mujmalysvet.cz>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
@ -50,6 +50,9 @@ radixtree_t *nat6_tcp, *nat6_udp, *nat6_icmp,
*nat4_tcp, *nat4_udp, *nat4_icmp, *nat4_tcp, *nat4_udp, *nat4_icmp,
*nat4_tcp_fragments; *nat4_tcp_fragments;
/**
* Initialization of NAT tables.
*/
void nat_init(void) void nat_init(void)
{ {
nat6_tcp = radixtree_create(); nat6_tcp = radixtree_create();
@ -63,6 +66,9 @@ void nat_init(void)
nat4_tcp_fragments = radixtree_create(); nat4_tcp_fragments = radixtree_create();
} }
/**
* Clean-up of NAT tables.
*/
void nat_quit(void) void nat_quit(void)
{ {
/* 128 + 16 + 32 + 16 = 192 / 6 = 32 */ /* 128 + 16 + 32 + 16 = 192 / 6 = 32 */
@ -79,6 +85,20 @@ void nat_quit(void)
radixtree_destroy(nat4_tcp_fragments, 8); radixtree_destroy(nat4_tcp_fragments, 8);
} }
/**
* Lookup or create NAT connection for outgoing IPv6 packet.
*
* @param nat_proto6 IPv6 NAT table
* @param nat_proto4 IPv4 NAT table
* @param eth_src Source MAC address
* @param ipv6_src Source IPv6 address
* @param ipv6_dst Destination IPv6 address
* @param port_src Source port
* @param port_dst Destination port
*
* @return NULL when it wasn't possible to create connection
* @return pointer to connection structure otherwise
*/
struct s_nat *nat_out(radixtree_t *nat_proto6, radixtree_t *nat_proto4, struct s_nat *nat_out(radixtree_t *nat_proto6, radixtree_t *nat_proto4,
struct s_mac_addr eth_src, struct s_mac_addr eth_src,
struct s_ipv6_addr ipv6_src, struct s_ipv6_addr ipv6_dst, struct s_ipv6_addr ipv6_src, struct s_ipv6_addr ipv6_dst,
@ -137,6 +157,17 @@ struct s_nat *nat_out(radixtree_t *nat_proto6, radixtree_t *nat_proto4,
} }
} }
/**
* Lookup NAT connection for incoming IPv4 packet.
*
* @param nat_proto4 NAT table
* @param ipv4_src Source IPv4 address
* @param port_src Source port
* @param port_dst Destination port
*
* @return NULL when no connection was found
* @return pointer to connection structure otherwise
*/
struct s_nat *nat_in(radixtree_t *nat_proto4, struct s_ipv4_addr ipv4_src, struct s_nat *nat_in(radixtree_t *nat_proto4, struct s_ipv4_addr ipv4_src,
unsigned short port_src, unsigned short port_dst) unsigned short port_src, unsigned short port_dst)
{ {
@ -225,8 +256,8 @@ struct s_nat *nat_in_fragments(radixtree_t *nat_proto4,
* @param ipv4_src Source IPv4 address * @param ipv4_src Source IPv4 address
* @param id Fragment identification * @param id Fragment identification
*/ */
void nat_in_fragments_clenup(radixtree_t *nat_proto4, void nat_in_fragments_cleanup(radixtree_t *nat_proto4,
struct s_ipv4_addr ipv4_src, unsigned short id) struct s_ipv4_addr ipv4_src, unsigned short id)
{ {
/* create structure to search in the tree */ /* create structure to search in the tree */
struct s_radixtree_fragments4 radixsearch4; struct s_radixtree_fragments4 radixsearch4;

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2011 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2012 Michal Zima <xhire@mujmalysvet.cz>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
@ -53,7 +53,7 @@ struct s_nat *nat_in(radixtree_t *nat_proto4, struct s_ipv4_addr ipv4_src,
struct s_nat *nat_in_fragments(radixtree_t *nat_proto4, struct s_nat *nat_in_fragments(radixtree_t *nat_proto4,
struct s_ipv4_addr ipv4_src, struct s_ipv4_addr ipv4_src,
unsigned short id, struct s_nat *nat); unsigned short id, struct s_nat *nat);
void nat_in_fragments_clenup(radixtree_t *nat_proto4, void nat_in_fragments_cleanup(radixtree_t *nat_proto4,
struct s_ipv4_addr ipv4_src, unsigned short id); struct s_ipv4_addr ipv4_src, unsigned short id);
#endif /* NAT_H */ #endif /* NAT_H */

View File

@ -22,6 +22,11 @@
#include "radixtree.h" #include "radixtree.h"
/**
* Creates root of radix tree.
*
* @return Root of new radix tree
*/
radixtree_t *radixtree_create(void) radixtree_t *radixtree_create(void)
{ {
radixtree_t *radixtree; radixtree_t *radixtree;
@ -36,21 +41,36 @@ radixtree_t *radixtree_create(void)
return radixtree; return radixtree;
} }
void radixtree_destroy(radixtree_t *t, unsigned char depth) /**
* Destroys a radix tree.
*
* @param root Root of the tree to destroy
* @param depth Depth of the tree
*/
void radixtree_destroy(radixtree_t *root, unsigned char depth)
{ {
unsigned char i; unsigned char i;
for (i = 0; i < ARRAY_SIZE; i++) { for (i = 0; i < ARRAY_SIZE; i++) {
if (depth != 1 && t->array[i] != NULL) { if (depth != 1 && root->array[i] != NULL) {
radixtree_destroy(t->array[i], depth - 1); radixtree_destroy(root->array[i], depth - 1);
} else if (depth == 1) { } else if (depth == 1) {
free(t->array[i]); free(root->array[i]);
} }
} }
free(t); free(root);
} }
/**
* Inserts new data entry into the tree.
*
* @param root Root of the radix tree
* @param chunker Function to use to get chunks for indexing internal array
* @param search_data Key used to search in the tree
* @param size Length of the key
* @param data Data to store in the tree
*/
void radixtree_insert(radixtree_t *root, void radixtree_insert(radixtree_t *root,
unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count), unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count),
void *search_data, unsigned char size, void *data) void *search_data, unsigned char size, void *data)
@ -85,6 +105,14 @@ void radixtree_insert(radixtree_t *root,
free(chunks); free(chunks);
} }
/**
* Deletes an entry from the tree.
*
* @param root Root of the radix tree
* @param chunker Function to use to get chunks for indexing internal array
* @param data Key used to search in the tree
* @param size Length of the key
*/
void radixtree_delete(radixtree_t *root, void radixtree_delete(radixtree_t *root,
unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count), unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count),
void *data, unsigned char size) void *data, unsigned char size)
@ -97,7 +125,7 @@ void radixtree_delete(radixtree_t *root,
chunks = chunker(data, size, &chunk_count); chunks = chunker(data, size, &chunk_count);
for (i = 0, tmp = root; i < chunk_count && tmp != NULL; i++, tmp = tmp->array[chunks[i]]) { for (i = 0, tmp = root; i < chunk_count && tmp != NULL; tmp = tmp->array[chunks[i++]]) {
flags = tmp->count == 1 ? flags | (0x1 << i) : 0; flags = tmp->count == 1 ? flags | (0x1 << i) : 0;
if (i + 1 == chunk_count) { if (i + 1 == chunk_count) {
@ -128,6 +156,14 @@ void radixtree_delete(radixtree_t *root,
free(chunks); free(chunks);
} }
/**
* Lookups an entry in the tree.
*
* @param root Root of the radix tree
* @param chunker Function to use to get chunks for indexing internal array
* @param data Key used to search in the tree
* @param size Length of the key
*/
void *radixtree_lookup(radixtree_t *root, void *radixtree_lookup(radixtree_t *root,
unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count), unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count),
void *data, unsigned char size) void *data, unsigned char size)

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2011 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2012 Michal Zima <xhire@mujmalysvet.cz>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
@ -28,7 +28,7 @@ typedef struct radixtree {
} radixtree_t; } radixtree_t;
radixtree_t *radixtree_create(void); radixtree_t *radixtree_create(void);
void radixtree_destroy(radixtree_t *t, unsigned char depth); void radixtree_destroy(radixtree_t *root, unsigned char depth);
void radixtree_insert(radixtree_t *root, void radixtree_insert(radixtree_t *root,
unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count), unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count),
void *search_data, unsigned char size, void *data); void *search_data, unsigned char size, void *data);

View File

@ -57,12 +57,12 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
struct s_ipv6_fragment *frag; struct s_ipv6_fragment *frag;
/* full processing of unfragmented packet or the first fragment with /* full processing of unfragmented packet or the first fragment with
* TCP header with checksum field (this is safe) * TCP header
*/ */
if ((ip4->flags_offset & htons(IPV4_FLAG_DONT_FRAGMENT)) || if ((ip4->flags_offset & htons(IPV4_FLAG_DONT_FRAGMENT)) ||
((ip4->flags_offset & htons(IPV4_FLAG_MORE_FRAGMENTS)) && ((ip4->flags_offset & htons(IPV4_FLAG_MORE_FRAGMENTS)) &&
(ip4->flags_offset & 0xff1f) == 0x0000 && (ip4->flags_offset & 0xff1f) == 0x0000 &&
payload_size >= sizeof(struct s_tcp) - 2)) { payload_size >= sizeof(struct s_tcp))) {
/* parse TCP header */ /* parse TCP header */
tcp = (struct s_tcp *) payload; tcp = (struct s_tcp *) payload;
@ -249,8 +249,8 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
sizeof(struct s_ipv6_fragment)); sizeof(struct s_ipv6_fragment));
/* fill in missing IPv6 fragment header fields */ /* fill in missing IPv6 fragment header fields */
frag->offset_flag = htons((htons(ip4->flags_offset) << 3) | frag->offset_flag = htons((htons(ip4->flags_offset) <<
IPV6_FLAG_MORE_FRAGMENTS); 3) | IPV6_FLAG_MORE_FRAGMENTS);
/* copy the payload data */ /* copy the payload data */
memcpy((unsigned char *) frag + memcpy((unsigned char *) frag +
@ -264,7 +264,8 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
ip6->len = htons(payload_size + ip6->len = htons(payload_size +
sizeof(struct s_ipv6_fragment) - sizeof(struct s_ipv6_fragment) -
FRAGMENT_LEN); FRAGMENT_LEN);
frag->offset_flag = htons((htons(ip4->flags_offset) + frag->offset_flag = htons(((htons(ip4->flags_offset) &
0xfffc) +
FRAGMENT_LEN / 8) << 3); FRAGMENT_LEN / 8) << 3);
if (ip4->flags_offset & if (ip4->flags_offset &
htons(IPV4_FLAG_MORE_FRAGMENTS)) { htons(IPV4_FLAG_MORE_FRAGMENTS)) {
@ -378,7 +379,8 @@ int tcp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
/* build IPv4 packet */ /* build IPv4 packet */
ip4->ver_hdrlen = 0x45; /* ver 4, header length 20 B */ ip4->ver_hdrlen = 0x45; /* ver 4, header length 20 B */
ip4->tos = 0x0; ip4->tos = ((ip6->ver & 0x0f) << 4) |
((ip6->traffic_class & 0xf0) >> 4);
ip4->len = htons(sizeof(struct s_ipv4) + htons(ip6->len)); ip4->len = htons(sizeof(struct s_ipv4) + htons(ip6->len));
ip4->id = 0x0; ip4->id = 0x0;
ip4->flags_offset = htons(IPV4_FLAG_DONT_FRAGMENT); ip4->flags_offset = htons(IPV4_FLAG_DONT_FRAGMENT);

View File

@ -30,7 +30,6 @@ struct s_tcp {
unsigned char flags; /* 6 b; flags */ unsigned char flags; /* 6 b; flags */
unsigned short window; /* 16 b; size of the receive window */ unsigned short window; /* 16 b; size of the receive window */
unsigned short checksum; /* 16 b */ unsigned short checksum; /* 16 b */
unsigned short urgent_ptr; /* 16 b; ptr to last urgent data byte */
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload, int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,

View File

@ -18,7 +18,8 @@
#include <net/if.h> /* struct ifreq */ #include <net/if.h> /* struct ifreq */
#include <netinet/if_ether.h> /* {P,A}F_PACKET, ETH_P_*, socket, SOCK_RAW, #include <netinet/if_ether.h> /* {P,A}F_PACKET, ETH_P_*, socket, SOCK_RAW,
* setsockopt, SOL_SOCKET, SO_BINDTODEVICE, sendto */ * setsockopt, SOL_SOCKET, SO_BINDTODEVICE,
* sendto */
#include <netinet/in.h> /* htons */ #include <netinet/in.h> /* htons */
#include <netpacket/packet.h> /* sockaddr_ll, PACKET_OTHERHOST */ #include <netpacket/packet.h> /* sockaddr_ll, PACKET_OTHERHOST */
#include <stdio.h> /* fprintf, stderr, perror */ #include <stdio.h> /* fprintf, stderr, perror */
@ -34,7 +35,8 @@ struct sockaddr_in socket_address_ipv4;
int sock, sock_ipv4; int sock, sock_ipv4;
/** /**
* Initialize socket and all needed properties. Should be called only once on program startup. * Initialize sockets and all needed properties. Should be called only once on
* program startup.
* *
* @return 0 for success * @return 0 for success
* @return 1 for failure * @return 1 for failure
@ -45,10 +47,10 @@ int transmission_init(void)
/** RAW socket **/ /** RAW socket **/
/* prepare settings for RAW socket */ /* prepare settings for RAW socket */
socket_address.sll_family = PF_PACKET; /* RAW communication */ socket_address.sll_family = PF_PACKET; /* raw communication */
socket_address.sll_protocol = htons(ETH_P_IP); /* protocol above the ethernet layer */ socket_address.sll_protocol = htons(ETH_P_IP); /* L3 proto */
socket_address.sll_ifindex = interface.ifr_ifindex; /* set index of the network device */ socket_address.sll_ifindex = interface.ifr_ifindex;
socket_address.sll_pkttype = PACKET_OTHERHOST; /* target host is another host */ socket_address.sll_pkttype = PACKET_OTHERHOST;
/* initialize RAW socket */ /* initialize RAW socket */
if ((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) { if ((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {
@ -58,8 +60,10 @@ int transmission_init(void)
} }
/* bind the socket to the interface */ /* bind the socket to the interface */
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &interface, sizeof(struct ifreq)) == -1) { if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &interface,
fprintf(stderr, "[Error] Couldn't bind the socket to the interface.\n"); sizeof(struct ifreq)) == -1) {
fprintf(stderr, "[Error] Couldn't bind the socket to the "
"interface.\n");
perror("setsockopt()"); perror("setsockopt()");
return 1; return 1;
} }
@ -78,8 +82,10 @@ int transmission_init(void)
} }
/* we will provide our own IPv4 header */ /* we will provide our own IPv4 header */
if (setsockopt(sock_ipv4, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) == -1) { if (setsockopt(sock_ipv4, IPPROTO_IP, IP_HDRINCL, &on,
fprintf(stderr, "[Error] Couldn't apply the socket settings.\n"); sizeof(on)) == -1) {
fprintf(stderr, "[Error] Couldn't apply the socket "
"settings.\n");
perror("setsockopt()"); perror("setsockopt()");
return 1; return 1;
} }
@ -88,7 +94,7 @@ int transmission_init(void)
} }
/** /**
* Close socket. Should be called only once on program shutdown. * Close sockets. Should be called only once on program shutdown.
* *
* @return 0 for success * @return 0 for success
* @return 1 for failure * @return 1 for failure
@ -97,7 +103,8 @@ int transmission_quit(void)
{ {
/* close the socket */ /* close the socket */
if (close(sock) || close(sock_ipv4)) { if (close(sock) || close(sock_ipv4)) {
fprintf(stderr, "[Error] Couldn't close the transmission sockets.\n"); fprintf(stderr, "[Error] Couldn't close the transmission "
"sockets.\n");
perror("close()"); perror("close()");
return 1; return 1;
} else { } else {
@ -116,7 +123,8 @@ int transmission_quit(void)
*/ */
int transmit_raw(unsigned char *data, unsigned int length) int transmit_raw(unsigned char *data, unsigned int length)
{ {
if (sendto(sock, data, length, 0, (struct sockaddr *) &socket_address, sizeof(struct sockaddr_ll)) != (int) length) { if (sendto(sock, data, length, 0, (struct sockaddr *) &socket_address,
sizeof(struct sockaddr_ll)) != (int) length) {
fprintf(stderr, "[Error] Couldn't send a RAW packet.\n"); fprintf(stderr, "[Error] Couldn't send a RAW packet.\n");
perror("sendto()"); perror("sendto()");
return 1; return 1;
@ -129,18 +137,23 @@ int transmit_raw(unsigned char *data, unsigned int length)
* Send IPv4 packet with IPv4 header supplied. Ethernet header is added by OS. * Send IPv4 packet with IPv4 header supplied. Ethernet header is added by OS.
* *
* @param ip Destination IPv4 address * @param ip Destination IPv4 address
* @param data Raw packet data, excluding ethernet header, but including IPv4 header * @param data Raw packet data, excluding ethernet header, but
* including IPv4 header
* @param length Length of the whole packet in bytes * @param length Length of the whole packet in bytes
* *
* @return 0 for success * @return 0 for success
* @return 1 for failure * @return 1 for failure
*/ */
int transmit_ipv4(struct s_ipv4_addr *ip, unsigned char *data, unsigned int length) int transmit_ipv4(struct s_ipv4_addr *ip, unsigned char *data,
unsigned int length)
{ {
/* set the destination IPv4 address */ /* set the destination IPv4 address */
memcpy(&socket_address_ipv4.sin_addr.s_addr, ip, sizeof(struct s_ipv4_addr)); memcpy(&socket_address_ipv4.sin_addr.s_addr, ip,
sizeof(struct s_ipv4_addr));
if (sendto(sock_ipv4, data, length, 0, (struct sockaddr *) &socket_address_ipv4, sizeof(struct sockaddr)) != (int) length) { if (sendto(sock_ipv4, data, length, 0,
(struct sockaddr *) &socket_address_ipv4,
sizeof(struct sockaddr)) != (int) length) {
fprintf(stderr, "[Error] Couldn't send an IPv4 packet.\n"); fprintf(stderr, "[Error] Couldn't send an IPv4 packet.\n");
perror("sendto()"); perror("sendto()");
return 1; return 1;

View File

@ -97,8 +97,8 @@ int udp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
eth6->type = htons(ETHERTYPE_IPV6); eth6->type = htons(ETHERTYPE_IPV6);
/* build IPv6 packet */ /* build IPv6 packet */
ip6->ver = 0x60; ip6->ver = 0x60 | (ip4->tos >> 4);
ip6->traffic_class = 0x0; ip6->traffic_class = ip4->tos << 4;
ip6->flow_label = 0x0; ip6->flow_label = 0x0;
ip6->len = htons(payload_size); ip6->len = htons(payload_size);
ip6->next_header = IPPROTO_UDP; ip6->next_header = IPPROTO_UDP;
@ -193,7 +193,8 @@ int udp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
/* build IPv4 packet */ /* build IPv4 packet */
ip4->ver_hdrlen = 0x45; /* ver 4, header length 20 B */ ip4->ver_hdrlen = 0x45; /* ver 4, header length 20 B */
ip4->tos = 0x0; ip4->tos = ((ip6->ver & 0x0f) << 4) |
((ip6->traffic_class & 0xf0) >> 4);
ip4->len = htons(sizeof(struct s_ipv4) + htons(ip6->len)); ip4->len = htons(sizeof(struct s_ipv4) + htons(ip6->len));
ip4->id = 0x0; ip4->id = 0x0;
ip4->flags_offset = htons(IPV4_FLAG_DONT_FRAGMENT); ip4->flags_offset = htons(IPV4_FLAG_DONT_FRAGMENT);

View File

@ -37,10 +37,12 @@
#include "transmitter.h" #include "transmitter.h"
#include "wrapper.h" #include "wrapper.h"
#define INTERFACE "eth0" -/* +++ CONFIGURATION +++ */
#define BUFFER_SIZE 65536 #define INTERFACE "eth0" /* be sure to turn off generic-segmentation-offload! */
#define PREFIX "fd77::" #define PREFIX "64:ff9b::"
#define IPV4_ADDR "192.168.0.111" #define IPV4_ADDR "192.168.0.111"
/* --- CONFIGURATION --- */
struct ifreq interface; struct ifreq interface;
struct s_mac_addr mac; struct s_mac_addr mac;

View File

@ -22,7 +22,9 @@
#include "ipv4.h" #include "ipv4.h"
#include "ipv6.h" #include "ipv6.h"
/* +++ CONFIGURE +++ */
#define MTU 1280 #define MTU 1280
/* --- CONFIGURE --- */
extern struct ifreq interface; extern struct ifreq interface;
extern struct s_mac_addr mac; extern struct s_mac_addr mac;