source: mainline/uspace/lib/pcap/src/pcapctl_dump.c@ 2ebbe9b

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

nic, drvs, pcapctl

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