source: mainline/uspace/app/nic/nic.c@ bd76871

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since bd76871 was b7fd2a0, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

Use errno_t in all uspace and kernel code.

Change type of every variable, parameter and return value that holds an
<errno.h> constant to either errno_t (the usual case), or sys_errno_t
(some places in kernel). This is for the purpose of self-documentation,
as well as for type-checking with a bit of type definition hackery.

Although this is a massive commit, it is a simple text replacement, and thus
is very easy to verify. Simply do the following:

`
git checkout <this commit's hash>
git reset HEAD
git add .
tools/srepl '\berrno_t\b' int
git add .
tools/srepl '\bsys_errno_t\b' sysarg_t
git reset
git diff
`

While this doesn't ensure that the replacements are correct, it does ensure
that the commit doesn't do anything except those replacements. Since errno_t
is typedef'd to int in the usual case (and sys_errno_t to sysarg_t), even if
incorrect, this commit cannot change behavior.

  • Property mode set to 100644
File size: 13.4 KB
Line 
1/*
2 * Copyright (c) 2014 Jiri Svoboda
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 nic
30 * @{
31 */
32/** @file NIC configuration utility.
33 *
34 */
35
36#include <errno.h>
37#include <loc.h>
38#include <nic_iface.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <stddef.h>
42#include <str_error.h>
43
44#define NAME "nic"
45
46typedef struct {
47 nic_device_info_t device_info;
48 nic_address_t address;
49 nic_cable_state_t link_state;
50 nic_channel_mode_t duplex;
51 nic_unicast_mode_t unicast_mode;
52 nic_multicast_mode_t multicast_mode;
53 nic_broadcast_mode_t broadcast_mode;
54 int speed;
55} nic_info_t;
56
57static void print_syntax(void)
58{
59 printf("syntax:\n");
60 printf("\t" NAME " [<index> <cmd> [<args...>]]\n");
61 printf("\t<index> is NIC index number reported by the tool\n");
62 printf("\t<cmd> is:\n");
63 printf("\taddr <mac_address> - set MAC address\n");
64 printf("\tspeed <10|100|1000> - set NIC speed\n");
65 printf("\tduplex <half|full|simplex> - set duplex mode\n");
66 printf("\tauto - enable autonegotiation\n");
67 printf("\tunicast <block|default|list|promisc> - set unicast receive filtering\n");
68 printf("\tmulticast <block|list|promisc> - set multicast receive filtering\n");
69 printf("\tbroadcast <block|allow> - block or allow incoming broadcast frames\n");
70}
71
72static async_sess_t *get_nic_by_index(size_t i)
73{
74 errno_t rc;
75 size_t count;
76 char *svc_name;
77 category_id_t nic_cat;
78 service_id_t *nics = NULL;
79 async_sess_t *sess;
80
81 rc = loc_category_get_id("nic", &nic_cat, 0);
82 if (rc != EOK) {
83 printf("Error resolving category 'nic'.\n");
84 goto error;
85 }
86
87 rc = loc_category_get_svcs(nic_cat, &nics, &count);
88 if (rc != EOK) {
89 printf("Error getting list of NICs.\n");
90 goto error;
91 }
92
93 rc = loc_service_get_name(nics[i], &svc_name);
94 if (rc != EOK) {
95 printf("Error getting service name.\n");
96 goto error;
97 }
98
99 printf("Using device: %s\n", svc_name);
100
101 sess = loc_service_connect(nics[i], INTERFACE_DDF, 0);
102 if (sess == NULL) {
103 printf("Error connecting to service.\n");
104 goto error;
105 }
106
107 return sess;
108error:
109 return NULL;
110}
111
112static errno_t nic_get_info(service_id_t svc_id, char *svc_name,
113 nic_info_t *info)
114{
115 async_sess_t *sess;
116 nic_role_t role;
117 errno_t rc;
118
119 sess = loc_service_connect(svc_id, INTERFACE_DDF, 0);
120 if (sess == NULL) {
121 printf("Error connecting to service.\n");
122 rc = EIO;
123 goto error;
124 }
125
126 rc = nic_get_address(sess, &info->address);
127 if (rc != EOK) {
128 printf("Error getting NIC address.\n");
129 rc = EIO;
130 goto error;
131 }
132
133 rc = nic_get_device_info(sess, &info->device_info);
134 if (rc != EOK) {
135 printf("Error getting NIC device info.\n");
136 rc = EIO;
137 goto error;
138 }
139
140 rc = nic_get_cable_state(sess, &info->link_state);
141 if (rc != EOK) {
142 printf("Error getting link state.\n");
143 rc = EIO;
144 goto error;
145 }
146
147 rc = nic_get_operation_mode(sess, &info->speed, &info->duplex, &role);
148 if (rc != EOK) {
149 printf("Error getting NIC speed and duplex mode.\n");
150 rc = EIO;
151 goto error;
152 }
153
154 rc = nic_unicast_get_mode(sess, &info->unicast_mode, 0, NULL, NULL);
155 if (rc != EOK) {
156 printf("Error gettinc NIC unicast receive mode.\n");
157 rc = EIO;
158 goto error;
159 }
160
161 rc = nic_multicast_get_mode(sess, &info->multicast_mode, 0, NULL, NULL);
162 if (rc != EOK) {
163 printf("Error gettinc NIC multicast receive mode.\n");
164 rc = EIO;
165 goto error;
166 }
167
168 rc = nic_broadcast_get_mode(sess, &info->broadcast_mode);
169 if (rc != EOK) {
170 printf("Error gettinc NIC broadcast receive mode.\n");
171 rc = EIO;
172 goto error;
173 }
174
175 return EOK;
176error:
177 return rc;
178}
179
180static const char *nic_link_state_str(nic_cable_state_t link_state)
181{
182 switch (link_state) {
183 case NIC_CS_UNKNOWN: return "unknown";
184 case NIC_CS_PLUGGED: return "up";
185 case NIC_CS_UNPLUGGED: return "down";
186 default: assert(false); return NULL;
187 }
188}
189
190static const char *nic_duplex_mode_str(nic_channel_mode_t mode)
191{
192 switch (mode) {
193 case NIC_CM_FULL_DUPLEX: return "full-duplex";
194 case NIC_CM_HALF_DUPLEX: return "half-duplex";
195 case NIC_CM_SIMPLEX: return "simplex";
196 default: assert(false); return NULL;
197 }
198}
199
200static const char *nic_unicast_mode_str(nic_unicast_mode_t mode)
201{
202 switch (mode) {
203 case NIC_UNICAST_UNKNOWN: return "unknown";
204 case NIC_UNICAST_BLOCKED: return "blocked";
205 case NIC_UNICAST_DEFAULT: return "default";
206 case NIC_UNICAST_LIST: return "list";
207 case NIC_UNICAST_PROMISC: return "promisc";
208 default: assert(false); return NULL;
209 }
210}
211
212static const char *nic_multicast_mode_str(nic_multicast_mode_t mode)
213{
214 switch (mode) {
215 case NIC_MULTICAST_UNKNOWN: return "unknown";
216 case NIC_MULTICAST_BLOCKED: return "blocked";
217 case NIC_MULTICAST_LIST: return "list";
218 case NIC_MULTICAST_PROMISC: return "promisc";
219 default: assert(false); return NULL;
220 }
221}
222
223static const char *nic_broadcast_mode_str(nic_broadcast_mode_t mode)
224{
225 switch (mode) {
226 case NIC_BROADCAST_UNKNOWN: return "unknown";
227 case NIC_BROADCAST_BLOCKED: return "blocked";
228 case NIC_BROADCAST_ACCEPTED: return "accepted";
229 default: assert(false); return NULL;
230 }
231}
232
233static char *nic_addr_format(nic_address_t *a)
234{
235 int rc;
236 char *s;
237
238 rc = asprintf(&s, "%02x:%02x:%02x:%02x:%02x:%02x",
239 a->address[0], a->address[1], a->address[2],
240 a->address[3], a->address[4], a->address[5]);
241 if (rc < 0)
242 return NULL;
243
244 return s;
245}
246
247static errno_t nic_list(void)
248{
249 category_id_t nic_cat;
250 service_id_t *nics = NULL;
251 nic_info_t nic_info;
252 size_t count, i;
253 char *svc_name;
254 char *addr_str;
255 errno_t rc;
256
257 rc = loc_category_get_id("nic", &nic_cat, 0);
258 if (rc != EOK) {
259 printf("Error resolving category 'nic'.\n");
260 goto error;
261 }
262
263 rc = loc_category_get_svcs(nic_cat, &nics, &count);
264 if (rc != EOK) {
265 printf("Error getting list of NICs.\n");
266 goto error;
267 }
268
269 printf("[Index]: [Service Name]\n");
270 for (i = 0; i < count; i++) {
271 rc = loc_service_get_name(nics[i], &svc_name);
272 if (rc != EOK) {
273 printf("Error getting service name.\n");
274 goto error;
275 }
276
277 rc = nic_get_info(nics[i], svc_name, &nic_info);
278 if (rc != EOK)
279 goto error;
280
281 addr_str = nic_addr_format(&nic_info.address);
282 if (addr_str == NULL) {
283 printf("Out of memory.\n");
284 rc = ENOMEM;
285 goto error;
286 }
287
288 printf("%zu: %s\n", i, svc_name);
289 printf("\tMAC address: %s\n", addr_str);
290 printf("\tVendor name: %s\n",
291 nic_info.device_info.vendor_name);
292 printf("\tModel name: %s\n",
293 nic_info.device_info.model_name);
294 printf("\tLink state: %s\n",
295 nic_link_state_str(nic_info.link_state));
296 printf("\tUnicast receive mode: %s\n",
297 nic_unicast_mode_str(nic_info.unicast_mode));
298 printf("\tMulticast receive mode: %s\n",
299 nic_multicast_mode_str(nic_info.multicast_mode));
300 printf("\tBroadcast receive mode: %s\n",
301 nic_broadcast_mode_str(nic_info.broadcast_mode));
302
303 if (nic_info.link_state == NIC_CS_PLUGGED) {
304 printf("\tSpeed: %dMbps %s\n", nic_info.speed,
305 nic_duplex_mode_str(nic_info.duplex));
306 }
307
308 free(svc_name);
309 free(addr_str);
310 }
311
312 return EOK;
313error:
314 free(nics);
315 return rc;
316}
317
318static errno_t nic_set_speed(int i, char *str)
319{
320 async_sess_t *sess;
321 uint32_t speed;
322 int oldspeed;
323 nic_channel_mode_t oldduplex;
324 nic_role_t oldrole;
325 errno_t rc;
326
327 rc = str_uint32_t(str, NULL, 10, false, &speed);
328 if (rc != EOK) {
329 printf("Speed must be a numeric value.\n");
330 return rc;
331 }
332
333 if (speed != 10 && speed != 100 && speed != 1000) {
334 printf("Speed must be one of: 10, 100, 1000.\n");
335 return EINVAL;
336 }
337
338 sess = get_nic_by_index(i);
339 if (sess == NULL) {
340 printf("Specified NIC doesn't exist or cannot connect to it.\n");
341 return EINVAL;
342 }
343
344 rc = nic_get_operation_mode(sess, &oldspeed, &oldduplex, &oldrole);
345 if (rc != EOK) {
346 printf("Error getting NIC speed and duplex mode.\n");
347 return EIO;
348 }
349
350 return nic_set_operation_mode(sess, speed, oldduplex, oldrole);
351}
352
353static errno_t nic_set_duplex(int i, char *str)
354{
355 async_sess_t *sess;
356 int oldspeed;
357 nic_channel_mode_t duplex = NIC_CM_UNKNOWN;
358 nic_channel_mode_t oldduplex;
359 nic_role_t oldrole;
360 errno_t rc;
361
362 if (!str_cmp(str, "half"))
363 duplex = NIC_CM_HALF_DUPLEX;
364
365 if (!str_cmp(str, "full"))
366 duplex = NIC_CM_FULL_DUPLEX;
367
368 if (!str_cmp(str, "simplex"))
369 duplex = NIC_CM_SIMPLEX;
370
371 if (duplex == NIC_CM_UNKNOWN) {
372 printf("Invalid duplex specification.\n");
373 return EINVAL;
374 }
375
376 sess = get_nic_by_index(i);
377 if (sess == NULL) {
378 printf("Specified NIC doesn't exist or cannot connect to it.\n");
379 return EINVAL;
380 }
381
382 rc = nic_get_operation_mode(sess, &oldspeed, &oldduplex, &oldrole);
383 if (rc != EOK) {
384 printf("Error getting NIC speed and duplex mode.\n");
385 return EIO;
386 }
387
388 return nic_set_operation_mode(sess, oldspeed, duplex, oldrole);
389}
390
391static errno_t nic_set_autoneg(int i)
392{
393 async_sess_t *sess;
394 errno_t rc;
395
396 sess = get_nic_by_index(i);
397 if (sess == NULL) {
398 printf("Specified NIC doesn't exist or cannot connect to it.\n");
399 return EINVAL;
400 }
401
402 rc = nic_autoneg_restart(sess);
403 if (rc != EOK) {
404 printf("Error restarting NIC autonegotiation.\n");
405 return EIO;
406 }
407
408 return EOK;
409}
410
411static errno_t nic_set_addr(int i, char *str)
412{
413 async_sess_t *sess;
414 nic_address_t addr;
415 errno_t rc;
416 int idx;
417
418 sess = get_nic_by_index(i);
419 if (sess == NULL) {
420 printf("Specified NIC doesn't exist or cannot connect to it.\n");
421 return EINVAL;
422 }
423
424 if (str_size(str) != 17) {
425 printf("Invalid MAC address specified");
426 return EINVAL;
427 }
428
429 for (idx = 0; idx < 6; idx++) {
430 rc = str_uint8_t(&str[idx * 3], NULL, 16, false, &addr.address[idx]);
431 if (rc != EOK) {
432 printf("Invalid MAC address specified");
433 return EINVAL;
434 }
435 }
436
437 return nic_set_address(sess, &addr);
438}
439
440static errno_t nic_set_rx_unicast(int i, char *str)
441{
442 async_sess_t *sess;
443
444 sess = get_nic_by_index(i);
445 if (sess == NULL) {
446 printf("Specified NIC doesn't exist or cannot connect to it.\n");
447 return EINVAL;
448 }
449
450 if (!str_cmp(str, "block")) {
451 nic_unicast_set_mode(sess, NIC_UNICAST_BLOCKED, NULL, 0);
452 return EOK;
453 }
454
455 if (!str_cmp(str, "default")) {
456 nic_unicast_set_mode(sess, NIC_UNICAST_DEFAULT, NULL, 0);
457 return EOK;
458 }
459
460 if (!str_cmp(str, "list")) {
461 nic_unicast_set_mode(sess, NIC_UNICAST_LIST, NULL, 0);
462 return EOK;
463 }
464
465 if (!str_cmp(str, "promisc")) {
466 nic_unicast_set_mode(sess, NIC_UNICAST_PROMISC, NULL, 0);
467 return EOK;
468 }
469
470
471 printf("Invalid pameter - should be one of: block, default, promisc\n");
472 return EINVAL;
473}
474
475static errno_t nic_set_rx_multicast(int i, char *str)
476{
477 async_sess_t *sess;
478
479 sess = get_nic_by_index(i);
480 if (sess == NULL) {
481 printf("Specified NIC doesn't exist or cannot connect to it.\n");
482 return EINVAL;
483 }
484
485 if (!str_cmp(str, "block")) {
486 nic_multicast_set_mode(sess, NIC_MULTICAST_BLOCKED, NULL, 0);
487 return EOK;
488 }
489
490 if (!str_cmp(str, "list")) {
491 nic_multicast_set_mode(sess, NIC_MULTICAST_LIST, NULL, 0);
492 return EOK;
493 }
494
495 if (!str_cmp(str, "promisc")) {
496 nic_multicast_set_mode(sess, NIC_MULTICAST_PROMISC, NULL, 0);
497 return EOK;
498 }
499
500 printf("Invalid pameter - should be one of: block, promisc\n");
501 return EINVAL;
502}
503
504static errno_t nic_set_rx_broadcast(int i, char *str)
505{
506 async_sess_t *sess;
507
508 sess = get_nic_by_index(i);
509 if (sess == NULL) {
510 printf("Specified NIC doesn't exist or cannot connect to it.\n");
511 return EINVAL;
512 }
513
514 if (!str_cmp(str, "block")) {
515 nic_broadcast_set_mode(sess, NIC_BROADCAST_BLOCKED);
516 return EOK;
517 }
518
519 if (!str_cmp(str, "accept")) {
520 nic_broadcast_set_mode(sess, NIC_BROADCAST_ACCEPTED);
521 return EOK;
522 }
523
524 printf("Invalid pameter - should be 'block' or 'accept'\n");
525 return EINVAL;
526}
527
528int main(int argc, char *argv[])
529{
530 errno_t rc;
531 uint32_t index;
532
533 if (argc == 1) {
534 rc = nic_list();
535 if (rc != EOK)
536 return 1;
537 } else if (argc >= 3) {
538 rc = str_uint32_t(argv[1], NULL, 10, false, &index);
539 if (rc != EOK) {
540 printf(NAME ": Invalid argument.\n");
541 print_syntax();
542 return 1;
543 }
544
545 if (!str_cmp(argv[2], "addr"))
546 return nic_set_addr(index, argv[3]);
547
548 if (!str_cmp(argv[2], "speed"))
549 return nic_set_speed(index, argv[3]);
550
551 if (!str_cmp(argv[2], "duplex"))
552 return nic_set_duplex(index, argv[3]);
553
554 if (!str_cmp(argv[2], "auto"))
555 return nic_set_autoneg(index);
556
557 if (!str_cmp(argv[2], "unicast"))
558 return nic_set_rx_unicast(index, argv[3]);
559
560 if (!str_cmp(argv[2], "multicast"))
561 return nic_set_rx_multicast(index, argv[3]);
562
563 if (!str_cmp(argv[2], "broadcast"))
564 return nic_set_rx_broadcast(index, argv[3]);
565
566 } else {
567 printf(NAME ": Invalid argument.\n");
568 print_syntax();
569 return 1;
570 }
571
572 return 0;
573}
574
575/** @}
576 */
Note: See TracBrowser for help on using the repository browser.