1
0
mirror of https://code.semirocket.science/wrapsix synced 2024-09-19 23:11:04 +03:00

Migrate to static allocations

Use consistent types (char instead of unsigned char)
...and syntax too
This commit is contained in:
xHire 2017-05-06 14:21:20 +02:00
parent b645beaae3
commit e8924ec64e
11 changed files with 186 additions and 299 deletions

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2012 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2017 xHire <xhire@wrapsix.org>
* *
* 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 General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,14 +18,15 @@
#include <net/ethernet.h> /* ETHERTYPE_* */ #include <net/ethernet.h> /* ETHERTYPE_* */
#include <netinet/in.h> /* htons */ #include <netinet/in.h> /* htons */
#include <stdlib.h> /* malloc */ #include <string.h> /* memcmp */
#include <string.h> /* memcmp, memset */
#include "arp.h" #include "arp.h"
#include "log.h" #include "log.h"
#include "transmitter.h" #include "transmitter.h"
#include "wrapper.h" #include "wrapper.h"
#define ARP_PACKET_SIZE sizeof(struct s_ethernet) + sizeof(struct s_arp)
/** /**
* Process ARP packets and reply to them. * Process ARP packets and reply to them.
* *
@ -39,7 +40,7 @@ int arp(struct s_ethernet *ethq, char *payload)
{ {
struct s_arp *arpq, *arpr; /* request and reply */ struct s_arp *arpq, *arpr; /* request and reply */
struct s_ethernet *ethr; struct s_ethernet *ethr;
unsigned char *packet; char packet[ARP_PACKET_SIZE];
arpq = (struct s_arp *) payload; arpq = (struct s_arp *) payload;
@ -55,16 +56,6 @@ int arp(struct s_ethernet *ethq, char *payload)
return 1; return 1;
} }
/* compute the packet size */
#define ARP_PACKET_SIZE sizeof(struct s_ethernet) + sizeof(struct s_arp)
/* allocate enough memory */
if ((packet = (unsigned char *) malloc(ARP_PACKET_SIZE)) == NULL) {
log_error("Lack of free memory");
return 1;
}
memset(packet, 0x0, ARP_PACKET_SIZE);
/* define ethernet header and ARP offsets */ /* define ethernet header and ARP offsets */
ethr = (struct s_ethernet *) packet; ethr = (struct s_ethernet *) packet;
arpr = (struct s_arp *) (packet + sizeof(struct s_ethernet)); arpr = (struct s_arp *) (packet + sizeof(struct s_ethernet));

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2013 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2017 xHire <xhire@wrapsix.org>
* *
* 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 General Public License as published by * it under the terms of the GNU General Public License as published by
@ -17,13 +17,13 @@
*/ */
#include <netinet/in.h> /* htonl */ #include <netinet/in.h> /* htonl */
#include <stdlib.h> /* malloc */
#include <string.h> /* memcpy */ #include <string.h> /* memcpy */
#include "checksum.h" #include "checksum.h"
#include "ipv4.h" #include "ipv4.h"
#include "ipv6.h" #include "ipv6.h"
#include "log.h" #include "log.h"
#include "wrapper.h"
/** /**
* General checksum computation function. * General checksum computation function.
@ -49,9 +49,9 @@ unsigned short checksum(const void *data, int length)
} }
if (length) { if (length) {
unsigned char temp[2]; char temp[2];
temp[0] = *(unsigned char *) buf; temp[0] = *(char *) buf;
temp[1] = 0; temp[1] = 0;
sum += *(unsigned short *) temp; sum += *(unsigned short *) temp;
@ -121,16 +121,10 @@ unsigned short checksum_update(unsigned short old_sum,
unsigned short checksum_ipv4(struct s_ipv4_addr ip_src, unsigned short checksum_ipv4(struct s_ipv4_addr ip_src,
struct s_ipv4_addr ip_dest, struct s_ipv4_addr ip_dest,
unsigned short length, unsigned char proto, unsigned short length, unsigned char proto,
unsigned char *payload) char *payload)
{ {
unsigned char *buffer; char buffer[PACKET_BUFFER];
struct s_ipv4_pseudo *header; struct s_ipv4_pseudo *header;
unsigned short sum;
if ((buffer = malloc(sizeof(struct s_ipv4_pseudo) + length)) == NULL) {
log_error("Lack of free memory");
return 0;
}
header = (struct s_ipv4_pseudo *) buffer; header = (struct s_ipv4_pseudo *) buffer;
@ -142,11 +136,7 @@ unsigned short checksum_ipv4(struct s_ipv4_addr ip_src,
memcpy(buffer + sizeof(struct s_ipv4_pseudo), payload, (int) length); memcpy(buffer + sizeof(struct s_ipv4_pseudo), payload, (int) length);
sum = checksum(buffer, sizeof(struct s_ipv4_pseudo) + (int) length); return checksum(buffer, sizeof(struct s_ipv4_pseudo) + (int) length);
free(buffer);
return sum;
} }
/** /**
@ -163,16 +153,10 @@ unsigned short checksum_ipv4(struct s_ipv4_addr ip_src,
unsigned short checksum_ipv6(struct s_ipv6_addr ip_src, unsigned short checksum_ipv6(struct s_ipv6_addr ip_src,
struct s_ipv6_addr ip_dest, struct s_ipv6_addr ip_dest,
unsigned short length, unsigned char proto, unsigned short length, unsigned char proto,
unsigned char *payload) char *payload)
{ {
unsigned char *buffer; char buffer[PACKET_BUFFER];
struct s_ipv6_pseudo *header; struct s_ipv6_pseudo *header;
unsigned short sum;
if ((buffer = malloc(sizeof(struct s_ipv6_pseudo) + length)) == NULL) {
log_error("Lack of free memory");
return 0;
}
header = (struct s_ipv6_pseudo *) buffer; header = (struct s_ipv6_pseudo *) buffer;
@ -184,11 +168,7 @@ unsigned short checksum_ipv6(struct s_ipv6_addr ip_src,
memcpy(buffer + sizeof(struct s_ipv6_pseudo), payload, (int) length); memcpy(buffer + sizeof(struct s_ipv6_pseudo), payload, (int) length);
sum = checksum(buffer, sizeof(struct s_ipv6_pseudo) + (int) length); return checksum(buffer, sizeof(struct s_ipv6_pseudo) + (int) length);
free(buffer);
return sum;
} }
/** /**

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2012 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2017 xHire <xhire@wrapsix.org>
* *
* 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 General Public License as published by * it under the terms of the GNU General Public License as published by
@ -28,10 +28,10 @@ unsigned short checksum_update(unsigned short old_sum,
unsigned short *new_data, short new_len); unsigned short *new_data, short new_len);
unsigned short checksum_ipv4(struct s_ipv4_addr ip_src, unsigned short checksum_ipv4(struct s_ipv4_addr ip_src,
struct s_ipv4_addr ip_dest, unsigned short length, struct s_ipv4_addr ip_dest, unsigned short length,
unsigned char proto, unsigned char *payload); unsigned char proto, char *payload);
unsigned short checksum_ipv6(struct s_ipv6_addr ip_src, unsigned short checksum_ipv6(struct s_ipv6_addr ip_src,
struct s_ipv6_addr ip_dest, unsigned short length, struct s_ipv6_addr ip_dest, unsigned short length,
unsigned char proto, unsigned char *payload); unsigned char proto, char *payload);
unsigned short checksum_ipv4_update(unsigned short old_sum, unsigned short checksum_ipv4_update(unsigned short old_sum,
struct s_ipv6_addr ip6_src, struct s_ipv6_addr ip6_src,
struct s_ipv6_addr ip6_dest, struct s_ipv6_addr ip6_dest,

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2013 xHire <xhire@wrapsix.org> * Copyright (C) 2008-2017 xHire <xhire@wrapsix.org>
* *
* 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 General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,7 +18,6 @@
#include <net/ethernet.h> /* ETHERTYPE_* */ #include <net/ethernet.h> /* ETHERTYPE_* */
#include <netinet/in.h> /* htons */ #include <netinet/in.h> /* htons */
#include <stdlib.h> /* malloc */
#include <string.h> /* memcpy, memset */ #include <string.h> /* memcpy, memset */
#include "checksum.h" #include "checksum.h"
@ -33,12 +32,12 @@
#include "wrapper.h" #include "wrapper.h"
/* declarations */ /* declarations */
int sub_icmp4_error(unsigned char *payload, unsigned short payload_size, int sub_icmp4_error(char *payload, unsigned short payload_size,
unsigned char *packet, unsigned short *packet_len, char *packet, unsigned short *packet_len,
struct s_icmp **icmp, struct s_nat **connection); struct s_icmp **icmp, struct s_nat **connection);
int sub_icmp6_error(struct s_ethernet *eth6, int sub_icmp6_error(struct s_ethernet *eth6,
unsigned char *payload, unsigned short payload_size, char *payload, unsigned short payload_size,
unsigned char *packet, unsigned short *packet_len, char *packet, unsigned short *packet_len,
struct s_icmp **icmp, struct s_nat **connection); struct s_icmp **icmp, struct s_nat **connection);
/** /**
@ -60,11 +59,11 @@ int icmp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4,
struct s_icmp *icmp; struct s_icmp *icmp;
unsigned int *icmp_extra; unsigned int *icmp_extra;
unsigned short *icmp_extra_s; unsigned short *icmp_extra_s;
unsigned char *icmp_extra_c; char *icmp_extra_c;
unsigned char *icmp_data; char *icmp_data;
struct s_nat *connection; struct s_nat *connection;
unsigned short orig_checksum; unsigned short orig_checksum;
unsigned char packet[PACKET_BUFFER]; char packet[PACKET_BUFFER];
unsigned short new_len = sizeof(struct s_ethernet) + unsigned short new_len = sizeof(struct s_ethernet) +
sizeof(struct s_ipv6); sizeof(struct s_ipv6);
@ -83,12 +82,12 @@ int icmp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4,
} }
icmp = (struct s_icmp *) payload; icmp = (struct s_icmp *) payload;
icmp_data = (unsigned char *) (payload + sizeof(struct s_icmp)); icmp_data = payload + sizeof(struct s_icmp);
/* ICMP checksum recheck */ /* ICMP checksum recheck */
orig_checksum = icmp->checksum; orig_checksum = icmp->checksum;
icmp->checksum = 0; icmp->checksum = 0;
icmp->checksum = checksum((unsigned char *) icmp, payload_size); icmp->checksum = checksum((char *) icmp, payload_size);
if (icmp->checksum != orig_checksum) { if (icmp->checksum != orig_checksum) {
/* packet is corrupted and shouldn't be processed */ /* packet is corrupted and shouldn't be processed */
@ -120,13 +119,13 @@ int icmp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4,
/* copy the payload data */ /* copy the payload data */
if (payload_size < mtu - sizeof(struct s_ipv6)) { if (payload_size < mtu - sizeof(struct s_ipv6)) {
memcpy(&packet[new_len], payload, payload_size); memcpy(packet + new_len, payload, payload_size);
icmp = (struct s_icmp *) &packet[new_len]; icmp = (struct s_icmp *) (packet + new_len);
new_len += payload_size; new_len += payload_size;
} else { } else {
memcpy(&packet[new_len], payload, mtu - memcpy(packet + new_len, payload, mtu -
sizeof(struct s_ipv6)); sizeof(struct s_ipv6));
icmp = (struct s_icmp *) &packet[new_len]; icmp = (struct s_icmp *) (packet + new_len);
new_len += mtu - sizeof(struct s_ipv6); new_len += mtu - sizeof(struct s_ipv6);
} }
@ -142,17 +141,17 @@ int icmp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4,
} }
eip4 = (struct s_ipv4 *) (icmp_data + 4); eip4 = (struct s_ipv4 *) (icmp_data + 4);
eip6 = (struct s_ipv6 *) &packet[ eip6 = (struct s_ipv6 *) (packet +
sizeof(struct s_ethernet) + sizeof(struct s_ethernet) +
sizeof(struct s_ipv6) + sizeof(struct s_ipv6) +
sizeof(struct s_icmp) + 4]; sizeof(struct s_icmp) + 4);
/* translate ICMP type&code */ /* translate ICMP type&code */
if (icmp->code == 2) { if (icmp->code == 2) {
icmp->type = ICMPV6_PARAM_PROBLEM; icmp->type = ICMPV6_PARAM_PROBLEM;
icmp->code = 1; icmp->code = 1;
icmp_extra = (unsigned int *) icmp_extra = (unsigned int *)
(((unsigned char *) icmp) + ((char *) icmp +
sizeof(struct s_icmp)); sizeof(struct s_icmp));
if (eip6->next_header == if (eip6->next_header ==
IPPROTO_FRAGMENT) { IPPROTO_FRAGMENT) {
@ -166,10 +165,10 @@ int icmp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4,
icmp->type = ICMPV6_PKT_TOO_BIG; icmp->type = ICMPV6_PKT_TOO_BIG;
icmp->code = 0; icmp->code = 0;
icmp_extra = (unsigned int *) icmp_extra = (unsigned int *)
(((unsigned char *) icmp) + ((char *) icmp +
sizeof(struct s_icmp)); sizeof(struct s_icmp));
icmp_extra_s = (unsigned short *) icmp_extra_s = (unsigned short *)
(((unsigned char *) icmp) + ((char *) icmp +
sizeof(struct s_icmp) + 2); sizeof(struct s_icmp) + 2);
if (ntohs(*icmp_extra_s) < 68) { if (ntohs(*icmp_extra_s) < 68) {
*icmp_extra = htonl( *icmp_extra = htonl(
@ -240,9 +239,9 @@ int icmp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4,
if (icmp->code == 0 || icmp->code == 2) { if (icmp->code == 0 || icmp->code == 2) {
/* update the extra field */ /* update the extra field */
icmp_extra = (unsigned int *) icmp_extra = (unsigned int *)
(((unsigned char *) icmp) + ((char *) icmp +
sizeof(struct s_icmp)); sizeof(struct s_icmp));
icmp_extra_c = (unsigned char *) icmp_extra; icmp_extra_c = (char *) icmp_extra;
switch (*icmp_extra_c) { switch (*icmp_extra_c) {
case 0: case 0:
case 1: case 1:
@ -306,7 +305,7 @@ int icmp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4,
} }
eth6 = (struct s_ethernet *) packet; eth6 = (struct s_ethernet *) packet;
ip6 = (struct s_ipv6 *) &packet[sizeof(struct s_ethernet)]; ip6 = (struct s_ipv6 *) (packet + sizeof(struct s_ethernet));
/* build ethernet header */ /* build ethernet header */
eth6->dest = connection->mac; eth6->dest = connection->mac;
@ -329,7 +328,7 @@ int icmp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4,
icmp->checksum = checksum_ipv6(ip6->ip_src, ip6->ip_dest, new_len - icmp->checksum = checksum_ipv6(ip6->ip_src, ip6->ip_dest, new_len -
sizeof(struct s_ethernet) - sizeof(struct s_ethernet) -
sizeof(struct s_ipv6), IPPROTO_ICMPV6, sizeof(struct s_ipv6), IPPROTO_ICMPV6,
(unsigned char *) icmp); (char *) icmp);
/* send translated packet */ /* send translated packet */
transmit_raw(packet, new_len); transmit_raw(packet, new_len);
@ -353,12 +352,12 @@ int icmp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
struct s_icmp *icmp; struct s_icmp *icmp;
unsigned int *icmp_extra; unsigned int *icmp_extra;
unsigned short *icmp_extra_s; unsigned short *icmp_extra_s;
unsigned char *icmp_extra_c; char *icmp_extra_c;
unsigned char *icmp_data; char *icmp_data;
struct s_nat *connection; struct s_nat *connection;
unsigned short orig_checksum; unsigned short orig_checksum;
unsigned short payload_size; unsigned short payload_size;
unsigned char packet[PACKET_BUFFER - sizeof(struct s_ethernet)]; char packet[PACKET_BUFFER - sizeof(struct s_ethernet)];
unsigned short new_len = sizeof(struct s_ipv4); unsigned short new_len = sizeof(struct s_ipv4);
struct s_icmp_echo *echo; struct s_icmp_echo *echo;
@ -374,14 +373,14 @@ int icmp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
} }
icmp = (struct s_icmp *) payload; icmp = (struct s_icmp *) payload;
icmp_data = (unsigned char *) (payload + sizeof(struct s_icmp)); icmp_data = payload + sizeof(struct s_icmp);
/* checksum recheck */ /* checksum recheck */
orig_checksum = icmp->checksum; orig_checksum = icmp->checksum;
icmp->checksum = 0; icmp->checksum = 0;
icmp->checksum = checksum_ipv6(ip6->ip_src, ip6->ip_dest, icmp->checksum = checksum_ipv6(ip6->ip_src, ip6->ip_dest,
payload_size, IPPROTO_ICMPV6, payload_size, IPPROTO_ICMPV6,
(unsigned char *) icmp); (char *) icmp);
if (icmp->checksum != orig_checksum) { if (icmp->checksum != orig_checksum) {
/* packet is corrupted and shouldn't be processed */ /* packet is corrupted and shouldn't be processed */
@ -418,17 +417,18 @@ int icmp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
/* override information in original ICMP header */ /* override information in original ICMP header */
icmp->type = ICMPV4_ECHO_REQUEST; icmp->type = ICMPV4_ECHO_REQUEST;
icmp = (struct s_icmp *) (packet + new_len);
/* copy the payload data */ /* copy the payload data */
/* IPv6 node can handle too big packets itself */ /* IPv6 node can handle too big packets itself */
if (payload_size < 1500 - sizeof(struct s_ipv4)) { if (payload_size < 1500 - sizeof(struct s_ipv4)) {
memcpy(&packet[new_len], payload, payload_size); memcpy(icmp, payload, payload_size);
icmp = (struct s_icmp *) &packet[new_len];
new_len += payload_size; new_len += payload_size;
} else { } else {
memcpy(&packet[new_len], payload, 1500 - memcpy(icmp, payload,
sizeof(struct s_ipv4)); 1500 - sizeof(struct s_ipv4));
icmp = (struct s_icmp *) &packet[new_len]; /* before new_len was only the size of s_ipv4 */
new_len += 1500 - sizeof(struct s_ipv4); new_len = 1500;
} }
break; break;
@ -497,9 +497,9 @@ int icmp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
/* update the extra field */ /* update the extra field */
icmp_extra = (unsigned int *) icmp_extra = (unsigned int *)
(((unsigned char *) icmp) + ((char *) icmp +
sizeof(struct s_icmp)); sizeof(struct s_icmp));
icmp_extra_c = (unsigned char *) icmp_extra; icmp_extra_c = (char *) icmp_extra;
switch (*icmp_extra) { switch (*icmp_extra) {
case 0: case 0:
case 1: case 1:
@ -572,11 +572,9 @@ int icmp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
icmp->code = 4; icmp->code = 4;
icmp_extra = (unsigned int *) icmp_extra = (unsigned int *)
(((unsigned char *) icmp) + ((char *) icmp + sizeof(struct s_icmp));
sizeof(struct s_icmp));
icmp_extra_s = (unsigned short *) icmp_extra_s = (unsigned short *)
(((unsigned char *) icmp) + ((char *) icmp + sizeof(struct s_icmp) + 2);
sizeof(struct s_icmp) + 2);
if (eip6->next_header != IPPROTO_FRAGMENT) { if (eip6->next_header != IPPROTO_FRAGMENT) {
*icmp_extra_s = htons(ntohl(*icmp_extra) - 20); *icmp_extra_s = htons(ntohl(*icmp_extra) - 20);
} else { } else {
@ -617,13 +615,12 @@ int icmp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
/* compute ICMP checksum */ /* compute ICMP checksum */
icmp->checksum = 0x0; icmp->checksum = 0x0;
icmp->checksum = checksum((unsigned char *) icmp, new_len - icmp->checksum = checksum((char *) icmp, new_len -
sizeof(struct s_ipv4)); sizeof(struct s_ipv4));
/* compute IPv4 checksum */ /* compute IPv4 checksum */
ip4->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest, ip4->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest,
new_len, IPPROTO_ICMP, new_len, IPPROTO_ICMP, (char *) icmp);
(unsigned char *) icmp);
/* send translated packet */ /* send translated packet */
transmit_ipv4(&ip4->ip_dest, packet, new_len); transmit_ipv4(&ip4->ip_dest, packet, new_len);
@ -644,7 +641,7 @@ int icmp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
int icmp_ndp(struct s_ethernet *ethq, struct s_ipv6 *ipq, int icmp_ndp(struct s_ethernet *ethq, struct s_ipv6 *ipq,
struct s_icmp_ndp_ns *ndp_ns) struct s_icmp_ndp_ns *ndp_ns)
{ {
unsigned char *packet; char packet[PACKET_BUFFER];
struct s_ethernet *ethr; struct s_ethernet *ethr;
struct s_ipv6 *ipr; struct s_ipv6 *ipr;
struct s_icmp *icmp; struct s_icmp *icmp;
@ -655,15 +652,11 @@ int icmp_ndp(struct s_ethernet *ethq, struct s_ipv6 *ipq,
return 1; return 1;
} }
/* allocate memory for reply packet */ /* prepare memory for reply packet */
#define NDP_PACKET_SIZE sizeof(struct s_ethernet) + \ #define NDP_PACKET_SIZE sizeof(struct s_ethernet) + \
sizeof(struct s_ipv6) + \ sizeof(struct s_ipv6) + \
sizeof(struct s_icmp) + \ sizeof(struct s_icmp) + \
sizeof(struct s_icmp_ndp_na) sizeof(struct s_icmp_ndp_na)
if ((packet = (unsigned char *) malloc(NDP_PACKET_SIZE)) == NULL) {
log_error("Lack of free memory");
return 1;
}
memset(packet, 0x0, NDP_PACKET_SIZE); memset(packet, 0x0, NDP_PACKET_SIZE);
/* divide reply packet into parts */ /* divide reply packet into parts */
@ -703,14 +696,11 @@ int icmp_ndp(struct s_ethernet *ethq, struct s_ipv6 *ipq,
/* compute ICMP checksum */ /* compute ICMP checksum */
icmp->checksum = checksum_ipv6(ipr->ip_src, ipr->ip_dest, icmp->checksum = checksum_ipv6(ipr->ip_src, ipr->ip_dest,
htons(ipr->len), IPPROTO_ICMPV6, htons(ipr->len), IPPROTO_ICMPV6,
(unsigned char *) icmp); (char *) icmp);
/* send NDP reply */ /* send NDP reply */
transmit_raw(packet, NDP_PACKET_SIZE); transmit_raw(packet, NDP_PACKET_SIZE);
/* clean-up */
free(packet);
return 0; return 0;
} }
@ -727,12 +717,13 @@ int icmp_ndp(struct s_ethernet *ethq, struct s_ipv6 *ipq,
* @return 1 for failure * @return 1 for failure
*/ */
int icmp4_error(struct s_ipv4_addr ip_dest, unsigned char type, int icmp4_error(struct s_ipv4_addr ip_dest, unsigned char type,
unsigned char code, unsigned char *data, unsigned short length) unsigned char code, char *data, unsigned short length)
{ {
unsigned char *packet, *payload; char packet[PACKET_BUFFER];
unsigned int *unused; char *payload;
struct s_ipv4 *ip4; unsigned int *unused;
struct s_icmp *icmp; struct s_ipv4 *ip4;
struct s_icmp *icmp;
/* 4 = unused space after ICMP header */ /* 4 = unused space after ICMP header */
unsigned short payload_size = length > 1500 - sizeof(struct s_ipv4) - unsigned short payload_size = length > 1500 - sizeof(struct s_ipv4) -
@ -740,18 +731,11 @@ int icmp4_error(struct s_ipv4_addr ip_dest, unsigned char type,
1500 - sizeof(struct s_ipv4) - sizeof(struct s_icmp) - 4 : 1500 - sizeof(struct s_ipv4) - sizeof(struct s_icmp) - 4 :
length; length;
if ((packet = (unsigned char *) malloc(sizeof(struct s_ipv4) +
sizeof(struct s_icmp) + 4 + payload_size)) == NULL) {
log_error("Lack of free memory");
return 1;
}
ip4 = (struct s_ipv4 *) packet; ip4 = (struct s_ipv4 *) packet;
icmp = (struct s_icmp *) (packet + sizeof(struct s_ipv4)); icmp = (struct s_icmp *) (packet + sizeof(struct s_ipv4));
unused = (unsigned int *) (packet + sizeof(struct s_ipv4) + unused = (unsigned int *) (packet + sizeof(struct s_ipv4) +
sizeof(struct s_icmp)); sizeof(struct s_icmp));
payload = (unsigned char *) (packet + sizeof(struct s_ipv4) + payload = packet + sizeof(struct s_ipv4) + sizeof(struct s_icmp) + 4;
sizeof(struct s_icmp) + 4);
/* 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 */
@ -777,20 +761,17 @@ int icmp4_error(struct s_ipv4_addr ip_dest, unsigned char type,
memcpy(payload, data, payload_size); memcpy(payload, data, payload_size);
/* compute ICMP checksum */ /* compute ICMP checksum */
icmp->checksum = checksum((unsigned char *) icmp, icmp->checksum = checksum((char *) icmp,
payload_size + 4 + sizeof(struct s_icmp)); payload_size + 4 + sizeof(struct s_icmp));
/* compute IPv4 checksum */ /* compute IPv4 checksum */
ip4->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest, ip4->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest,
htons(ip4->len), IPPROTO_ICMP, htons(ip4->len), IPPROTO_ICMP,
(unsigned char *) icmp); (char *) icmp);
/* send packet */ /* send packet */
transmit_ipv4(&ip4->ip_dest, packet, htons(ip4->len)); transmit_ipv4(&ip4->ip_dest, packet, htons(ip4->len));
/* clean-up */
free(packet);
return 0; return 0;
} }
@ -808,14 +789,15 @@ int icmp4_error(struct s_ipv4_addr ip_dest, unsigned char type,
* @return 1 for failure * @return 1 for failure
*/ */
int icmp6_error(struct s_mac_addr mac_dest, struct s_ipv6_addr ip_dest, int icmp6_error(struct s_mac_addr mac_dest, struct s_ipv6_addr ip_dest,
unsigned char type, unsigned char code, unsigned char *data, unsigned char type, unsigned char code, char *data,
unsigned short length) unsigned short length)
{ {
unsigned char *packet, *payload; char packet[PACKET_BUFFER];
unsigned int *unused; char *payload;
unsigned int *unused;
struct s_ethernet *eth; struct s_ethernet *eth;
struct s_ipv6 *ip6; struct s_ipv6 *ip6;
struct s_icmp *icmp; struct s_icmp *icmp;
/* 4 = unused space after ICMP header */ /* 4 = unused space after ICMP header */
/* 1280 -- because RFC on ICMPv6 says so */ /* 1280 -- because RFC on ICMPv6 says so */
@ -824,13 +806,6 @@ int icmp6_error(struct s_mac_addr mac_dest, struct s_ipv6_addr ip_dest,
1280 - sizeof(struct s_ipv6) - sizeof(struct s_icmp) - 4 : 1280 - sizeof(struct s_ipv6) - sizeof(struct s_icmp) - 4 :
length; length;
if ((packet = (unsigned char *) malloc(sizeof(struct s_ethernet) +
sizeof(struct s_ipv6) + sizeof(struct s_icmp) + 4 +
payload_size)) == NULL) {
log_error("Lack of free memory");
return 1;
}
eth = (struct s_ethernet *) packet; eth = (struct s_ethernet *) packet;
ip6 = (struct s_ipv6 *) (packet + sizeof(struct s_ethernet)); ip6 = (struct s_ipv6 *) (packet + sizeof(struct s_ethernet));
icmp = (struct s_icmp *) (packet + sizeof(struct s_ethernet) + icmp = (struct s_icmp *) (packet + sizeof(struct s_ethernet) +
@ -838,9 +813,8 @@ int icmp6_error(struct s_mac_addr mac_dest, struct s_ipv6_addr ip_dest,
unused = (unsigned int *) (packet + sizeof(struct s_ethernet) + unused = (unsigned int *) (packet + sizeof(struct s_ethernet) +
sizeof(struct s_ipv6) + sizeof(struct s_ipv6) +
sizeof(struct s_icmp)); sizeof(struct s_icmp));
payload = (unsigned char *) (packet + sizeof(struct s_ethernet) + payload = packet + sizeof(struct s_ethernet) + sizeof(struct s_ipv6) +
sizeof(struct s_ipv6) + sizeof(struct s_icmp) + 4;
sizeof(struct s_icmp) + 4);
/* ethernet */ /* ethernet */
eth->dest = mac_dest; eth->dest = mac_dest;
@ -869,16 +843,12 @@ int icmp6_error(struct s_mac_addr mac_dest, struct s_ipv6_addr ip_dest,
/* compute ICMP checksum */ /* compute ICMP checksum */
icmp->checksum = checksum_ipv6(host_ipv6_addr, ip_dest, icmp->checksum = checksum_ipv6(host_ipv6_addr, ip_dest,
sizeof(struct s_icmp) + 4 + payload_size, sizeof(struct s_icmp) + 4 + payload_size,
IPPROTO_ICMPV6, IPPROTO_ICMPV6, (char *) icmp);
(unsigned char *) icmp);
/* send packet */ /* send packet */
transmit_raw(packet, sizeof(struct s_ethernet) + sizeof(struct s_ipv6) + transmit_raw(packet, sizeof(struct s_ethernet) + sizeof(struct s_ipv6) +
sizeof(struct s_icmp) + 4 + payload_size); sizeof(struct s_icmp) + 4 + payload_size);
/* clean-up */
free(packet);
return 0; return 0;
} }
@ -895,18 +865,18 @@ int icmp6_error(struct s_mac_addr mac_dest, struct s_ipv6_addr ip_dest,
* @return 0 for success * @return 0 for success
* @return 1 for failure * @return 1 for failure
*/ */
int sub_icmp4_error(unsigned char *payload, unsigned short payload_size, int sub_icmp4_error(char *payload, unsigned short payload_size,
unsigned char *packet, unsigned short *packet_len, char *packet, unsigned short *packet_len,
struct s_icmp **icmp, struct s_nat **connection) struct s_icmp **icmp, struct s_nat **connection)
{ {
struct s_ipv4 *eip4; struct s_ipv4 *eip4;
struct s_ipv6 *eip6; struct s_ipv6 *eip6;
struct s_tcp *etcp; struct s_tcp *etcp;
struct s_udp *eudp; struct s_udp *eudp;
struct s_icmp *eicmp; struct s_icmp *eicmp;
unsigned short eip4_hlen; unsigned short eip4_hlen;
struct s_ipv6_fragment *eip6_frag; struct s_ipv6_fragment *eip6_frag;
struct s_icmp_echo *echo; struct s_icmp_echo *echo;
/* sanity check */ /* sanity check */
if (payload_size < 1) { if (payload_size < 1) {
@ -932,8 +902,8 @@ int sub_icmp4_error(unsigned char *payload, unsigned short payload_size,
/* define new inner IPv6 header */ /* define new inner IPv6 header */
/* new_len+4+4+40=102 < 1280 */ /* new_len+4+4+40=102 < 1280 */
eip6 = (struct s_ipv6 *) &packet[*packet_len + sizeof(struct s_icmp) + eip6 = (struct s_ipv6 *) (packet + *packet_len + sizeof(struct s_icmp) +
4]; 4);
/* we'll need this right now */ /* we'll need this right now */
ipv4_to_ipv6(&eip4->ip_dest, &eip6->ip_dest); ipv4_to_ipv6(&eip4->ip_dest, &eip6->ip_dest);
@ -1016,8 +986,8 @@ int sub_icmp4_error(unsigned char *payload, unsigned short payload_size,
} }
/* copy ICMP header to new packet */ /* copy ICMP header to new packet */
memcpy(&packet[*packet_len], *icmp, sizeof(struct s_icmp) + 4); memcpy(packet + *packet_len, *icmp, sizeof(struct s_icmp) + 4);
*icmp = (struct s_icmp *) &packet[*packet_len]; *icmp = (struct s_icmp *) (packet + *packet_len);
/* complete inner IPv6 header */ /* complete inner IPv6 header */
eip6->ver = 0x60 | (eip4->tos >> 4); eip6->ver = 0x60 | (eip4->tos >> 4);
@ -1035,7 +1005,7 @@ int sub_icmp4_error(unsigned char *payload, unsigned short payload_size,
/* was the IPv4 packet fragmented? */ /* was the IPv4 packet fragmented? */
if (ntohs(eip4->flags_offset) & 0x1fff) { if (ntohs(eip4->flags_offset) & 0x1fff) {
eip6_frag = (struct s_ipv6_fragment *) &packet[*packet_len]; eip6_frag = (struct s_ipv6_fragment *) (packet + *packet_len);
if (ntohs(eip4->flags_offset) & IPV4_FLAG_MORE_FRAGMENTS) { if (ntohs(eip4->flags_offset) & IPV4_FLAG_MORE_FRAGMENTS) {
eip6_frag->offset_flag = htons(((ntohs(eip4-> eip6_frag->offset_flag = htons(((ntohs(eip4->
@ -1051,9 +1021,9 @@ int sub_icmp4_error(unsigned char *payload, unsigned short payload_size,
eip6->len = htons(ntohs(eip4->len) - eip4_hlen + eip6->len = htons(ntohs(eip4->len) - eip4_hlen +
sizeof(struct s_ipv6_fragment)); sizeof(struct s_ipv6_fragment));
eip6_frag->next_header = eip6->next_header; eip6_frag->next_header = eip6->next_header;
eip6->next_header = IPPROTO_FRAGMENT; eip6_frag->id = htonl(ntohs(eip4->id));
eip6_frag->id = htonl(ntohs(eip4->id)); eip6->next_header = IPPROTO_FRAGMENT;
*packet_len += sizeof(struct s_ipv6_fragment); *packet_len += sizeof(struct s_ipv6_fragment);
} else { } else {
@ -1064,11 +1034,11 @@ int sub_icmp4_error(unsigned char *payload, unsigned short payload_size,
/* we can afford to use full MTU instead of just 1280 B as admin /* we can afford to use full MTU instead of just 1280 B as admin
* warrants this to us */ * warrants this to us */
if (payload_size > mtu + sizeof(struct s_ethernet) - *packet_len) { if (payload_size > mtu + sizeof(struct s_ethernet) - *packet_len) {
memcpy(&packet[*packet_len], payload, memcpy(packet + *packet_len, payload,
mtu + sizeof(struct s_ethernet) - *packet_len); mtu + sizeof(struct s_ethernet) - *packet_len);
*packet_len = mtu; *packet_len = mtu + sizeof(struct s_ethernet);
} else { } else {
memcpy(&packet[*packet_len], payload, payload_size); memcpy(packet + *packet_len, payload, payload_size);
*packet_len += payload_size; *packet_len += payload_size;
} }
@ -1090,17 +1060,17 @@ int sub_icmp4_error(unsigned char *payload, unsigned short payload_size,
* @return 1 for failure * @return 1 for failure
*/ */
int sub_icmp6_error(struct s_ethernet *eth6, int sub_icmp6_error(struct s_ethernet *eth6,
unsigned char *payload, unsigned short payload_size, char *payload, unsigned short payload_size,
unsigned char *packet, unsigned short *packet_len, char *packet, unsigned short *packet_len,
struct s_icmp **icmp, struct s_nat **connection) struct s_icmp **icmp, struct s_nat **connection)
{ {
struct s_ipv4 *eip4; struct s_ipv4 *eip4;
struct s_ipv6 *eip6; struct s_ipv6 *eip6;
struct s_ipv6_fragment *eip6_frag; struct s_ipv6_fragment *eip6_frag;
struct s_tcp *etcp; struct s_tcp *etcp;
struct s_udp *eudp; struct s_udp *eudp;
struct s_icmp *eicmp; struct s_icmp *eicmp;
struct s_icmp_echo *echo; struct s_icmp_echo *echo;
unsigned char skip_l4 = 0; unsigned char skip_l4 = 0;
@ -1116,8 +1086,8 @@ int sub_icmp6_error(struct s_ethernet *eth6,
/* define new inner IPv4 header */ /* define new inner IPv4 header */
/* new_len+4+4+20=48 < 576 */ /* new_len+4+4+20=48 < 576 */
eip4 = (struct s_ipv4 *) &packet[*packet_len + sizeof(struct s_icmp) + eip4 = (struct s_ipv4 *) (packet + *packet_len + sizeof(struct s_icmp) +
4]; 4);
/* we'll need this right now */ /* we'll need this right now */
ipv6_to_ipv4(&eip6->ip_src, &eip4->ip_src); ipv6_to_ipv4(&eip6->ip_src, &eip4->ip_src);
@ -1247,8 +1217,8 @@ int sub_icmp6_error(struct s_ethernet *eth6,
} }
/* copy ICMP header to new packet */ /* copy ICMP header to new packet */
memcpy(&packet[*packet_len], *icmp, sizeof(struct s_icmp) + 4); memcpy(packet + *packet_len, *icmp, sizeof(struct s_icmp) + 4);
*icmp = (struct s_icmp *) &packet[*packet_len]; *icmp = (struct s_icmp *) (packet + *packet_len);
/* complete inner IPv4 header */ /* complete inner IPv4 header */
eip4->ver_hdrlen = 0x45; /* ver 4, header length 20 B */ eip4->ver_hdrlen = 0x45; /* ver 4, header length 20 B */
@ -1263,16 +1233,16 @@ int sub_icmp6_error(struct s_ethernet *eth6,
eip4->proto = IPPROTO_ICMP; eip4->proto = IPPROTO_ICMP;
} }
/* packet_len == sizeof(IPv4) */ /* packet_len == sizeof(outer IPv4 header) */
*packet_len += sizeof(struct s_icmp) + 4 + sizeof(struct s_ipv4); *packet_len += sizeof(struct s_icmp) + 4 + sizeof(struct s_ipv4);
/* copy payload */ /* copy payload */
/* let's use 576 as an IPv4 MTU */ /* let's use 576 as an IPv4 MTU */
if (payload_size > 576 - *packet_len) { if (payload_size > 576 - *packet_len) {
memcpy(&packet[*packet_len], payload, 576 - *packet_len); memcpy(packet + *packet_len, payload, 576 - *packet_len);
*packet_len = 576; *packet_len = 576;
} else { } else {
memcpy(&packet[*packet_len], payload, payload_size); memcpy(packet + *packet_len, payload, payload_size);
*packet_len += payload_size; *packet_len += payload_size;
} }

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2013 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2017 xHire <xhire@wrapsix.org>
* *
* 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 General Public License as published by * it under the terms of the GNU General Public License as published by
@ -84,9 +84,9 @@ int icmp_ndp(struct s_ethernet *ethq, struct s_ipv6 *ipq,
struct s_icmp_ndp_ns *ndp_ns); struct s_icmp_ndp_ns *ndp_ns);
int icmp4_error(struct s_ipv4_addr ip_dest, unsigned char type, int icmp4_error(struct s_ipv4_addr ip_dest, unsigned char type,
unsigned char code, unsigned char *data, unsigned short length); unsigned char code, char *data, unsigned short length);
int icmp6_error(struct s_mac_addr mac_dest, struct s_ipv6_addr ip_dest, int icmp6_error(struct s_mac_addr mac_dest, struct s_ipv6_addr ip_dest,
unsigned char type, unsigned char code, unsigned char *data, unsigned char type, unsigned char code, char *data,
unsigned short length); unsigned short length);
#endif /* ICMP_H */ #endif /* ICMP_H */

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2013 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2017 xHire <xhire@wrapsix.org>
* *
* 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 General Public License as published by * it under the terms of the GNU General Public License as published by
@ -63,7 +63,7 @@ int ipv4(struct s_ethernet *eth, char *packet)
payload[0] & 0x08) && !(ip->flags_offset & htons(0x1fff))) { payload[0] & 0x08) && !(ip->flags_offset & htons(0x1fff))) {
/* code 0 = ttl exceeded in transmit */ /* code 0 = ttl exceeded in transmit */
icmp4_error(ip->ip_src, ICMPV4_TIME_EXCEEDED, 0, icmp4_error(ip->ip_src, ICMPV4_TIME_EXCEEDED, 0,
(unsigned char *) packet, htons(ip->len)); packet, htons(ip->len));
} }
return 1; return 1;
} else { } else {

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2013 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2017 xHire <xhire@wrapsix.org>
* *
* 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 General Public License as published by * it under the terms of the GNU General Public License as published by
@ -56,7 +56,7 @@ int ipv6(struct s_ethernet *eth, char *packet)
if (ip->next_header != IPPROTO_ICMPV6 || payload[0] & 0x80) { if (ip->next_header != IPPROTO_ICMPV6 || payload[0] & 0x80) {
/* code 0 = hl exceeded in transmit */ /* code 0 = hl exceeded in transmit */
icmp6_error(eth->src, ip->ip_src, ICMPV6_TIME_EXCEEDED, icmp6_error(eth->src, ip->ip_src, ICMPV6_TIME_EXCEEDED,
0, (unsigned char *) packet, 0, packet,
htons(ip->len) + sizeof(struct s_ipv6)); htons(ip->len) + sizeof(struct s_ipv6));
} }
return 1; return 1;

109
src/tcp.c
View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2013 xHire <xhire@wrapsix.org> * Copyright (C) 2008-2017 xHire <xhire@wrapsix.org>
* *
* 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 General Public License as published by * it under the terms of the GNU General Public License as published by
@ -48,12 +48,12 @@
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,
unsigned short payload_size) unsigned short payload_size)
{ {
struct s_tcp *tcp; struct s_tcp *tcp;
struct s_nat *connection; struct s_nat *connection;
unsigned short tmp_short; unsigned short tmp_short;
unsigned char *packet; char packet[PACKET_BUFFER];
unsigned char *saved_packet; char *saved_packet;
struct s_nat_fragments *frag_conn; struct s_nat_fragments *frag_conn;
linkedlist_node_t *llnode; linkedlist_node_t *llnode;
@ -79,7 +79,7 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
tcp->checksum = 0; tcp->checksum = 0;
tcp->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest, tcp->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest,
payload_size, IPPROTO_TCP, payload_size, IPPROTO_TCP,
(unsigned char *) tcp); (char *) tcp);
if (tcp->checksum != tmp_short) { if (tcp->checksum != tmp_short) {
/* packet is corrupted and shouldn't be /* packet is corrupted and shouldn't be
@ -184,11 +184,10 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
(char *) llnode->prev->data + (char *) llnode->prev->data +
sizeof(unsigned short) + sizeof(unsigned short) +
sizeof(struct s_ethernet)), sizeof(struct s_ethernet)),
(char *) ( (char *) llnode->prev->data +
(char *) llnode->prev->data +
sizeof(unsigned short) + sizeof(unsigned short) +
sizeof(struct s_ethernet) + sizeof(struct s_ethernet) +
sizeof(struct s_ipv4)), sizeof(struct s_ipv4),
tmp_short); tmp_short);
free(llnode->prev->data); free(llnode->prev->data);
linkedlist_delete(frag_conn->queue, linkedlist_delete(frag_conn->queue,
@ -197,15 +196,7 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
} }
} }
/* allocate enough memory for translated packet */ /* translated packet */
if ((packet = (unsigned char *) malloc(
payload_size > mtu - sizeof(struct s_ipv6) ?
mtu + sizeof(struct s_ethernet) :
sizeof(struct s_ethernet) + sizeof(struct s_ipv6) +
payload_size)) == NULL) {
log_error("Lack of free memory");
return 1;
}
eth6 = (struct s_ethernet *) packet; eth6 = (struct s_ethernet *) packet;
ip6 = (struct s_ipv6 *) (packet + sizeof(struct s_ethernet)); ip6 = (struct s_ipv6 *) (packet + sizeof(struct s_ethernet));
@ -244,8 +235,8 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
ip6->next_header = IPPROTO_FRAGMENT; ip6->next_header = IPPROTO_FRAGMENT;
/* create IPv6 fragment header */ /* create IPv6 fragment header */
frag = (struct s_ipv6_fragment *) ((unsigned char *) ip6 frag = (struct s_ipv6_fragment *) ((char *) ip6 +
+ sizeof(struct s_ipv6)); sizeof(struct s_ipv6));
frag->next_header = IPPROTO_TCP; frag->next_header = IPPROTO_TCP;
frag->zeros = 0x0; frag->zeros = 0x0;
frag->offset_flag = htons(IPV6_FLAG_MORE_FRAGMENTS); frag->offset_flag = htons(IPV6_FLAG_MORE_FRAGMENTS);
@ -253,8 +244,7 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
(unsigned int) rand(); (unsigned int) rand();
/* copy the payload data */ /* copy the payload data */
memcpy((unsigned char *) frag + memcpy((char *) frag + sizeof(struct s_ipv6_fragment),
sizeof(struct s_ipv6_fragment),
payload, FRAGMENT_LEN); payload, FRAGMENT_LEN);
/* send translated packet */ /* send translated packet */
@ -270,8 +260,7 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
frag->offset_flag = htons((FRAGMENT_LEN / 8) << 3); frag->offset_flag = htons((FRAGMENT_LEN / 8) << 3);
/* copy the payload data */ /* copy the payload data */
memcpy((unsigned char *) frag + memcpy((char *) frag + sizeof(struct s_ipv6_fragment),
sizeof(struct s_ipv6_fragment),
payload + FRAGMENT_LEN, payload + FRAGMENT_LEN,
payload_size - FRAGMENT_LEN); payload_size - FRAGMENT_LEN);
@ -285,7 +274,7 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
ip6->next_header = IPPROTO_TCP; ip6->next_header = IPPROTO_TCP;
/* copy the payload data */ /* copy the payload data */
memcpy((unsigned char *) ip6 + sizeof(struct s_ipv6), memcpy((char *) ip6 + sizeof(struct s_ipv6),
payload, payload_size); payload, payload_size);
/* send translated packet */ /* send translated packet */
@ -303,7 +292,7 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
log_debug("Incoming connection wasn't found in " log_debug("Incoming connection wasn't found in "
"fragments table -- saving it"); "fragments table -- saving it");
if ((saved_packet = (unsigned char *) malloc( if ((saved_packet = (char *) malloc(
sizeof(unsigned short) + sizeof(struct s_ethernet) + sizeof(unsigned short) + sizeof(struct s_ethernet) +
sizeof(struct s_ipv4) + payload_size)) == NULL) { sizeof(struct s_ipv4) + payload_size)) == NULL) {
log_error("Lack of free memory"); log_error("Lack of free memory");
@ -322,36 +311,25 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
/* save the packet and put it into the queue */ /* save the packet and put it into the queue */
memcpy(saved_packet, &payload_size, memcpy(saved_packet, &payload_size,
sizeof(unsigned short)); sizeof(unsigned short));
memcpy((unsigned char *) (saved_packet + memcpy(saved_packet + sizeof(unsigned short),
sizeof(unsigned short)), eth4, (char *) eth4, sizeof(struct s_ethernet));
sizeof(struct s_ethernet)); memcpy(saved_packet + sizeof(unsigned short) +
memcpy((unsigned char *) (saved_packet + sizeof(struct s_ethernet),
sizeof(unsigned short) + (char *) ip4, sizeof(struct s_ipv4));
sizeof(struct s_ethernet)), ip4, memcpy(saved_packet + sizeof(unsigned short) +
sizeof(struct s_ipv4));
memcpy((unsigned char *) (saved_packet +
sizeof(unsigned short) +
sizeof(struct s_ethernet) + sizeof(struct s_ethernet) +
sizeof(struct s_ipv4)), payload, payload_size); sizeof(struct s_ipv4), payload, payload_size);
linkedlist_append(frag_conn->queue, saved_packet); linkedlist_append(frag_conn->queue, saved_packet);
return 0; return 0;
} }
/* allocate enough memory for translated packet */ /* translated packet */
if ((packet = (unsigned char *) malloc(
payload_size > mtu - sizeof(struct s_ipv6) -
sizeof(struct s_ipv6_fragment) ?
mtu + sizeof(struct s_ethernet) :
sizeof(struct s_ethernet) + sizeof(struct s_ipv6) +
sizeof(struct s_ipv6_fragment) + payload_size)) == NULL) {
log_error("Lack of free memory");
return 1;
}
eth6 = (struct s_ethernet *) packet; eth6 = (struct s_ethernet *) packet;
ip6 = (struct s_ipv6 *) (packet + sizeof(struct s_ethernet)); ip6 = (struct s_ipv6 *) (packet + sizeof(struct s_ethernet));
frag = (struct s_ipv6_fragment *) ((unsigned char *) ip6 + frag = (struct s_ipv6_fragment *) (packet +
sizeof(struct s_ethernet) +
sizeof(struct s_ipv6)); sizeof(struct s_ipv6));
/* build ethernet header */ /* build ethernet header */
@ -386,8 +364,7 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
IPV6_FLAG_MORE_FRAGMENTS); IPV6_FLAG_MORE_FRAGMENTS);
/* copy the payload data */ /* copy the payload data */
memcpy((unsigned char *) frag + memcpy((char *) frag + sizeof(struct s_ipv6_fragment),
sizeof(struct s_ipv6_fragment),
payload, FRAGMENT_LEN); payload, FRAGMENT_LEN);
/* send translated packet */ /* send translated packet */
@ -407,8 +384,7 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
} }
/* copy the payload data */ /* copy the payload data */
memcpy((unsigned char *) frag + memcpy((char *) frag + sizeof(struct s_ipv6_fragment),
sizeof(struct s_ipv6_fragment),
payload + FRAGMENT_LEN, payload + FRAGMENT_LEN,
payload_size - FRAGMENT_LEN); payload_size - FRAGMENT_LEN);
@ -432,7 +408,7 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
} }
/* copy the payload data */ /* copy the payload data */
memcpy((unsigned char *) ip6 + sizeof(struct s_ipv6) + memcpy((char *) ip6 + sizeof(struct s_ipv6) +
sizeof(struct s_ipv6_fragment), sizeof(struct s_ipv6_fragment),
payload, payload_size); payload, payload_size);
@ -444,9 +420,6 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
} }
} }
/* clean-up */
free(packet);
return 0; return 0;
} }
@ -463,11 +436,11 @@ int tcp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
*/ */
int tcp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload) int tcp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
{ {
struct s_tcp *tcp; struct s_tcp *tcp;
struct s_nat *connection; struct s_nat *connection;
unsigned short orig_checksum; unsigned short orig_checksum;
struct s_ipv4 *ip4; struct s_ipv4 *ip4;
unsigned char *packet; char packet[PACKET_BUFFER];
/* parse TCP header */ /* parse TCP header */
tcp = (struct s_tcp *) payload; tcp = (struct s_tcp *) payload;
@ -477,7 +450,7 @@ int tcp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
tcp->checksum = 0; tcp->checksum = 0;
tcp->checksum = checksum_ipv6(ip6->ip_src, ip6->ip_dest, tcp->checksum = checksum_ipv6(ip6->ip_src, ip6->ip_dest,
htons(ip6->len), IPPROTO_TCP, htons(ip6->len), IPPROTO_TCP,
(unsigned char *) payload); (char *) payload);
if (tcp->checksum != orig_checksum) { if (tcp->checksum != orig_checksum) {
/* packet is corrupted and shouldn't be processed */ /* packet is corrupted and shouldn't be processed */
@ -560,12 +533,7 @@ int tcp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
} }
} }
/* allocate memory for translated packet */ /* translated packet */
if ((packet = (unsigned char *) malloc(sizeof(struct s_ipv4) +
htons(ip6->len))) == NULL) {
log_error("Lack of free memory");
return 1;
}
ip4 = (struct s_ipv4 *) packet; ip4 = (struct s_ipv4 *) packet;
/* build IPv4 packet */ /* build IPv4 packet */
@ -600,8 +568,5 @@ int tcp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
/* send translated packet */ /* send translated packet */
transmit_ipv4(&ip4->ip_dest, packet, htons(ip4->len)); transmit_ipv4(&ip4->ip_dest, packet, htons(ip4->len));
/* clean-up */
free(packet);
return 0; return 0;
} }

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2012 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2017 xHire <xhire@wrapsix.org>
* *
* 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 General Public License as published by * it under the terms of the GNU General Public License as published by
@ -119,7 +119,7 @@ int transmission_quit(void)
* @return 0 for success * @return 0 for success
* @return 1 for failure * @return 1 for failure
*/ */
int transmit_raw(unsigned char *data, unsigned int length) int transmit_raw(char *data, unsigned int length)
{ {
if (sendto(sock, data, length, 0, (struct sockaddr *) &socket_address, if (sendto(sock, data, length, 0, (struct sockaddr *) &socket_address,
sizeof(struct sockaddr_ll)) != (int) length) { sizeof(struct sockaddr_ll)) != (int) length) {
@ -142,8 +142,7 @@ int transmit_raw(unsigned char *data, unsigned int length)
* @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, int transmit_ipv4(struct s_ipv4_addr *ip, char *data, unsigned int length)
unsigned int length)
{ {
/* set the destination IPv4 address */ /* set the destination IPv4 address */
memcpy(&socket_address_ipv4.sin_addr.s_addr, ip, memcpy(&socket_address_ipv4.sin_addr.s_addr, ip,

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2013 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2017 xHire <xhire@wrapsix.org>
* *
* 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 General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,8 +23,7 @@
int transmission_init(void); int transmission_init(void);
int transmission_quit(void); int transmission_quit(void);
int transmit_raw(unsigned char *data, unsigned int length); int transmit_raw(char *data, unsigned int length);
int transmit_ipv4(struct s_ipv4_addr *ip, unsigned char *data, int transmit_ipv4(struct s_ipv4_addr *ip, char *data, unsigned int length);
unsigned int length);
#endif /* TRANSMITTER_H */ #endif /* TRANSMITTER_H */

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2013 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2017 xHire <xhire@wrapsix.org>
* *
* 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 General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,7 +18,6 @@
#include <net/ethernet.h> /* ETHERTYPE_* */ #include <net/ethernet.h> /* ETHERTYPE_* */
#include <netinet/in.h> /* htons */ #include <netinet/in.h> /* htons */
#include <stdlib.h> /* malloc */
#include <string.h> /* memcpy */ #include <string.h> /* memcpy */
#include "checksum.h" #include "checksum.h"
@ -48,13 +47,13 @@
int udp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload, int udp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
unsigned short payload_size) unsigned short payload_size)
{ {
struct s_udp *udp; struct s_udp *udp;
struct s_nat *connection; struct s_nat *connection;
unsigned short orig_checksum; unsigned short orig_checksum;
unsigned char *packet; char packet[PACKET_BUFFER];
struct s_ethernet *eth6; struct s_ethernet *eth6;
struct s_ipv6 *ip6; struct s_ipv6 *ip6;
/* parse UDP header */ /* parse UDP header */
udp = (struct s_udp *) payload; udp = (struct s_udp *) payload;
@ -65,7 +64,7 @@ int udp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
udp->checksum = 0; udp->checksum = 0;
udp->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest, udp->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest,
payload_size, IPPROTO_UDP, payload_size, IPPROTO_UDP,
(unsigned char *) udp); payload);
if (udp->checksum != orig_checksum) { if (udp->checksum != orig_checksum) {
/* packet is corrupted and shouldn't be processed */ /* packet is corrupted and shouldn't be processed */
@ -85,13 +84,7 @@ int udp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
linkedlist_move2end(timeout_udp, connection->llnode); linkedlist_move2end(timeout_udp, connection->llnode);
/* allocate memory for translated packet */ /* translated packet */
if ((packet = (unsigned char *) malloc(sizeof(struct s_ethernet) +
sizeof(struct s_ipv6) +
payload_size)) == NULL) {
log_error("Lack of free memory");
return 1;
}
eth6 = (struct s_ethernet *) packet; eth6 = (struct s_ethernet *) packet;
ip6 = (struct s_ipv6 *) (packet + sizeof(struct s_ethernet)); ip6 = (struct s_ipv6 *) (packet + sizeof(struct s_ethernet));
@ -124,7 +117,7 @@ int udp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
/* if original checksum was 0x0000, we need to compute it */ /* if original checksum was 0x0000, we need to compute it */
udp->checksum = checksum_ipv6(ip6->ip_src, ip6->ip_dest, udp->checksum = checksum_ipv6(ip6->ip_src, ip6->ip_dest,
payload_size, IPPROTO_UDP, payload_size, IPPROTO_UDP,
(unsigned char *) udp); (char *) udp);
} }
/* copy the payload data (with new checksum) */ /* copy the payload data (with new checksum) */
@ -135,9 +128,6 @@ int udp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
transmit_raw(packet, sizeof(struct s_ethernet) + sizeof(struct s_ipv6) + transmit_raw(packet, sizeof(struct s_ethernet) + sizeof(struct s_ipv6) +
payload_size); payload_size);
/* clean-up */
free(packet);
return 0; return 0;
} }
@ -154,12 +144,12 @@ int udp_ipv4(struct s_ethernet *eth4, struct s_ipv4 *ip4, char *payload,
*/ */
int udp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload) int udp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
{ {
struct s_udp *udp; struct s_udp *udp;
struct s_nat *connection; struct s_nat *connection;
unsigned short orig_checksum; unsigned short orig_checksum;
struct s_ipv4 *ip4; struct s_ipv4 *ip4;
unsigned char *packet; char packet[PACKET_BUFFER];
unsigned int packet_size; unsigned int packet_size;
/* parse UDP header */ /* parse UDP header */
udp = (struct s_udp *) payload; udp = (struct s_udp *) payload;
@ -168,8 +158,7 @@ int udp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
orig_checksum = udp->checksum; orig_checksum = udp->checksum;
udp->checksum = 0; udp->checksum = 0;
udp->checksum = checksum_ipv6(ip6->ip_src, ip6->ip_dest, udp->checksum = checksum_ipv6(ip6->ip_src, ip6->ip_dest,
htons(ip6->len), IPPROTO_UDP, htons(ip6->len), IPPROTO_UDP, payload);
(unsigned char *) payload);
if (udp->checksum != orig_checksum) { if (udp->checksum != orig_checksum) {
/* packet is corrupted and shouldn't be processed */ /* packet is corrupted and shouldn't be processed */
@ -193,13 +182,10 @@ int udp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
linkedlist_move2end(timeout_udp, connection->llnode); linkedlist_move2end(timeout_udp, connection->llnode);
} }
/* allocate memory for translated packet */
packet_size = sizeof(struct s_ipv4) + htons(ip6->len); /* translated packet */
if ((packet = (unsigned char *) malloc(packet_size)) == NULL) {
log_error("Lack of free memory");
return 1;
}
ip4 = (struct s_ipv4 *) packet; ip4 = (struct s_ipv4 *) packet;
packet_size = sizeof(struct s_ipv4) + htons(ip6->len);
/* 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 */
@ -233,8 +219,5 @@ int udp_ipv6(struct s_ethernet *eth6, struct s_ipv6 *ip6, char *payload)
/* send translated packet */ /* send translated packet */
transmit_ipv4(&ip4->ip_dest, packet, packet_size); transmit_ipv4(&ip4->ip_dest, packet, packet_size);
/* clean-up */
free(packet);
return 0; return 0;
} }