File: ec_packet.c

package info (click to toggle)
ettercap 1:0.8.2-10
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 5,468 kB
  • ctags: 6,333
  • sloc: ansic: 47,337; yacc: 310; lex: 204; makefile: 121; xml: 31; sh: 24
file content (212 lines) | stat: -rw-r--r-- 5,705 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/*
    ettercap -- packet object handling

    Copyright (C) ALoR & NaGA

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

#include <ec.h>
#include <ec_packet.h>
#include <ec_inet.h>
#include <ec_ui.h>
#include <ec_format.h>

/* --------------------------- */

struct packet_object* packet_allocate_object(u_char *data, u_int len)
{
   struct packet_object *po;

   SAFE_CALLOC(po, 1, sizeof(struct packet_object));
   packet_create_object(po, data, len);
   po->flags |= PO_FORGED;
   
   return po;
}

/*
 * associate the buffer to the packet object
 */

inline int packet_create_object(struct packet_object *po, u_char *buf, u_int len)
{
   /* clear the memory */
   memset(po, 0, sizeof(struct packet_object));
   
   /* set the buffer and the len of the received packet */
   po->packet = buf;
   po->len = len;
   
   return (0);
}

/*
 * allocate the buffer for disp data
 *
 * disp data is useful when the protocol is
 * encrypted and we want to forward the packet as is
 * but display the decrypted data.
 * decoders should decrypt data from po->DATA.data to po->DATA.disp_data
 */

int packet_disp_data(struct packet_object *po, u_char *buf, u_int len)
{
   /* disp_data is always null terminated */
   if (len + 1) {
      if(po->DATA.disp_data)
        SAFE_FREE(po->DATA.disp_data);
      SAFE_CALLOC(po->DATA.disp_data, len + 1, sizeof(u_char));
   } else {
      ERROR_MSG("packet_disp_data() negative len");
   }

   po->DATA.disp_len = len;
   memcpy(po->DATA.disp_data, buf, len);

   return len;
}

/*
 * free the packet object memory
 */

inline int packet_destroy_object(struct packet_object *po)
{
   
   /* 
    * the packet is a duplicate
    * we have to free even the packet buffer.
    * alse free data directed to top_half
    */
   if (po->flags & PO_DUP) {
     
      SAFE_FREE(po->packet);
      
      /* 
       * free the dissector info 
       * during the duplication, the pointers where
       * passed to the dup, so we have to free them
       * here.
       */
      SAFE_FREE(po->DISSECTOR.user);
      SAFE_FREE(po->DISSECTOR.pass);
      SAFE_FREE(po->DISSECTOR.content);
      SAFE_FREE(po->DISSECTOR.info);
      SAFE_FREE(po->DISSECTOR.banner);
      SAFE_FREE(po->DISSECTOR.os);
   }
      
   /* 
    * free the disp_data pointer
    * it was malloced by tcp or udp decoder.
    * If the packet was duplicated, disp_data points to NULL
    * (the dup func set it)
    * because the duplicate points to the real data and will 
    * free them.
    */
   SAFE_FREE(po->DATA.disp_data);

   /* if it is alloced entirely by ourselves */
   if(po->flags & PO_FORGED) {
      SAFE_FREE(po->packet);
      SAFE_FREE(po);
   }
   
   return 0;
}


/*
 * duplicate a po and return
 * the new allocated one
 */
struct packet_object * packet_dup(struct packet_object *po, u_char flag)
{
   struct packet_object *dup_po;

   SAFE_CALLOC(dup_po, 1, sizeof(struct packet_object));

   /* 
    * copy the po over the dup_po 
    * but this is not sufficient, we have to adjust all 
    * the pointer to the po->packet.
    * so allocate a new packet, then recalculate the
    * pointers
    */
   memcpy(dup_po, po, sizeof(struct packet_object));

   /*
    * We set disp_data to NULL to avoid free in the 
    * original packet. Descending decoder chain doesn't
    * care about disp_data. top_half will free it when 
    * necessary, destroying the packet duplicate.
    */
   dup_po->DATA.disp_data = po->DATA.disp_data;
   po->DATA.disp_data = NULL;
   po->DATA.disp_len = 0;
   
   /* copy only if the buffer exists */
   if ( (flag & PO_DUP_PACKET) && po->packet != NULL) {  
      /* duplicate the po buffer */
      SAFE_CALLOC(dup_po->packet, po->len, sizeof(u_char));
  
      /* copy the buffer */
      memcpy(dup_po->packet, po->packet, po->len);
   } else {
      dup_po->len = 0;
      dup_po->packet = NULL;
   }

   /* 
    * If we want to duplicate packet content we don't want 
    * user, pass, etc. Otherwise we would free them twice
    * (they are freed by the other duplicate into top half).
    */      
   if (flag & PO_DUP_PACKET) {
      dup_po->DISSECTOR.user = NULL;
      dup_po->DISSECTOR.pass = NULL;
      dup_po->DISSECTOR.info = NULL;
      dup_po->DISSECTOR.banner = NULL;
      dup_po->DISSECTOR.os = NULL;
   }
   
   /* 
    * adjust all the pointers as the difference
    * between the old buffer and the pointer
    */
   dup_po->L2.header = dup_po->packet + (po->L2.header - po->packet);
   
   dup_po->L3.header = dup_po->packet + (po->L3.header - po->packet);
   dup_po->L3.options = dup_po->packet + (po->L3.options - po->packet);
   
   dup_po->L4.header = dup_po->packet + (po->L4.header - po->packet);
   dup_po->L4.options = dup_po->packet + (po->L4.options - po->packet);
   
   dup_po->DATA.data = dup_po->packet + (po->DATA.data - po->packet);

   dup_po->fwd_packet = dup_po->packet + (po->fwd_packet - po->packet);

   /* this packet is a duplicate */
   dup_po->flags |= PO_DUP;

   return dup_po;
}

   
/* EOF */

// vim:ts=3:expandtab