source: mainline/uspace/lib/pcap/src/pcapdump_client.c@ 373dded

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

docs comments

  • Property mode set to 100644
File size: 6.7 KB
RevLine 
[17a8fcf]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 */
[87b490e3]32/** @file Client side of the pcapctl. Functions are called from the app pcapctl.
[17a8fcf]33 */
34
35#include <errno.h>
36#include <async.h>
37#include <str.h>
38#include <stdlib.h>
[7924f82]39#include <stdio.h>
40#include <ctype.h>
[f161ce1]41#include "pcapdump_client.h"
[e1e8f7a]42#include "pcapdump_ipc.h"
[17a8fcf]43
44/** Finish an async exchange on the pcapctl session
45 *
46 * @param exch Exchange to be finished
47 */
48static void pcapctl_dump_exchange_end(async_exch_t *exch)
49{
50 async_exchange_end(exch);
51}
52
[87b490e3]53/** Get service based on the index of the device.
54 * @param index of the device.
55 * @param svc placeholder for service ide.
56 * @return EOK if successful, error code otherwise.
57 */
[0210d42d]58static errno_t pcapctl_cat_get_svc(int *index, service_id_t *svc)
59{
60 errno_t rc;
61 category_id_t pcap_cat;
62 size_t count;
63 service_id_t *pcap_svcs = NULL;
64
65 rc = loc_category_get_id("pcap", &pcap_cat, 0);
66 if (rc != EOK) {
[e5b2777]67 fprintf(stderr, "Error resolving category 'pcap'.\n");
[0210d42d]68 return rc;
69 }
70
71 rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count);
72 if (rc != EOK) {
[e5b2777]73 fprintf(stderr, "Error resolving list of pcap services.\n");
[0210d42d]74 free(pcap_svcs);
75 return rc;
76 }
77 if (*index < (int)count) {
78 *svc = pcap_svcs[*index];
79 free(pcap_svcs);
80 return EOK;
81 }
82
83 return ENOENT;
84}
[91042127]85
[87b490e3]86/** Check if the index is an index of valid device.
87 * @param index to check.
88 * @return EOK if device is valid, error code otherwise.
89 */
[9e26790]90errno_t pcapctl_is_valid_device(int *index)
[2ebbe9b]91{
[91042127]92 errno_t rc;
93 category_id_t pcap_cat;
94 size_t count;
95 service_id_t *pcap_svcs = NULL;
96
97 rc = loc_category_get_id("pcap", &pcap_cat, 0);
[17a8fcf]98 if (rc != EOK) {
[e5b2777]99 fprintf(stderr, "Error resolving category pcap.\n");
[91042127]100 return rc;
[17a8fcf]101 }
102
[91042127]103 rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count);
104 if (rc != EOK) {
[e5b2777]105 fprintf(stderr, "Error resolving list of pcap services.\n");
[8765039]106 free(pcap_svcs);
[91042127]107 return rc;
108 }
[9e26790]109 if (*index + 1 > (int)count || *index < 0) {
110 return EINVAL;
[91042127]111 }
112 return EOK;
113}
114
[87b490e3]115/** Check if the index is an index of valid writer operations.
116 * @param index to check.
117 * @param sess pcapctl session for IPC communictaion.
118 */
[fb31682]119errno_t pcapctl_is_valid_ops_number(int *index, pcapctl_sess_t *sess)
[e1e8f7a]120{
121 async_exch_t *exch = async_exchange_begin(sess->sess);
122 ipc_call_t answer;
123 aid_t req = async_send_0(exch, PCAP_CONTROL_GET_OPS_NUM, &answer);
124
125 async_exchange_end(exch);
126
127 errno_t retval;
128 async_wait_for(req, &retval);
129
130 if (retval != EOK) {
131 return retval;
132 }
133
134 int ops_count = (int)ipc_get_arg1(&answer);
[fb31682]135 if (*index + 1 > ops_count || *index < 0) {
[e1e8f7a]136 return EINVAL;
137 }
138 return EOK;
139}
140
[87b490e3]141/** Get all devices that can dump packets. */
[9e26790]142errno_t pcapctl_list(void)
[2ebbe9b]143{
[7924f82]144 errno_t rc;
145 category_id_t pcap_cat;
146 size_t count;
147 service_id_t *pcap_svcs = NULL;
148
149 rc = loc_category_get_id("pcap", &pcap_cat, 0);
150 if (rc != EOK) {
[e5b2777]151 fprintf(stderr, "Error resolving category pcap.\n");
[7924f82]152 return rc;
153 }
154
155 rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count);
156 if (rc != EOK) {
[e5b2777]157 fprintf(stderr, "Error resolving list of pcap services.\n");
[7924f82]158 free(pcap_svcs);
159 return rc;
160 }
161
[9e26790]162 fprintf(stdout, "Devices:\n");
163 for (unsigned i = 0; i < count; ++i) {
164 char *name = NULL;
165 loc_service_get_name(pcap_svcs[i], &name);
166 fprintf(stdout, "%d. %s\n", i, name);
[7924f82]167 }
[9e26790]168 free(pcap_svcs);
[7924f82]169 return EOK;
170}
171
[87b490e3]172/** Start pcapctl IPC session.
173 * @param index index of the device which can dump packets.
174 * @param rsess placeholder for the session.
175 * @return EOK if successful, error code otherwise.
[7924f82]176 */
[9e26790]177errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess)
[91042127]178{
179 errno_t rc;
180 service_id_t svc;
[8765039]181 pcapctl_sess_t *sess = calloc(1, sizeof(pcapctl_sess_t));
182 if (sess == NULL)
183 return ENOMEM;
184
[0210d42d]185 if (*index == -1) {
[03cd7a9e]186 *index = 0;
[0210d42d]187 }
[03cd7a9e]188
189 rc = pcapctl_cat_get_svc(index, &svc);
190 if (rc != EOK) {
[e5b2777]191 fprintf(stderr, "Error finding the device with index: %d\n", *index);
[03cd7a9e]192 goto error;
[0210d42d]193 }
[6c60a7c]194
[91042127]195 async_sess_t *new_session = loc_service_connect(svc, INTERFACE_PCAP_CONTROL, 0);
[17a8fcf]196 if (new_session == NULL) {
[91042127]197 fprintf(stderr, "Error connecting to service.\n");
[17a8fcf]198 rc = EREFUSED;
199 goto error;
200 }
[0210d42d]201
[17a8fcf]202 sess->sess = new_session;
[8765039]203 *rsess = sess;
204 return EOK;
[17a8fcf]205error:
[8765039]206 pcapctl_dump_close(sess);
[17a8fcf]207 return rc;
208}
209
[87b490e3]210/** Close pcapctl IPC session.
211 * @param sess Session to close.
212 * @return EOK if successful, error code otherwise.
[7924f82]213 */
[8765039]214errno_t pcapctl_dump_close(pcapctl_sess_t *sess)
215{
216 free(sess);
217 return EOK;
218}
219
[87b490e3]220/** Send start request via IPC to start dumping.
[17a8fcf]221 *
[87b490e3]222 * @param name Name of the destination buffer to dump packets to.
223 * @param sess Session that is used for communication.
224 * @return EOK on success or an error code.
[17a8fcf]225 */
[e1e8f7a]226errno_t pcapctl_dump_start(const char *name, int *ops_index, pcapctl_sess_t *sess)
[17a8fcf]227{
228 errno_t rc;
229 async_exch_t *exch = async_exchange_begin(sess->sess);
230
231 size_t size = str_size(name);
[e1e8f7a]232 aid_t req = async_send_1(exch, PCAP_CONTROL_SET_START, *ops_index, NULL);
[17a8fcf]233
[1d14090]234 rc = async_data_write_start(exch, name, size);
[17a8fcf]235
236 pcapctl_dump_exchange_end(exch);
237
238 if (rc != EOK) {
239 async_forget(req);
240 return rc;
241 }
242
243 errno_t retval;
244 async_wait_for(req, &retval);
245 return retval;
246}
247
[87b490e3]248/** Send stop request via IPC to start dumping.
[17a8fcf]249 *
[87b490e3]250 * @param sess Session that is used for communication.
251 * @return EOK on success or an error code.
[17a8fcf]252 */
253errno_t pcapctl_dump_stop(pcapctl_sess_t *sess)
254{
255 errno_t rc;
256 async_exch_t *exch = async_exchange_begin(sess->sess);
257 rc = async_req_0_0(exch, PCAP_CONTROL_SET_STOP);
258
259 pcapctl_dump_exchange_end(exch);
260 return rc;
261}
262
263/** @}
264 */
Note: See TracBrowser for help on using the repository browser.