1 /******************************************************************************
6 Description: <ETH, IPv4, DCCP> encapsulation functions
8 ******************************************************************************/
10 #include <linux/dccp.h>
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)
22 struct ether_header *ethh;
23 struct dccp_hdr *dccph;
26 if(!h || !odata || !ndata || !*odata || !*ndata || !olength || !nlength){
27 dbgprintf(0,"Error: DCCP Encapsulation given bad data!\n");
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");
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);
44 /*We have a data carrying packet, proceed to process*/
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");
57 if(fill_eip4_encap((struct eip4_en_p*)state.en_priv, *odata, *olength, h)<0){
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);
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");
73 /* Check That this is IPv4 and that DCCP is next*/
74 iph= (struct iphdr *) (*ndata - sizeof(struct iphdr));
76 dbgprintf(1, "Note: Packet is not IPv4\n");
79 if(iph->protocol!=33){
80 dbgprintf(1, "Note: Packet is not DCCP\n");
84 /*set IP to indicate that TCP is next protocol*/
88 /* Adjust libpcap headers*/
89 h->caplen=sizeof(struct ether_header) +sizeof(struct iphdr);
90 h->len=sizeof(struct ether_header) +sizeof(struct iphdr);
92 /*Adjust packet length*/
93 *olength=ntohs(iph->tot_len) - dccph->dccph_doff*4;
95 /*Adjust New Packet Length*/
96 *nlength-=sizeof(struct ether_header) +sizeof(struct iphdr);
98 /*Move Packet Pointer past DCCP header*/
99 *odata+=dccph->dccph_doff*4;
104 /* encapsulation manipulation after conversion */
105 int dccp_encap_post(int tlen, u_char *data)
107 return eip4_post((struct eip4_en_p*)state.en_priv, tlen, data);
110 /* Create a TCP three-way handshake */
111 int dccp_encap_handshake(struct pcap_pkthdr *h)
113 return eip4_handshake((struct eip4_en_p*)state.en_priv, h);
116 /* Create a TCP ending handshake */
119 return eip4_fin((struct eip4_en_p*)state.en_priv);
125 /* The DCCP Encapsulation Structure*/
126 struct encap_ops dccp_encap = {
128 .post=dccp_encap_post,
129 .handshake=dccp_encap_handshake,