]> sjero.net Git - dccp2tcp/blob - encap.c
Tag older versions in repository
[dccp2tcp] / encap.c
1 /******************************************************************************
2 Author: Samuel Jero
3
4 Date: 7/2011
5
6 Description: Encapsulation Functions for DCCP conversion to TCP
7
8 ******************************************************************************/
9 #include "dccp2tcp.h"
10 #include "encap.h"
11 #include "pcap/sll.h"
12
13 /*Encapsulation start point and link layer selector*/
14 int do_encap(int link, struct packet *new, const struct const_packet *old)
15 {
16         switch(link){
17                 case DLT_EN10MB:
18                                 /*Ethernet*/
19                                 if(!ethernet_encap(new, old)){
20                                                 return 0;
21                                 }
22                                 break;
23                 case DLT_RAW:
24                                 /*Raw. Just IP*/
25                                 if(!ipv4_encap(new, old)){
26                                                 return 0;
27                                 }
28                                 break;
29                 case DLT_LINUX_SLL:
30                                 /*Linux Cooked Capture*/
31                                 if(!linux_cooked_encap(new, old)){
32                                         return 0;
33                                 }
34                                 break;
35                 default:
36                                 dbgprintf(0, "Unknown Link Layer\n");
37                                 return 0;
38         }
39
40         /*Adjust libpcap header*/
41         if(new->h->caplen >= new->h->len || new->h->caplen >= new->length){
42                 new->h->caplen=new->length;
43         }
44         new->h->len=new->length;
45
46 return 1;
47 }
48
49 /*Standard Ethernet Encapsulation*/
50 int ethernet_encap(struct packet *new, const struct const_packet *old)
51 {
52                 struct ether_header     *ethh;
53                 struct const_packet nold;
54                 struct packet           nnew;
55
56                 /*Safety checks*/
57                 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
58                         dbgprintf(0,"Error: Ethernet Encapsulation Function given bad data!\n");
59                         return 0;
60                 }
61                 if(old->length < sizeof(struct ether_header) || new->length < sizeof(struct ether_header)){
62                         dbgprintf(0, "Error: Ethernet Encapsulation Function given packet of wrong size!\n");
63                         return 0;
64                 }
65
66                 /*Copy Ethernet header over*/
67                 memcpy(new->data, old->data, sizeof(struct ether_header));
68
69                 /*Cast Pointer*/
70                 ethh=(struct ether_header*)(new->data);
71
72                 /*Adjust pointers and lengths*/
73                 nold.data= old->data+ sizeof(struct ether_header);
74                 nnew.data= new->data + sizeof(struct ether_header);
75                 nold.length= old->length - sizeof(struct ether_header);
76                 nnew.length= new->length - sizeof(struct ether_header);
77                 nnew.h=new->h;
78                 nold.h=old->h;
79
80                 /*Select Next Protocol*/
81                 switch(ntohs(ethh->ether_type)){
82                         case ETHERTYPE_IP:
83                                         if(!ipv4_encap(&nnew, &nold)){
84                                                         return 0;
85                                         }
86                                         break;
87                         default:
88                                         dbgprintf(1, "Unknown Next Protocol at Ethernet\n");
89                                         return 0;
90                                         break;
91                 }
92
93                 /*Adjust length*/
94                 new->length=nnew.length + sizeof(struct ether_header);
95 return 1;
96 }
97
98 /*IPv4 Encapsulation*/
99 int ipv4_encap(struct packet *new, const struct const_packet *old)
100 {
101                 struct iphdr            *iph;
102                 struct packet           nnew;
103                 struct const_packet     nold;
104
105                 /*Safety checks*/
106                 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
107                         dbgprintf(0,"Error: IPv4 Encapsulation Function given bad data!\n");
108                         return 0;
109                 }
110                 if(old->length < sizeof(struct iphdr) || new->length < sizeof(struct iphdr)){
111                         dbgprintf(0, "Error: IPv4 Encapsulation Function given packet of wrong size!\n");
112                         return 0;
113                 }
114
115                 /*Copy IPv4 header over*/
116                 memcpy(new->data, old->data, sizeof(struct iphdr));
117
118                 /*Cast Pointer*/
119                 iph=(struct iphdr*)(new->data);
120
121                 /*Adjust pointers and lengths*/
122                 nold.data= old->data +iph->ihl*4;
123                 nnew.data= new->data +iph->ihl*4;
124                 nold.length= old->length -iph->ihl*4;
125                 nnew.length= new->length -iph->ihl*4;
126                 nnew.h=new->h;
127                 nold.h=old->h;
128
129                 /*Confirm that this is IPv4*/
130                 if(iph->version!=4){
131                         dbgprintf(1, "Note: Packet is not IPv4\n");
132                         return 0;
133                 }
134
135                 /*Select Next Protocol*/
136                 switch(iph->protocol){
137                         case 0x21:
138                                         /*DCCP*/
139                                         nnew.src_id=iph->saddr;
140                                         nnew.dest_id=iph->daddr;
141                                         if(!convert_packet(&nnew, &nold)){
142                                                 return 0;
143                                         }
144                                         break;
145                         default:
146                                         dbgprintf(1, "Unknown Next Protocol at IPv4\n");
147                                         return 0;
148                                         break;
149                 }
150
151                 /*set ip to indicate that TCP is next protocol*/
152                 iph->protocol=6;
153                 iph->check=htonl(0);
154
155                 /*Adjust length*/
156                 new->length=nnew.length + iph->ihl*4;
157
158                 /*Determine if computed length is reasonable*/
159                 if(nnew.length > 0xFFFF){
160                                 dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
161                                 return 0;
162                 }
163
164                 /*Adjust IPv4 header to account for packet's total length*/
165                 iph->tot_len=htons(new->length);
166 return 1;
167 }
168
169 int linux_cooked_encap(struct packet *new, const struct const_packet *old)
170 {
171         struct sll_header               *slh;
172         struct packet                   nnew;
173         struct const_packet             nold;
174
175
176         /*Safety checks*/
177         if(!new|| !old || !new->data || !old->data || !new->h || !old->h){
178                 dbgprintf(0,"Error: SLL Encapsulation Function given bad data!\n");
179                 return 0;
180         }
181         if(old->length < sizeof(struct sll_header) || new->length < sizeof(struct sll_header)){
182                 dbgprintf(0, "Error: SLL Encapsulation Function given packet of wrong size!\n");
183                 return 0;
184         }
185
186         /*Copy SLL header over*/
187         memcpy(new->data, old->data, sizeof(struct sll_header));
188
189         /*Cast Pointer*/
190         slh=(struct sll_header*)(new->data);
191
192         /*Adjust pointers and lengths*/
193         nold.data= old->data + sizeof(struct sll_header);
194         nnew.data= new->data + sizeof(struct sll_header);
195         nold.length= old->length - sizeof(struct sll_header);
196         nnew.length= new->length- sizeof(struct sll_header);
197         nnew.h=new->h;
198         nold.h=old->h;
199
200         /*Confirm that this is SLL*/
201         if(ntohs(slh->sll_pkttype) > 4){
202                 dbgprintf(1, "Note: Packet is not SLL (Linux Cooked Capture)\n");
203                 return 0;
204         }
205
206         /*Select Next Protocol*/
207         switch(ntohs(slh->sll_protocol)){
208                 case ETHERTYPE_IP:
209                                 if(!ipv4_encap(&nnew, &nold)){
210                                                 return 0;
211                                 }
212                                 break;
213                 default:
214                                 dbgprintf(1, "Unknown Next Protocol at SLL\n");
215                                 return 0;
216                                 break;
217         }
218
219         /*Adjust length*/
220         new->length=nnew.length + sizeof(struct sll_header);
221 return 1;
222 }