source: mainline/uspace/app/pcapctl/main.c@ 87b490e3

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

docs comments

  • Property mode set to 100644
File size: 7.3 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 pcapctl
30 * @{
31 */
[87b490e3]32/** @file pcapctl command-line utility.
[17a8fcf]33 */
34
35#include <stdio.h>
36#include <str.h>
37#include <errno.h>
[9e26790]38#include <arg_parse.h>
39#include <getopt.h>
[28ed2d89]40#include <vfs/vfs.h>
[17a8fcf]41
[f161ce1]42#include "pcapdump_client.h"
[17a8fcf]43
[87b490e3]44#define NAME "pcapctl"
45#define DEFAULT_DEV_NUM 0
46#define DECIMAL_SYSTEM 10
[17a8fcf]47
[87b490e3]48/* Default writer operations for dumper, must be consistent with array defined in /uspace/lib/pcap/pcap_dumper.c */
49#define DEFAULT_FILE_OPS 0
50#define SHORT_FILE_OPS 1
51#define APPEND_FILE_OPS 2
52#define USB_FILE_OPS 3
[fb31682]53
[87b490e3]54/** Create async session and send start request.
55 * @param dev_number index of the device that can dump packets.
56 * @param name of the output buffer.
57 * @param ops_index index of the writer operations for the dumper.
58 * @return EOK if all parameters are valid and start request was sent successfully, error code otherwise.
59 */
[e1e8f7a]60static errno_t start_dumping(int *dev_number, const char *name, int *ops_index)
[17a8fcf]61{
[2ebbe9b]62 pcapctl_sess_t *sess = NULL;
[9e26790]63 errno_t rc = pcapctl_dump_open(dev_number, &sess);
[91042127]64 if (rc != EOK) {
65 return 1;
66 }
[7924f82]67
[e1e8f7a]68 rc = pcapctl_is_valid_ops_number(ops_index, sess);
[fb31682]69 if (rc != EOK) {
[e1e8f7a]70 printf("Wrong number of ops: %d.\n", *ops_index);
71 pcapctl_dump_close(sess);
72 return rc;
73 }
74
75 rc = pcapctl_dump_start(name, ops_index, sess);
[64ea525]76 if (rc != EOK) {
[fb31682]77 if (rc == EBUSY) {
78 printf("Dumping for device %d is in process, stop to start dumping to file %s.\n", *dev_number, name);
79 }
[1d14090]80 printf("Starting the dumping was not successful.\n");
81 }
[8765039]82 pcapctl_dump_close(sess);
[91042127]83 return EOK;
[17a8fcf]84}
85
[87b490e3]86/** Create async session and send stop dumping request.
87 * @param dev_numbe index of the device on which the dumping will be stopped.
88 * @return EOK if request was sent successfully, error code otherwise.
89 */
[9e26790]90static errno_t stop_dumping(int *dev_number)
[17a8fcf]91{
[2ebbe9b]92 pcapctl_sess_t *sess = NULL;
[9e26790]93 errno_t rc = pcapctl_dump_open(dev_number, &sess);
[91042127]94 if (rc != EOK) {
95 return 1;
96 }
[1d14090]97 rc = pcapctl_dump_stop(sess);
[64ea525]98 if (rc != EOK) {
[1d14090]99 printf("Stoping the dumping was not successful.\n");
100 }
101 pcapctl_dump_close(sess);
102 return EOK;
103}
104
[87b490e3]105/** Print devices that can dump packets. */
[2ebbe9b]106static void list_devs(void)
107{
[91042127]108 pcapctl_list();
[17a8fcf]109}
110
[9e26790]111/**
112 * Array of supported commandline options
113 */
114static const struct option opts[] = {
[87b490e3]115 { "append", required_argument, 0, 'A' }, /* file as argument and ops 0 if not exist and 2 if exists */
116 { "new", required_argument, 0, 'N' }, /* file name as argument */
[fb31682]117 { "truncated", required_argument, 0, 'T' }, // truncated ops
118 { "usb", required_argument, 0, 'U' }, //??
[9e26790]119 { "device", required_argument, 0, 'd' },
120 { "list", no_argument, 0, 'l' },
121 { "help", no_argument, 0, 'h' },
[28ed2d89]122 { "outfile", required_argument, 0, 'o' },
[9e26790]123 { "start", no_argument, 0, 'r' },
124 { "stop", no_argument, 0, 't' },
[28ed2d89]125 { "ops", required_argument, 0, 'p' },
[fb31682]126 { "force", no_argument, 0, 'f' },
[9e26790]127 { 0, 0, 0, 0 }
128};
129
[87b490e3]130/** Check if the file exists.
131 * @param path of the file to check.
132 * @return true if exists, false otherwise.
133 */
[28ed2d89]134static bool file_exists(const char *path)
135{
136 vfs_stat_t stats;
[fb31682]137 if (vfs_stat_path(path, &stats) != EOK) {
138 return false;
139 } else {
140 return true;
141 }
[28ed2d89]142}
143
[7924f82]144static void usage(void)
[17a8fcf]145{
[87b490e3]146 printf("HelenOS Packet Dumping utility.\n"
147 "Usage:\n"
[9e26790]148 NAME " --list | -l \n"
[2ebbe9b]149 "\tList of devices\n"
[fb31682]150 NAME " --start | -r --device= | -d <device number from list> --outfile= | -o <outfile> --ops= | p <ops index>\n"
[2ebbe9b]151 "\tPackets dumped from device will be written to <outfile>\n"
[fb31682]152 NAME " --stop | -t --device= | -d <device number from list>\n"
[2ebbe9b]153 "\tDumping from <device> stops\n"
[fb31682]154 NAME " --start | -r --outfile= | -o <outfile>\n"
[fd6845e9]155 "\tPackets dumped from the 0. device from the list will be written to <outfile>\n"
[2ebbe9b]156 NAME " --help | -h\n"
[fb31682]157 "\tShow this application help.\n"
158 NAME " --force | -f"
159 "\tTo open existing file and write to it.\n");
[17a8fcf]160}
161
162int main(int argc, char *argv[])
163{
[9e26790]164 bool start = false;
165 bool stop = false;
[28ed2d89]166 int dev_number = DEFAULT_DEV_NUM;
[fb31682]167 int ops_number = DEFAULT_FILE_OPS;
[28ed2d89]168 bool forced = false;
[03cd7a9e]169 const char *output_file_name = "";
[9e26790]170 int idx = 0;
171 int ret = 0;
172 if (argc == 1) {
[7924f82]173 usage();
[9e26790]174 return 0;
175 }
176 while (ret != -1) {
[fb31682]177 ret = getopt_long(argc, argv, "A:N:T:U:d:lho:rtp:f", opts, &idx);
[9e26790]178 switch (ret) {
[f08447b]179 case 'd':
180 char *rest;
[e1e8f7a]181 long dev_result = strtol(optarg, &rest, DECIMAL_SYSTEM);
182 dev_number = (int)dev_result;
[f08447b]183 errno_t rc = pcapctl_is_valid_device(&dev_number);
184 if (rc != EOK) {
185 printf("Device with index %d not found\n", dev_number);
186 return 1;
[91042127]187 }
[f08447b]188 break;
[fb31682]189 case 'A':
190 output_file_name = optarg;
191 if (file_exists(output_file_name)) {
192 ops_number = APPEND_FILE_OPS;
193 }
194 break;
195 case 'N':
196 output_file_name = optarg;
197 break;
198 case 'T':
199 output_file_name = optarg;
200 ops_number = SHORT_FILE_OPS;
201 break;
202 case 'U':
203 output_file_name = optarg;
204 ops_number = USB_FILE_OPS;
205 break;
[f08447b]206 case 'l':
207 list_devs();
208 return 0;
209 case 'h':
210 usage();
211 return 0;
[28ed2d89]212 case 'o':
[f08447b]213 output_file_name = optarg;
214 break;
215 case 'r':
216 start = true;
217 break;
218 case 't':
219 stop = true;
220 break;
[28ed2d89]221 case 'p':
[fb31682]222 char *ops_inval;
[e1e8f7a]223 long ops_result = strtol(optarg, &ops_inval, DECIMAL_SYSTEM);
224 ops_number = (int)ops_result;
[1d14090]225 break;
[28ed2d89]226 case 'f':
227 forced = true;
228 break;
[17a8fcf]229 }
230 }
[9e26790]231
[fb31682]232 if (!str_cmp(output_file_name, "") && start) {
233 printf("Dumping destination was not specified. Specify with --outfile | -o\n");
234 return 1;
235 }
236
[9e26790]237 if (start) {
[28ed2d89]238
[fb31682]239 if (file_exists(output_file_name) && !forced && ops_number != 2) {
240 printf("File %s already exists. If you want to overwrite to it, then use flag --force.\n", output_file_name);
[28ed2d89]241 return 0;
242 }
243
[87b490e3]244 printf("Sarting dumping on device - %d, ops - %d.\n", dev_number, ops_number);
245
[f08447b]246 /* start with dev number and name */
[e1e8f7a]247 start_dumping(&dev_number, output_file_name, &ops_number);
[9e26790]248 } else if (stop) {
[f08447b]249 /* stop with dev number */
[87b490e3]250 printf("Stopping dumping on device - %d, ops - %d.\n", dev_number, ops_number);
[9e26790]251 stop_dumping(&dev_number);
[28ed2d89]252 } else {
253 usage();
[fb31682]254 return 1;
[1d14090]255 }
[17a8fcf]256 return 0;
257}
258
259/** @}
260 */
Note: See TracBrowser for help on using the repository browser.