Merge commit 'upstream/0.3.2'
[debian/uanytun.git] / src / encrypted_packet.c
1 /*
2  *  uAnytun
3  *
4  *  uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full
5  *  featured implementation uAnytun has no support for multiple connections
6  *  or synchronisation. It is a small single threaded implementation intended
7  *  to act as a client on small platforms.
8  *  The secure anycast tunneling protocol (satp) defines a protocol used
9  *  for communication between any combination of unicast and anycast
10  *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
11  *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
12  *  ethernet, ip, arp ...). satp directly includes cryptography and
13  *  message authentication based on the methodes used by SRTP.  It is
14  *  intended to deliver a generic, scaleable and secure solution for
15  *  tunneling and relaying of packets of any protocol.
16  *  
17  *
18  *  Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org>
19  *
20  *  This file is part of uAnytun.
21  *
22  *  uAnytun is free software: you can redistribute it and/or modify
23  *  it under the terms of the GNU General Public License as published by
24  *  the Free Software Foundation, either version 3 of the License, or
25  *  any later version.
26  *
27  *  uAnytun is distributed in the hope that it will be useful,
28  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30  *  GNU General Public License for more details.
31  *
32  *  You should have received a copy of the GNU General Public License
33  *  along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
34  */
35
36 #include "datatypes.h"
37
38 #include "encrypted_packet.h"
39
40 #include <stdlib.h>
41 #include <string.h>
42
43 void encrypted_packet_init(encrypted_packet_t* packet, u_int32_t auth_tag_length)
44 {
45   if(!packet)
46     return;
47
48   memset (packet, 0, sizeof(*packet));
49   if(auth_tag_length > (ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t)))
50     packet->auth_tag_length_ = ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t);
51   else
52     packet->auth_tag_length_ = auth_tag_length;
53 }
54
55 u_int32_t encrypted_packet_get_minimum_length(encrypted_packet_t* packet)
56 {
57   if(!packet)
58     return 0;
59
60   return (sizeof(encrypted_packet_header_t) + packet->auth_tag_length_);
61 }
62
63 u_int8_t* encrypted_packet_get_packet(encrypted_packet_t* packet)
64 {
65   if(!packet)
66     return NULL;
67
68   return packet->data_.buf_;
69 }
70
71 u_int32_t encrypted_packet_get_length(encrypted_packet_t* packet)
72 {
73   if(!packet)
74     return 0;
75
76   return (packet->payload_length_ + sizeof(encrypted_packet_header_t) + packet->auth_tag_length_);
77 }
78
79 void encrypted_packet_set_length(encrypted_packet_t* packet, u_int32_t len)
80 {
81   if(!packet)
82     return;
83
84   if(len > ENCRYPTED_PACKET_SIZE_MAX)
85     len = ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t) - packet->auth_tag_length_;
86   else if(len < (sizeof(encrypted_packet_header_t) + packet->auth_tag_length_))
87     len = 0;
88   else
89     len -= (sizeof(encrypted_packet_header_t) + packet->auth_tag_length_);
90
91   packet->payload_length_ = len;
92 }
93
94 u_int8_t* encrypted_packet_get_payload(encrypted_packet_t* packet)
95 {
96   if(!packet || !packet->payload_length_)
97     return NULL;
98
99   return (packet->data_.buf_ + sizeof(encrypted_packet_header_t));
100 }
101
102 u_int32_t encrypted_packet_get_payload_length(encrypted_packet_t* packet)
103 {
104   if(!packet)
105     return 0;
106
107   return packet->payload_length_;
108 }
109
110 void encrypted_packet_set_payload_length(encrypted_packet_t* packet, u_int32_t len)
111 {
112   if(!packet)
113     return;
114
115   if(len > (ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t) - packet->auth_tag_length_))
116     len = ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t) - packet->auth_tag_length_;
117
118   packet->payload_length_ = len;
119 }
120
121 u_int8_t* encrypted_packet_get_auth_portion(encrypted_packet_t* packet)
122 {
123   if(!packet)
124     return NULL;
125
126   return packet->data_.buf_;
127 }
128
129 u_int32_t encrypted_packet_get_auth_portion_length(encrypted_packet_t* packet)
130 {
131   if(!packet)
132     return 0;
133
134   return  packet->payload_length_ + sizeof(encrypted_packet_header_t);
135 }
136
137
138 u_int8_t* encrypted_packet_get_auth_tag(encrypted_packet_t* packet)
139 {
140   if(!packet || !packet->auth_tag_length_)
141     return NULL;
142
143   return (packet->data_.buf_ + sizeof(encrypted_packet_header_t) + packet->payload_length_);
144 }
145
146 u_int32_t encrypted_packet_get_auth_tag_length(encrypted_packet_t* packet)
147 {
148   if(!packet)
149     return 0;
150
151   return packet->auth_tag_length_;
152 }
153
154
155 seq_nr_t encrypted_packet_get_seq_nr(encrypted_packet_t* packet)
156 {
157   if(!packet)
158     return 0;
159
160   return SEQ_NR_T_NTOH(packet->data_.header_.seq_nr_);
161 }
162
163 void encrypted_packet_set_seq_nr(encrypted_packet_t* packet, seq_nr_t seq_nr)
164 {
165   if(!packet)
166     return;
167
168   packet->data_.header_.seq_nr_ = SEQ_NR_T_HTON(seq_nr);
169 }
170
171 sender_id_t encrypted_packet_get_sender_id(encrypted_packet_t* packet)
172 {
173   if(!packet)
174     return 0;
175
176   return SENDER_ID_T_NTOH(packet->data_.header_.sender_id_);
177 }
178
179 void encrypted_packet_set_sender_id(encrypted_packet_t* packet, sender_id_t sender_id)
180 {
181   if(!packet)
182     return;
183
184   packet->data_.header_.sender_id_ = SENDER_ID_T_HTON(sender_id);
185 }
186
187 mux_t encrypted_packet_get_mux(encrypted_packet_t* packet)
188 {
189   if(!packet)
190     return 0;
191   
192   return MUX_T_NTOH(packet->data_.header_.mux_);
193 }
194
195 void encrypted_packet_set_mux(encrypted_packet_t* packet, mux_t mux)
196 {
197   if(!packet)
198     return;
199
200   packet->data_.header_.mux_ = MUX_T_HTON(mux);
201 }