Initial Commit
[ltp2tcp] / dccp_encap.c
1 /******************************************************************************
2 Author: Samuel Jero
3
4 Date: 12/2010
5
6 Description:  <ETH, IPv4, DCCP> encapsulation functions
7
8 ******************************************************************************/
9 #include "ltp2tcp.h"
10 #include <linux/dccp.h>
11
12
13
14 extern int debug;
15
16
17
18 /* encapsulation manipulation previous to packet conversion */
19 int dccp_encap_pre(struct pcap_pkthdr *h, const u_char **odata, u_char **ndata, int* olength, int* nlength)
20 {
21         struct iphdr                    *iph;
22         struct ether_header             *ethh;
23         struct dccp_hdr                 *dccph;
24
25         /*Safety checks*/
26         if(!h || !odata || !ndata || !*odata || !*ndata || !olength || !nlength){
27                 dbgprintf(0,"Error: DCCP Encapsulation given bad data!\n");
28                 exit(1);
29         }
30         if(*olength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct dccp_hdr )
31                         || *nlength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct tcphdr)){
32                         dbgprintf(0, "Error: DCCP Encapsulation given packet of wrong size!\n");
33                         return -1;
34         }
35
36         /*Determine what type of DCCP packet this is*/
37         dccph=(struct dccp_hdr*) (*odata + sizeof(struct ether_header)+sizeof(struct iphdr));
38         if(dccph->dccph_type!=DCCP_PKT_DATA && dccph->dccph_type!=DCCP_PKT_DATAACK){
39                 /*Packet Contains no data, discard*/
40                 dbgprintf(2, "Note: DCCP Encapsulation discarding non-data-carrying packet. Type: %i\n", dccph->dccph_type);
41                 return -1;
42         }
43
44         /*We have a data carrying packet, proceed to process*/
45
46
47         /*initialize encapsulation private data*/
48         if(state.en_priv==NULL){
49                 /* First time, allocate memory and copy libpcap header and encap headers
50                  * this guarantees the IP "direction" of the encap headers */
51                 state.en_priv=malloc(sizeof(struct eip4_en_p));
52                 if(state.en_priv==NULL){
53                         dbgprintf(0,"Error: Couldn't allocate Memory\n");
54                         exit(1);
55                 }
56         }
57         if(fill_eip4_encap((struct eip4_en_p*)state.en_priv, *odata, *olength, h)<0){
58                 return -1;
59         }
60
61         /*Copy Ethernet and IPv4 headers over*/
62         memcpy(*ndata, *odata, sizeof(struct ether_header)+sizeof(struct iphdr));
63         *odata+=sizeof(struct ether_header)+ sizeof(struct iphdr);
64         *ndata+=sizeof(struct ether_header)+ sizeof(struct iphdr);
65
66         /*Confirm that this is Ethernet and that IPv4 is next*/
67         ethh=(struct ether_header*)(*odata -sizeof(struct ether_header)- sizeof(struct iphdr));
68         if(ethh->ether_type!=htons(ETHERTYPE_IP)){
69                 dbgprintf(1, "Note: Packet not Ethernet or Not IPv4 next\n");
70                 return -1;
71         }
72
73         /* Check That this is IPv4 and that DCCP is next*/
74         iph= (struct iphdr *) (*ndata - sizeof(struct iphdr));
75         if(iph->version!=4){
76                 dbgprintf(1, "Note: Packet is not IPv4\n");
77                 return -1;
78         }
79         if(iph->protocol!=33){
80                 dbgprintf(1, "Note: Packet is not DCCP\n");
81                 return -1;
82         }
83
84         /*set IP to indicate that TCP is next protocol*/
85         iph->protocol=6;
86         iph->check=htonl(0);
87
88         /* Adjust libpcap headers*/
89         h->caplen=sizeof(struct ether_header) +sizeof(struct iphdr);
90         h->len=sizeof(struct ether_header) +sizeof(struct iphdr);
91
92         /*Adjust packet length*/
93         *olength=ntohs(iph->tot_len) - dccph->dccph_doff*4;
94
95         /*Adjust New Packet Length*/
96         *nlength-=sizeof(struct ether_header) +sizeof(struct iphdr);
97
98         /*Move Packet Pointer past DCCP header*/
99         *odata+=dccph->dccph_doff*4;
100
101         return 0;
102 }
103
104 /* encapsulation manipulation after conversion */
105 int dccp_encap_post(int tlen, u_char *data)
106 {
107         return eip4_post((struct eip4_en_p*)state.en_priv, tlen, data);
108 }
109
110 /* Create a TCP three-way handshake */
111 int dccp_encap_handshake(struct pcap_pkthdr *h)
112 {
113         return eip4_handshake((struct eip4_en_p*)state.en_priv, h);
114 }
115
116 /* Create a TCP ending handshake */
117 int dccp_encap_fin()
118 {
119         return eip4_fin((struct eip4_en_p*)state.en_priv);
120 }
121
122
123
124
125 /* The DCCP Encapsulation Structure*/
126 struct encap_ops dccp_encap = {
127         .pre=dccp_encap_pre,
128         .post=dccp_encap_post,
129         .handshake=dccp_encap_handshake,
130         .fin=dccp_encap_fin
131 };