source: mainline/uspace/lib/pcap/src/pcapdump_client.c@ 31d2aee

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

create drv iface for drivers

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