1 /******************************************************************************
6 Description: Encapsulation Functions for DCCP conversion to TCP
8 ******************************************************************************/
12 #include <netinet/ip6.h>
14 /*Encapsulation start point and link layer selector*/
15 int do_encap(int link, struct packet *new, const struct const_packet *old)
20 if(!ethernet_encap(new, old)){
26 if(!ipv4_encap(new, old)){
31 /*Linux Cooked Capture*/
32 if(!linux_cooked_encap(new, old)){
37 dbgprintf(0, "Unknown Link Layer\n");
41 /*Adjust libpcap header*/
42 if(new->h->caplen >= new->h->len || new->h->caplen >= new->length){
43 new->h->caplen=new->length;
45 new->h->len=new->length;
50 /*Standard Ethernet Encapsulation*/
51 int ethernet_encap(struct packet *new, const struct const_packet *old)
53 struct ether_header *ethh;
54 struct const_packet nold;
58 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
59 dbgprintf(0,"Error: Ethernet Encapsulation Function given bad data!\n");
62 if(old->length < sizeof(struct ether_header) || new->length < sizeof(struct ether_header)){
63 dbgprintf(0, "Error: Ethernet Encapsulation Function given packet of wrong size!\n");
67 /*Copy Ethernet header over*/
68 memcpy(new->data, old->data, sizeof(struct ether_header));
71 ethh=(struct ether_header*)(new->data);
73 /*Adjust pointers and lengths*/
74 nold.data= old->data+ sizeof(struct ether_header);
75 nnew.data= new->data + sizeof(struct ether_header);
76 nold.length= old->length - sizeof(struct ether_header);
77 nnew.length= new->length - sizeof(struct ether_header);
81 /*Select Next Protocol*/
82 switch(ntohs(ethh->ether_type)){
84 if(!ipv4_encap(&nnew, &nold)){
89 if(!ipv6_encap(&nnew, &nold)){
94 dbgprintf(1, "Unknown Next Protocol at Ethernet\n");
100 new->length=nnew.length + sizeof(struct ether_header);
104 /*IPv6 Encapsulation*/
105 int ipv6_encap(struct packet *new, const struct const_packet *old)
109 struct const_packet nold;
112 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
113 dbgprintf(0,"Error: IPv6 Encapsulation Function given bad data!\n");
116 if(old->length < sizeof(struct ip6_hdr) || new->length < sizeof(struct ip6_hdr)){
117 dbgprintf(0, "Error: IPv6 Encapsulation Function given packet of wrong size!\n");
121 /*Copy IPv6 header over*/
122 memcpy(new->data, old->data, sizeof(struct ip6_hdr));
125 iph=(struct ip6_hdr*)(new->data);
127 /*Adjust pointers and lengths*/
128 nold.data= old->data + sizeof(struct ip6_hdr);
129 nnew.data= new->data +sizeof(struct ip6_hdr);
130 nold.length= old->length - sizeof(struct ip6_hdr);
131 nnew.length= new->length - sizeof(struct ip6_hdr);
135 /*Confirm that this is IPv6*/
136 if((ntohl(iph->ip6_ctlun.ip6_un1.ip6_un1_flow) & (0xF0000000)) == (60000000)){
137 dbgprintf(1, "Note: Packet is not IPv6\n");
141 /*Select Next Protocol*/
142 switch(iph->ip6_ctlun.ip6_un1.ip6_un1_nxt){
146 nnew.src_id=malloc(nnew.id_len);
147 nnew.dest_id=malloc(nnew.id_len);
148 if(nnew.src_id==NULL||nnew.dest_id==NULL){
149 dbgprintf(0,"Error: Couldn't allocate Memory\n");
152 memcpy(nnew.src_id,&iph->ip6_src,nnew.id_len);
153 memcpy(nnew.dest_id,&iph->ip6_dst,nnew.id_len);
154 if(!convert_packet(&nnew, &nold)){
159 dbgprintf(1, "Unknown Next Protocol at IPv6\n");
164 /*set ip to indicate that TCP is next protocol*/
165 iph->ip6_ctlun.ip6_un1.ip6_un1_nxt=6;
167 /*Determine if computed length is reasonable*/
168 if(nnew.length > 0xFFFF){
169 dbgprintf(1, "Error: Given TCP data length is too large for an IPv6 packet!\n");
173 /*Adjust IPv6 header to account for packet's total length*/
174 iph->ip6_ctlun.ip6_un1.ip6_un1_plen=htons(new->length);
177 new->length=nnew.length + sizeof(struct ip6_hdr);
185 /*IPv4 Encapsulation*/
186 int ipv4_encap(struct packet *new, const struct const_packet *old)
190 struct const_packet nold;
193 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
194 dbgprintf(0,"Error: IPv4 Encapsulation Function given bad data!\n");
197 if(old->length < sizeof(struct iphdr) || new->length < sizeof(struct iphdr)){
198 dbgprintf(0, "Error: IPv4 Encapsulation Function given packet of wrong size!\n");
202 /*Copy IPv4 header over*/
203 memcpy(new->data, old->data, sizeof(struct iphdr));
206 iph=(struct iphdr*)(new->data);
208 /*Adjust pointers and lengths*/
209 nold.data= old->data +iph->ihl*4;
210 nnew.data= new->data +iph->ihl*4;
211 nold.length= old->length -iph->ihl*4;
212 nnew.length= new->length -iph->ihl*4;
216 /*Confirm that this is IPv4*/
218 dbgprintf(1, "Note: Packet is not IPv4\n");
222 /*Select Next Protocol*/
223 switch(iph->protocol){
227 nnew.src_id=malloc(nnew.id_len);
228 nnew.dest_id=malloc(nnew.id_len);
229 if(nnew.src_id==NULL||nnew.dest_id==NULL){
230 dbgprintf(0,"Error: Couldn't allocate Memory\n");
233 memcpy(nnew.src_id,&iph->saddr,nnew.id_len);
234 memcpy(nnew.dest_id,&iph->daddr,nnew.id_len);
235 if(!convert_packet(&nnew, &nold)){
240 dbgprintf(1, "Unknown Next Protocol at IPv4\n");
245 /*set ip to indicate that TCP is next protocol*/
250 new->length=nnew.length + iph->ihl*4;
252 /*Determine if computed length is reasonable*/
253 if(nnew.length > 0xFFFF){
254 dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
258 /*Adjust IPv4 header to account for packet's total length*/
259 iph->tot_len=htons(new->length);
267 int linux_cooked_encap(struct packet *new, const struct const_packet *old)
269 struct sll_header *slh;
271 struct const_packet nold;
275 if(!new|| !old || !new->data || !old->data || !new->h || !old->h){
276 dbgprintf(0,"Error: SLL Encapsulation Function given bad data!\n");
279 if(old->length < sizeof(struct sll_header) || new->length < sizeof(struct sll_header)){
280 dbgprintf(0, "Error: SLL Encapsulation Function given packet of wrong size!\n");
284 /*Copy SLL header over*/
285 memcpy(new->data, old->data, sizeof(struct sll_header));
288 slh=(struct sll_header*)(new->data);
290 /*Adjust pointers and lengths*/
291 nold.data= old->data + sizeof(struct sll_header);
292 nnew.data= new->data + sizeof(struct sll_header);
293 nold.length= old->length - sizeof(struct sll_header);
294 nnew.length= new->length- sizeof(struct sll_header);
298 /*Confirm that this is SLL*/
299 if(ntohs(slh->sll_pkttype) > 4){
300 dbgprintf(1, "Note: Packet is not SLL (Linux Cooked Capture)\n");
304 /*Select Next Protocol*/
305 switch(ntohs(slh->sll_protocol)){
307 if(!ipv4_encap(&nnew, &nold)){
312 if(!ipv6_encap(&nnew, &nold)){
317 dbgprintf(1, "Unknown Next Protocol at SLL\n");
323 new->length=nnew.length + sizeof(struct sll_header);