1 /*
2     ettercap -- packet object handling
3 
4     Copyright (C) ALoR & NaGA
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 
20 */
21 
22 #include <ec.h>
23 #include <ec_packet.h>
24 #include <ec_inet.h>
25 #include <ec_ui.h>
26 #include <ec_format.h>
27 
28 /* --------------------------- */
29 
packet_allocate_object(u_char * data,u_int len)30 struct packet_object* packet_allocate_object(u_char *data, u_int len)
31 {
32    struct packet_object *po;
33 
34    SAFE_CALLOC(po, 1, sizeof(struct packet_object));
35    packet_create_object(po, data, len);
36    po->flags |= PO_FORGED;
37 
38    return po;
39 }
40 
41 /*
42  * associate the buffer to the packet object
43  */
44 
packet_create_object(struct packet_object * po,u_char * buf,u_int len)45 int packet_create_object(struct packet_object *po, u_char *buf, u_int len)
46 {
47    /* clear the memory */
48    memset(po, 0, sizeof(struct packet_object));
49 
50    /* set the buffer and the len of the received packet */
51    po->packet = buf;
52    po->len = len;
53 
54    return (0);
55 }
56 
57 /*
58  * allocate the buffer for disp data
59  *
60  * disp data is useful when the protocol is
61  * encrypted and we want to forward the packet as is
62  * but display the decrypted data.
63  * decoders should decrypt data from po->DATA.data to po->DATA.disp_data
64  */
65 
packet_disp_data(struct packet_object * po,u_char * buf,u_int len)66 int packet_disp_data(struct packet_object *po, u_char *buf, u_int len)
67 {
68    /* disp_data is always null terminated */
69    if (len + 1) {
70       if(po->DATA.disp_data)
71         SAFE_FREE(po->DATA.disp_data);
72       SAFE_CALLOC(po->DATA.disp_data, len + 1, sizeof(u_char));
73    } else {
74       ERROR_MSG("packet_disp_data() negative len");
75    }
76 
77    po->DATA.disp_len = len;
78    memcpy(po->DATA.disp_data, buf, len);
79 
80    return len;
81 }
82 
83 /*
84  * free the packet object memory
85  */
86 
packet_destroy_object(struct packet_object * po)87 int packet_destroy_object(struct packet_object *po)
88 {
89 
90    /*
91     * the packet is a duplicate
92     * we have to free even the packet buffer.
93     * alse free data directed to top_half
94     */
95    if (po->flags & PO_DUP) {
96 
97       SAFE_FREE(po->packet);
98 
99       /*
100        * free the dissector info
101        * during the duplication, the pointers where
102        * passed to the dup, so we have to free them
103        * here.
104        */
105       SAFE_FREE(po->DISSECTOR.user);
106       SAFE_FREE(po->DISSECTOR.pass);
107       SAFE_FREE(po->DISSECTOR.content);
108       SAFE_FREE(po->DISSECTOR.info);
109       SAFE_FREE(po->DISSECTOR.banner);
110       SAFE_FREE(po->DISSECTOR.os);
111    }
112 
113    /*
114     * free the disp_data pointer
115     * it was malloced by tcp or udp decoder.
116     * If the packet was duplicated, disp_data points to NULL
117     * (the dup func set it)
118     * because the duplicate points to the real data and will
119     * free them.
120     */
121    SAFE_FREE(po->DATA.disp_data);
122 
123    /* if it is alloced entirely by ourselves */
124    if(po->flags & PO_FORGED) {
125       SAFE_FREE(po->packet);
126       SAFE_FREE(po);
127    }
128 
129    return 0;
130 }
131 
132 
133 /*
134  * duplicate a po and return
135  * the new allocated one
136  */
packet_dup(struct packet_object * po,u_char flag)137 struct packet_object * packet_dup(struct packet_object *po, u_char flag)
138 {
139    struct packet_object *dup_po;
140 
141    SAFE_CALLOC(dup_po, 1, sizeof(struct packet_object));
142 
143    /*
144     * copy the po over the dup_po
145     * but this is not sufficient, we have to adjust all
146     * the pointer to the po->packet.
147     * so allocate a new packet, then recalculate the
148     * pointers
149     */
150    memcpy(dup_po, po, sizeof(struct packet_object));
151 
152    /*
153     * We set disp_data to NULL to avoid free in the
154     * original packet. Descending decoder chain doesn't
155     * care about disp_data. top_half will free it when
156     * necessary, destroying the packet duplicate.
157     */
158    dup_po->DATA.disp_data = po->DATA.disp_data;
159    po->DATA.disp_data = NULL;
160    po->DATA.disp_len = 0;
161 
162    /* copy only if the buffer exists */
163    if ( (flag & PO_DUP_PACKET) && po->packet != NULL) {
164       /* duplicate the po buffer */
165       SAFE_CALLOC(dup_po->packet, po->len, sizeof(u_char));
166 
167       /* copy the buffer */
168       memcpy(dup_po->packet, po->packet, po->len);
169    } else {
170       dup_po->len = 0;
171       dup_po->packet = NULL;
172    }
173 
174    /*
175     * If we want to duplicate packet content we don't want
176     * user, pass, etc. Otherwise we would free them twice
177     * (they are freed by the other duplicate into top half).
178     */
179    if (flag & PO_DUP_PACKET) {
180       dup_po->DISSECTOR.user = NULL;
181       dup_po->DISSECTOR.pass = NULL;
182       dup_po->DISSECTOR.info = NULL;
183       dup_po->DISSECTOR.banner = NULL;
184       dup_po->DISSECTOR.os = NULL;
185    }
186 
187    /*
188     * adjust all the pointers as the difference
189     * between the old buffer and the pointer
190     */
191    dup_po->L2.header = dup_po->packet + (po->L2.header - po->packet);
192 
193    dup_po->L3.header = dup_po->packet + (po->L3.header - po->packet);
194    dup_po->L3.options = dup_po->packet + (po->L3.options - po->packet);
195 
196    dup_po->L4.header = dup_po->packet + (po->L4.header - po->packet);
197    dup_po->L4.options = dup_po->packet + (po->L4.options - po->packet);
198 
199    dup_po->DATA.data = dup_po->packet + (po->DATA.data - po->packet);
200 
201    dup_po->fwd_packet = dup_po->packet + (po->fwd_packet - po->packet);
202 
203    /* this packet is a duplicate */
204    dup_po->flags |= PO_DUP;
205 
206    return dup_po;
207 }
208 
209 
210 /* EOF */
211 
212 // vim:ts=3:expandtab
213