source: mainline/uspace/lib/pcap/src/pcap_dumper.c@ e1e8f7a

Last change on this file since e1e8f7a was e1e8f7a, checked in by Nataliia Korop <n.corop08@…>, 10 months ago

set ops as number and with start req

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*
2 * Copyright (c) 2023 Nataliia Korop
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libpcap
30 * @{
31 */
32/** @file
33 * @brief pcap inteface: Dumping interface for the device which packets we want to dump
34 */
35
36#include <errno.h>
37#include <str.h>
38#include <io/log.h>
39#include "pcap_dumper.h"
40
41#define SHORT_OPS_BYTE_COUNT 60
42#define NAME "pcap"
43
44/** Initialize writing to .pcap file.
45 *
46 * @param writer Interface for working with .pcap file.
47 * @param filename Name of the file for dumping packets.
48 * @return EOK on success or an error code.
49 *
50 */
51static errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename)
52{
53 writer->data = fopen(filename, "a");
54 if (writer->data == NULL) {
55 return EINVAL;
56 }
57 pcap_writer_add_header(writer);
58
59 return EOK;
60}
61
62static errno_t pcap_writer_to_file_init_append(pcap_writer_t *writer, const char *filename)
63{
64 writer->data = fopen(filename, "a");
65 if (writer->data == NULL) {
66 return EINVAL;
67 }
68
69 return EOK;
70}
71
72static size_t pcap_file_w32(pcap_writer_t *writer, uint32_t data)
73{
74 return fwrite(&data, 1, 4, (FILE *)writer->data);
75}
76
77static size_t pcap_file_w16(pcap_writer_t *writer, uint16_t data)
78{
79 return fwrite(&data, 1, 2, (FILE *)writer->data);
80}
81
82static size_t pcap_file_wbuffer(pcap_writer_t *writer, const void *data, size_t size)
83{
84 assert(writer->data);
85 return fwrite(data, 1, size, (FILE *)writer->data);
86}
87
88static void pcap_file_close(pcap_writer_t *writer)
89{
90 fclose((FILE *)writer->data);
91 writer->data = NULL;
92}
93
94static const pcap_writer_ops_t file_ops = {
95 .open = &pcap_writer_to_file_init,
96 .write_u32 = &pcap_file_w32,
97 .write_u16 = &pcap_file_w16,
98 .write_buffer = &pcap_file_wbuffer,
99 .close = &pcap_file_close
100};
101
102static size_t pcap_short_file_wbuffer(pcap_writer_t *writer, const void *data, size_t size)
103{
104 return fwrite(data, 1, size < 60 ? size : 60, (FILE *)writer->data); //define
105}
106
107static const pcap_writer_ops_t short_file_ops = {
108 .open = &pcap_writer_to_file_init,
109 .write_u32 = &pcap_file_w32,
110 .write_u16 = &pcap_file_w16,
111 .write_buffer = &pcap_short_file_wbuffer,
112 .close = &pcap_file_close
113
114};
115
116static const pcap_writer_ops_t append_file_ops = {
117 .open = &pcap_writer_to_file_init_append,
118 .write_u32 = &pcap_file_w32,
119 .write_u16 = &pcap_file_w16,
120 .write_buffer = &pcap_file_wbuffer,
121 .close = &pcap_file_close
122};
123
124static pcap_writer_ops_t ops[3] = {file_ops, short_file_ops, append_file_ops};
125
126int pcap_dumper_get_ops_number(void)
127{
128 return (int)(sizeof(ops) / sizeof(pcap_writer_ops_t));
129}
130
131errno_t pcap_dumper_start(struct pcap_dumper *dumper, const char *name)
132{
133 fibril_mutex_lock(&dumper->mutex);
134
135 /** When try to start when already started, close current and starts new */
136 if (dumper->to_dump) {
137 pcap_dumper_stop(dumper);
138 }
139
140 errno_t rc = dumper->writer.ops->open(&dumper->writer, name);
141 if (rc == EOK) {
142 dumper->to_dump = true;
143 }
144
145 fibril_mutex_unlock(&dumper->mutex);
146 return rc;
147}
148
149errno_t pcap_dumper_set_ops(struct pcap_dumper *dumper, int index)
150{
151 fibril_mutex_lock(&dumper->mutex);
152 errno_t rc = EOK;
153 dumper->writer.ops = &ops[index];
154 fibril_mutex_unlock(&dumper->mutex);
155 return rc;
156}
157
158void pcap_dumper_add_packet(struct pcap_dumper *dumper, const void *data, size_t size)
159{
160 fibril_mutex_lock(&dumper->mutex);
161
162 if (!dumper->to_dump) {
163 fibril_mutex_unlock(&dumper->mutex);
164 return;
165 }
166
167 pcap_writer_add_packet(&dumper->writer, data, size);
168 fibril_mutex_unlock(&dumper->mutex);
169}
170
171void pcap_dumper_stop(struct pcap_dumper *dumper)
172{
173 fibril_mutex_lock(&dumper->mutex);
174
175 /** If want to stop, when already stopped, do nothing */
176 if (!dumper->to_dump) {
177 fibril_mutex_unlock(&dumper->mutex);
178 return;
179 }
180 dumper->to_dump = false;
181 dumper->writer.ops->close(&dumper->writer);
182 fibril_mutex_unlock(&dumper->mutex);
183}
184
185/** Initialize interface for dumping packets
186 *
187 * @param dumper Device dumping interface
188 *
189 */
190errno_t pcap_dumper_init(pcap_dumper_t *dumper)
191{
192 fibril_mutex_initialize(&dumper->mutex);
193 dumper->to_dump = false;
194 dumper->writer.ops = NULL;
195
196 errno_t rc = log_init(NAME);
197 if (rc != EOK) {
198 printf("%s : Failed to initialize log.\n", NAME);
199 return 1;
200 }
201 return EOK;
202}
203
204/** @}
205 */
Note: See TracBrowser for help on using the repository browser.