mirror of
https://code.semirocket.science/wrapsix
synced 2024-11-21 21:41:07 +02:00
A bit of code cleanup
This commit is contained in:
parent
707eb6159b
commit
59fdab7ed8
11
src/icmp.c
11
src/icmp.c
@ -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;
|
||||||
|
22
src/ipv4.c
22
src/ipv4.c
@ -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;
|
|
||||||
}
|
}
|
||||||
|
20
src/ipv6.c
20
src/ipv6.c
@ -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;
|
|
||||||
}
|
}
|
||||||
|
35
src/nat.c
35
src/nat.c
@ -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,7 +256,7 @@ 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 */
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
14
src/tcp.c
14
src/tcp.c
@ -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);
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user