nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* tap_export_pdu.c |
2 | * Routines for exporting PDUs to file |
||
3 | * |
||
4 | * Wireshark - Network traffic analyzer |
||
5 | * By Gerald Combs <gerald@wireshark.org> |
||
6 | * Copyright 1998 Gerald Combs |
||
7 | * |
||
8 | * This program is free software; you can redistribute it and/or |
||
9 | * modify it under the terms of the GNU General Public License |
||
10 | * as published by the Free Software Foundation; either version 2 |
||
11 | * of the License, or (at your option) any later version. |
||
12 | * |
||
13 | * This program is distributed in the hope that it will be useful, |
||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
16 | * GNU General Public License for more details. |
||
17 | * |
||
18 | * You should have received a copy of the GNU General Public License |
||
19 | * along with this program; if not, write to the Free Software |
||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
||
21 | */ |
||
22 | |||
23 | #include "config.h" |
||
24 | |||
25 | |||
26 | #include "globals.h" |
||
27 | #include "wiretap/pcap-encap.h" |
||
28 | #include "wsutil/os_version_info.h" |
||
29 | #include "ws_version_info.h" |
||
30 | |||
31 | #include <epan/tap.h> |
||
32 | #include <epan/exported_pdu.h> |
||
33 | #include <epan/epan_dissect.h> |
||
34 | #include <wiretap/wtap.h> |
||
35 | #include <wiretap/wtap_opttypes.h> |
||
36 | #include <wiretap/pcapng.h> |
||
37 | |||
38 | #include "tap_export_pdu.h" |
||
39 | |||
40 | /* Main entry point to the tap */ |
||
41 | static gboolean |
||
42 | export_pdu_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *data) |
||
43 | { |
||
44 | const exp_pdu_data_t *exp_pdu_data = (const exp_pdu_data_t *)data; |
||
45 | exp_pdu_t *exp_pdu_tap_data = (exp_pdu_t *)tapdata; |
||
46 | struct wtap_pkthdr pkthdr; |
||
47 | int err; |
||
48 | gchar *err_info; |
||
49 | int buffer_len; |
||
50 | guint8 *packet_buf; |
||
51 | |||
52 | memset(&pkthdr, 0, sizeof(struct wtap_pkthdr)); |
||
53 | buffer_len = exp_pdu_data->tvb_captured_length + exp_pdu_data->tlv_buffer_len; |
||
54 | packet_buf = (guint8 *)g_malloc(buffer_len); |
||
55 | |||
56 | if(exp_pdu_data->tlv_buffer_len > 0){ |
||
57 | memcpy(packet_buf, exp_pdu_data->tlv_buffer, exp_pdu_data->tlv_buffer_len); |
||
58 | g_free(exp_pdu_data->tlv_buffer); |
||
59 | } |
||
60 | if(exp_pdu_data->tvb_captured_length > 0){ |
||
61 | tvb_memcpy(exp_pdu_data->pdu_tvb, packet_buf+exp_pdu_data->tlv_buffer_len, 0, exp_pdu_data->tvb_captured_length); |
||
62 | } |
||
63 | pkthdr.rec_type = REC_TYPE_PACKET; |
||
64 | pkthdr.ts.secs = pinfo->abs_ts.secs; |
||
65 | pkthdr.ts.nsecs = pinfo->abs_ts.nsecs; |
||
66 | pkthdr.caplen = buffer_len; |
||
67 | pkthdr.len = exp_pdu_data->tvb_reported_length + exp_pdu_data->tlv_buffer_len; |
||
68 | |||
69 | pkthdr.pkt_encap = exp_pdu_tap_data->pkt_encap; |
||
70 | |||
71 | if (pinfo->fd->flags.has_user_comment) |
||
72 | pkthdr.opt_comment = g_strdup(epan_get_user_comment(edt->session, pinfo->fd)); |
||
73 | else if (pinfo->fd->flags.has_phdr_comment) |
||
74 | pkthdr.opt_comment = g_strdup(pinfo->phdr->opt_comment); |
||
75 | |||
76 | pkthdr.presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID|WTAP_HAS_TS|WTAP_HAS_PACK_FLAGS; |
||
77 | |||
78 | /* XXX: should the pkthdr.pseudo_header be set to the pinfo's pseudo-header? */ |
||
79 | /* XXX: report errors! */ |
||
80 | if (!wtap_dump(exp_pdu_tap_data->wdh, &pkthdr, packet_buf, &err, &err_info)) { |
||
81 | switch (err) { |
||
82 | |||
83 | case WTAP_ERR_UNWRITABLE_REC_DATA: |
||
84 | g_free(err_info); |
||
85 | break; |
||
86 | |||
87 | default: |
||
88 | break; |
||
89 | } |
||
90 | } |
||
91 | |||
92 | g_free(packet_buf); |
||
93 | g_free(pkthdr.opt_comment); |
||
94 | |||
95 | return FALSE; /* Do not redraw */ |
||
96 | } |
||
97 | |||
98 | int |
||
99 | exp_pdu_open(exp_pdu_t *exp_pdu_tap_data, int fd, char *comment) |
||
100 | { |
||
101 | |||
102 | int err; |
||
103 | |||
104 | /* pcapng defs */ |
||
105 | wtap_block_t shb_hdr; |
||
106 | GArray *shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); |
||
107 | wtapng_iface_descriptions_t *idb_inf; |
||
108 | wtap_block_t int_data; |
||
109 | wtapng_if_descr_mandatory_t *int_data_mand; |
||
110 | GString *os_info_str; |
||
111 | gsize opt_len; |
||
112 | gchar *opt_str; |
||
113 | |||
114 | /* Create data for SHB */ |
||
115 | os_info_str = g_string_new(""); |
||
116 | get_os_version_info(os_info_str); |
||
117 | |||
118 | shb_hdr = wtap_block_create(WTAP_BLOCK_NG_SECTION); |
||
119 | |||
120 | /* options */ |
||
121 | wtap_block_add_string_option(shb_hdr, OPT_COMMENT, comment, strlen(comment)); |
||
122 | g_free(comment); |
||
123 | |||
124 | /* |
||
125 | * UTF-8 string containing the name of the operating system used to create |
||
126 | * this section. |
||
127 | */ |
||
128 | opt_len = os_info_str->len; |
||
129 | opt_str = g_string_free(os_info_str, FALSE); |
||
130 | if (opt_str) { |
||
131 | wtap_block_add_string_option(shb_hdr, OPT_SHB_OS, opt_str, opt_len); |
||
132 | g_free(opt_str); |
||
133 | } |
||
134 | /* |
||
135 | * UTF-8 string containing the name of the application used to create |
||
136 | * this section. |
||
137 | */ |
||
138 | wtap_block_add_string_option_format(shb_hdr, OPT_SHB_USERAPPL, "Wireshark %s", get_ws_vcs_version_info()); |
||
139 | |||
140 | /* Create fake IDB info */ |
||
141 | idb_inf = g_new(wtapng_iface_descriptions_t,1); |
||
142 | idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); |
||
143 | |||
144 | /* create the fake interface data */ |
||
145 | int_data = wtap_block_create(WTAP_BLOCK_IF_DESCR); |
||
146 | int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data); |
||
147 | int_data_mand->wtap_encap = WTAP_ENCAP_WIRESHARK_UPPER_PDU; |
||
148 | int_data_mand->time_units_per_second = 1000000000; /* default nanosecond resolution */ |
||
149 | int_data_mand->link_type = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU); |
||
150 | int_data_mand->snap_len = WTAP_MAX_PACKET_SIZE; |
||
151 | |||
152 | wtap_block_add_string_option(int_data, OPT_IDB_NAME, "Fake IF, PDU->Export", strlen("Fake IF, PDU->Export")); |
||
153 | wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 9); |
||
154 | |||
155 | g_array_append_val(idb_inf->interface_data, int_data); |
||
156 | |||
157 | g_array_append_val(shb_hdrs, shb_hdr); |
||
158 | |||
159 | /* Use a random name for the temporary import buffer */ |
||
160 | exp_pdu_tap_data->wdh = wtap_dump_fdopen_ng(fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG, WTAP_ENCAP_WIRESHARK_UPPER_PDU, WTAP_MAX_PACKET_SIZE, FALSE, |
||
161 | shb_hdrs, idb_inf, NULL, &err); |
||
162 | if (exp_pdu_tap_data->wdh == NULL) { |
||
163 | g_assert(err != 0); |
||
164 | return err; |
||
165 | } |
||
166 | |||
167 | return 0; |
||
168 | } |
||
169 | |||
170 | int |
||
171 | exp_pdu_close(exp_pdu_t *exp_pdu_tap_data) |
||
172 | { |
||
173 | int err = 0; |
||
174 | if (!wtap_dump_close(exp_pdu_tap_data->wdh, &err)) |
||
175 | g_assert(err != 0); |
||
176 | |||
177 | remove_tap_listener(exp_pdu_tap_data); |
||
178 | return err; |
||
179 | } |
||
180 | |||
181 | |||
182 | char * |
||
183 | exp_pdu_pre_open(const char *tap_name, const char *filter, exp_pdu_t *exp_pdu_tap_data) |
||
184 | { |
||
185 | GString *error_string; |
||
186 | |||
187 | /* XXX: can we always assume WTAP_ENCAP_WIRESHARK_UPPER_PDU? */ |
||
188 | exp_pdu_tap_data->pkt_encap = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU); |
||
189 | |||
190 | /* Register this tap listener now */ |
||
191 | error_string = register_tap_listener(tap_name, /* The name of the tap we want to listen to */ |
||
192 | exp_pdu_tap_data, /* instance identifier/pointer to a struct holding |
||
193 | * all state variables */ |
||
194 | filter, /* pointer to a filter string */ |
||
195 | TL_REQUIRES_PROTO_TREE, /* flags for the tap listener */ |
||
196 | NULL, |
||
197 | export_pdu_packet, |
||
198 | NULL); |
||
199 | if (error_string != NULL) |
||
200 | return g_string_free(error_string, FALSE); |
||
201 | |||
202 | return NULL; |
||
203 | } |
||
204 | |||
205 | |||
206 | /* |
||
207 | * Editor modelines |
||
208 | * |
||
209 | * Local Variables: |
||
210 | * c-basic-offset: 4 |
||
211 | * tab-width: 8 |
||
212 | * indent-tabs-mode: nil |
||
213 | * End: |
||
214 | * |
||
215 | * ex: set shiftwidth=4 tabstop=8 expandtab: |
||
216 | * :indentSize=4:tabSize=8:noTabs=true: |
||
217 | */ |