mirror of
https://code.semirocket.science/wrapsix
synced 2024-11-24 02:06:17 +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);
|
||||
|
||||
/* build IPv6 packet */
|
||||
ip6->ver = 0x60;
|
||||
ip6->traffic_class = 0x0;
|
||||
ip6->ver = 0x60 | (ip4->tos >> 4);
|
||||
ip6->traffic_class = ip4->tos << 4;
|
||||
ip6->flow_label = 0x0;
|
||||
ip6->len = htons(payload_size);
|
||||
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 */
|
||||
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->id = 0x0;
|
||||
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);
|
||||
|
||||
/* send translated packet */
|
||||
printf("[Debug] transmitting\n");
|
||||
transmit_ipv4(&ip4->ip_dest, packet, htons(ip4->len));
|
||||
|
||||
/* clean-up */
|
||||
@ -320,8 +320,7 @@ int icmp_ndp(struct s_ethernet *ethq, struct s_ipv6 *ipq,
|
||||
|
||||
/* ICMP */
|
||||
icmp->type = ICMPV6_NDP_NA;
|
||||
icmp->code = 0;
|
||||
icmp->checksum = 0;
|
||||
/* code = checksum = 0 by memset */
|
||||
|
||||
/* NDP NA */
|
||||
ndp_na->flags = INNAF_S;
|
||||
|
22
src/ipv4.c
22
src/ipv4.c
@ -26,6 +26,15 @@
|
||||
#include "udp.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)
|
||||
{
|
||||
struct s_ipv4 *ip;
|
||||
@ -42,8 +51,6 @@ int ipv4(struct s_ethernet *eth, char *packet)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TODO: verify checksum */
|
||||
|
||||
/* compute sizes and get payload */
|
||||
header_size = (ip->ver_hdrlen & 0x0f) * 4; /* # of 4 byte words */
|
||||
data_size = htons(ip->len) - header_size;
|
||||
@ -52,21 +59,16 @@ int ipv4(struct s_ethernet *eth, char *packet)
|
||||
switch (ip->proto) {
|
||||
case IPPROTO_TCP:
|
||||
printf("[Debug] IPv4 Protocol: TCP\n");
|
||||
tcp_ipv4(eth, ip, payload, data_size);
|
||||
break;
|
||||
return tcp_ipv4(eth, ip, payload, data_size);
|
||||
case IPPROTO_UDP:
|
||||
printf("[Debug] IPv4 Protocol: UDP\n");
|
||||
udp_ipv4(eth, ip, payload, data_size);
|
||||
break;
|
||||
return udp_ipv4(eth, ip, payload, data_size);
|
||||
case IPPROTO_ICMP:
|
||||
printf("[Debug] IPv4 Protocol: ICMP\n");
|
||||
icmp_ipv4(eth, ip, payload, data_size);
|
||||
break;
|
||||
return icmp_ipv4(eth, ip, payload, data_size);
|
||||
default:
|
||||
printf("[Debug] IPv4 Protocol: unknown [%d/0x%x]\n",
|
||||
ip->proto, ip->proto);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
20
src/ipv6.c
20
src/ipv6.c
@ -26,6 +26,15 @@
|
||||
#include "udp.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)
|
||||
{
|
||||
struct s_ipv6 *ip;
|
||||
@ -45,21 +54,16 @@ int ipv6(struct s_ethernet *eth, char *packet)
|
||||
switch (ip->next_header) {
|
||||
case IPPROTO_TCP:
|
||||
printf("[Debug] IPv6 Protocol: TCP\n");
|
||||
tcp_ipv6(eth, ip, payload);
|
||||
break;
|
||||
return tcp_ipv6(eth, ip, payload);
|
||||
case IPPROTO_UDP:
|
||||
printf("[Debug] IPv6 Protocol: UDP\n");
|
||||
udp_ipv6(eth, ip, payload);
|
||||
break;
|
||||
return udp_ipv6(eth, ip, payload);
|
||||
case IPPROTO_ICMPV6:
|
||||
printf("[Debug] IPv6 Protocol: ICMP\n");
|
||||
icmp_ipv6(eth, ip, payload);
|
||||
break;
|
||||
return icmp_ipv6(eth, ip, payload);
|
||||
default:
|
||||
printf("[Debug] IPv6 Protocol: unknown [%d/0x%x]\n",
|
||||
ip->next_header, ip->next_header);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
37
src/nat.c
37
src/nat.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* 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_fragments;
|
||||
|
||||
/**
|
||||
* Initialization of NAT tables.
|
||||
*/
|
||||
void nat_init(void)
|
||||
{
|
||||
nat6_tcp = radixtree_create();
|
||||
@ -63,6 +66,9 @@ void nat_init(void)
|
||||
nat4_tcp_fragments = radixtree_create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean-up of NAT tables.
|
||||
*/
|
||||
void nat_quit(void)
|
||||
{
|
||||
/* 128 + 16 + 32 + 16 = 192 / 6 = 32 */
|
||||
@ -79,6 +85,20 @@ void nat_quit(void)
|
||||
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_mac_addr eth_src,
|
||||
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,
|
||||
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 id Fragment identification
|
||||
*/
|
||||
void nat_in_fragments_clenup(radixtree_t *nat_proto4,
|
||||
struct s_ipv4_addr ipv4_src, unsigned short id)
|
||||
void nat_in_fragments_cleanup(radixtree_t *nat_proto4,
|
||||
struct s_ipv4_addr ipv4_src, unsigned short id)
|
||||
{
|
||||
/* create structure to search in the tree */
|
||||
struct s_radixtree_fragments4 radixsearch4;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* 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_ipv4_addr ipv4_src,
|
||||
unsigned short id, struct s_nat *nat);
|
||||
void nat_in_fragments_clenup(radixtree_t *nat_proto4,
|
||||
struct s_ipv4_addr ipv4_src, unsigned short id);
|
||||
void nat_in_fragments_cleanup(radixtree_t *nat_proto4,
|
||||
struct s_ipv4_addr ipv4_src, unsigned short id);
|
||||
|
||||
#endif /* NAT_H */
|
||||
|
@ -22,6 +22,11 @@
|
||||
|
||||
#include "radixtree.h"
|
||||
|
||||
/**
|
||||
* Creates root of radix tree.
|
||||
*
|
||||
* @return Root of new radix tree
|
||||
*/
|
||||
radixtree_t *radixtree_create(void)
|
||||
{
|
||||
radixtree_t *radixtree;
|
||||
@ -36,21 +41,36 @@ radixtree_t *radixtree_create(void)
|
||||
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;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE; i++) {
|
||||
if (depth != 1 && t->array[i] != NULL) {
|
||||
radixtree_destroy(t->array[i], depth - 1);
|
||||
if (depth != 1 && root->array[i] != NULL) {
|
||||
radixtree_destroy(root->array[i], 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,
|
||||
unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count),
|
||||
void *search_data, unsigned char size, void *data)
|
||||
@ -85,6 +105,14 @@ void radixtree_insert(radixtree_t *root,
|
||||
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,
|
||||
unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count),
|
||||
void *data, unsigned char size)
|
||||
@ -97,7 +125,7 @@ void radixtree_delete(radixtree_t *root,
|
||||
|
||||
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;
|
||||
|
||||
if (i + 1 == chunk_count) {
|
||||
@ -128,6 +156,14 @@ void radixtree_delete(radixtree_t *root,
|
||||
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,
|
||||
unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count),
|
||||
void *data, unsigned char size)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@ -28,7 +28,7 @@ typedef struct radixtree {
|
||||
} radixtree_t;
|
||||
|
||||
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,
|
||||
unsigned char *(chunker)(void *data, unsigned char size, unsigned char *count),
|
||||
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;
|
||||
|
||||
/* 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)) ||
|
||||
((ip4->flags_offset & htons(IPV4_FLAG_MORE_FRAGMENTS)) &&
|
||||
(ip4->flags_offset & 0xff1f) == 0x0000 &&
|
||||
payload_size >= sizeof(struct s_tcp) - 2)) {
|
||||
payload_size >= sizeof(struct s_tcp))) {
|
||||
/* parse TCP header */
|
||||
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));
|
||||
|
||||
/* fill in missing IPv6 fragment header fields */
|
||||
frag->offset_flag = htons((htons(ip4->flags_offset) << 3) |
|
||||
IPV6_FLAG_MORE_FRAGMENTS);
|
||||
frag->offset_flag = htons((htons(ip4->flags_offset) <<
|
||||
3) | IPV6_FLAG_MORE_FRAGMENTS);
|
||||
|
||||
/* copy the payload data */
|
||||
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 +
|
||||
sizeof(struct s_ipv6_fragment) -
|
||||
FRAGMENT_LEN);
|
||||
frag->offset_flag = htons((htons(ip4->flags_offset) +
|
||||
frag->offset_flag = htons(((htons(ip4->flags_offset) &
|
||||
0xfffc) +
|
||||
FRAGMENT_LEN / 8) << 3);
|
||||
if (ip4->flags_offset &
|
||||
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 */
|
||||
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->id = 0x0;
|
||||
ip4->flags_offset = htons(IPV4_FLAG_DONT_FRAGMENT);
|
||||
|
@ -30,7 +30,6 @@ struct s_tcp {
|
||||
unsigned char flags; /* 6 b; flags */
|
||||
unsigned short window; /* 16 b; size of the receive window */
|
||||
unsigned short checksum; /* 16 b */
|
||||
unsigned short urgent_ptr; /* 16 b; ptr to last urgent data byte */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
|
||||
|
@ -18,7 +18,8 @@
|
||||
|
||||
#include <net/if.h> /* struct ifreq */
|
||||
#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 <netpacket/packet.h> /* sockaddr_ll, PACKET_OTHERHOST */
|
||||
#include <stdio.h> /* fprintf, stderr, perror */
|
||||
@ -34,7 +35,8 @@ struct sockaddr_in socket_address_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 1 for failure
|
||||
@ -45,10 +47,10 @@ int transmission_init(void)
|
||||
|
||||
/** RAW socket **/
|
||||
/* prepare settings for RAW socket */
|
||||
socket_address.sll_family = PF_PACKET; /* RAW communication */
|
||||
socket_address.sll_protocol = htons(ETH_P_IP); /* protocol above the ethernet layer */
|
||||
socket_address.sll_ifindex = interface.ifr_ifindex; /* set index of the network device */
|
||||
socket_address.sll_pkttype = PACKET_OTHERHOST; /* target host is another host */
|
||||
socket_address.sll_family = PF_PACKET; /* raw communication */
|
||||
socket_address.sll_protocol = htons(ETH_P_IP); /* L3 proto */
|
||||
socket_address.sll_ifindex = interface.ifr_ifindex;
|
||||
socket_address.sll_pkttype = PACKET_OTHERHOST;
|
||||
|
||||
/* initialize RAW socket */
|
||||
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 */
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &interface, sizeof(struct ifreq)) == -1) {
|
||||
fprintf(stderr, "[Error] Couldn't bind the socket to the interface.\n");
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &interface,
|
||||
sizeof(struct ifreq)) == -1) {
|
||||
fprintf(stderr, "[Error] Couldn't bind the socket to the "
|
||||
"interface.\n");
|
||||
perror("setsockopt()");
|
||||
return 1;
|
||||
}
|
||||
@ -78,8 +82,10 @@ int transmission_init(void)
|
||||
}
|
||||
|
||||
/* we will provide our own IPv4 header */
|
||||
if (setsockopt(sock_ipv4, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) == -1) {
|
||||
fprintf(stderr, "[Error] Couldn't apply the socket settings.\n");
|
||||
if (setsockopt(sock_ipv4, IPPROTO_IP, IP_HDRINCL, &on,
|
||||
sizeof(on)) == -1) {
|
||||
fprintf(stderr, "[Error] Couldn't apply the socket "
|
||||
"settings.\n");
|
||||
perror("setsockopt()");
|
||||
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 1 for failure
|
||||
@ -97,7 +103,8 @@ int transmission_quit(void)
|
||||
{
|
||||
/* close the socket */
|
||||
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()");
|
||||
return 1;
|
||||
} else {
|
||||
@ -116,7 +123,8 @@ int transmission_quit(void)
|
||||
*/
|
||||
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");
|
||||
perror("sendto()");
|
||||
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.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @return 0 for success
|
||||
* @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 */
|
||||
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");
|
||||
perror("sendto()");
|
||||
return 1;
|
||||
|
@ -97,8 +97,8 @@ int udp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
|
||||
eth6->type = htons(ETHERTYPE_IPV6);
|
||||
|
||||
/* build IPv6 packet */
|
||||
ip6->ver = 0x60;
|
||||
ip6->traffic_class = 0x0;
|
||||
ip6->ver = 0x60 | (ip4->tos >> 4);
|
||||
ip6->traffic_class = ip4->tos << 4;
|
||||
ip6->flow_label = 0x0;
|
||||
ip6->len = htons(payload_size);
|
||||
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 */
|
||||
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->id = 0x0;
|
||||
ip4->flags_offset = htons(IPV4_FLAG_DONT_FRAGMENT);
|
||||
|
@ -37,10 +37,12 @@
|
||||
#include "transmitter.h"
|
||||
#include "wrapper.h"
|
||||
|
||||
#define INTERFACE "eth0"
|
||||
#define BUFFER_SIZE 65536
|
||||
#define PREFIX "fd77::"
|
||||
-/* +++ CONFIGURATION +++ */
|
||||
#define INTERFACE "eth0" /* be sure to turn off generic-segmentation-offload! */
|
||||
#define PREFIX "64:ff9b::"
|
||||
#define IPV4_ADDR "192.168.0.111"
|
||||
/* --- CONFIGURATION --- */
|
||||
|
||||
|
||||
struct ifreq interface;
|
||||
struct s_mac_addr mac;
|
||||
|
@ -22,7 +22,9 @@
|
||||
#include "ipv4.h"
|
||||
#include "ipv6.h"
|
||||
|
||||
/* +++ CONFIGURE +++ */
|
||||
#define MTU 1280
|
||||
/* --- CONFIGURE --- */
|
||||
|
||||
extern struct ifreq interface;
|
||||
extern struct s_mac_addr mac;
|
||||
|
Loading…
Reference in New Issue
Block a user