can-eth-gw-utils Utilities  0.1
A bidirectional CAN to Ethernet Gateway (Utilities)
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
main.c
Go to the documentation of this file.
1 
13 /*****************************************************************************
14  * (C) Copyright 2013 Fabian Raab, Stefan Smarzly
15  *
16  * This file is part of CAN-Eth-GW.
17  *
18  * CAN-Eth-GW is free software: you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation, either version 3 of the License, or
21  * (at your option) any later version.
22  *
23  * CAN-Eth-GW is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with CAN-Eth-GW. If not, see <http://www.gnu.org/licenses/>.
30  *****************************************************************************/
31 
32 #include <errno.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 /* man getopt or
37  http://www.gnu.org/software/libc/manual/html_node/Getopt.html */
38 #include <getopt.h>
39 #include <stdint.h>
40 #include <inttypes.h>
41 #include "netlink.h"
42 
45 uint32_t flags = 0;
46 uint8_t gw_type = TYPE_NET;
47 
48 int main(int argc, char *argv[])
49 {
50  int err = 0;
51 
52  err = nl_sk_fam_init();
53  if (err != 0) {
54  fprintf(stderr,
55  "Error during initialisation of Socket or Netlink "
56  "Family: %d\n", err);
57  return EXIT_FAILURE;
58  }
59 
60  int c;
61 
62  while (1) {
63  static struct option long_options[] = {
64  /* These options set a flag. */
65 
66  /* These options don't set a flag.
67  We distinguish them by their indices. */
68  {"bidirectional", no_argument, 0, 'b'},
69  {"can-fd", no_argument, 0, 'f'},
70  {"type", required_argument, 0, 't'},
71  {0, 0, 0, 0},
72  };
73  /* getopt_long stores the option index here. */
74  int option_index = 0;
75 
76  c = getopt_long (argc, argv, "bft:",
77  long_options, &option_index);
78 
79  /* Detect the end of the options. */
80  if (c == -1)
81  break;
82 
83  switch (c) {
84  case 0:
85  /* If this option set a flag, do nothing else now. */
86  if (long_options[option_index].flag != 0)
87  break;
88  printf ("option %s", long_options[option_index].name);
89 
90  if (optarg)
91  printf (" with arg %s", optarg);
92  printf ("\n");
93  break;
94 
95  case 'b':
97  break;
98 
99  case 'f':
100  flags = flags | F_CAN_FD;
101  break;
102 
103  case 't':
104  if(!strcmp(optarg, "none")) {
105  gw_type = TYPE_NONE;
106  } else if(!strcmp(optarg, "eth")) {
107  gw_type = TYPE_ETH;
108  } else if (!strcmp(optarg, "net")) {
109  gw_type = TYPE_NET;
110  } else if (!strcmp(optarg, "tcp")) {
111  gw_type = TYPE_TCP;
112  } else if (!strcmp(optarg, "udp")) {
113  gw_type = TYPE_UDP;
114  } else {
115  fprintf(stderr, "%s: Supported Types: "
116  "none, eth, net, tcp, udp\n", argv[0]);
117  return EXIT_FAILURE;
118  }
119 
120  break;
121 
122  case '?':
123  /* getopt_long already printed an error message. */
124  break;
125 
126  default:
127  abort();
128  }
129  }
130 
131  /* Instead of reporting ‘--verbose’
132  and ‘--brief’ as they are encountered,
133  we report the final status resulting from them. */
134  if (verbose_flag)
135  puts ("verbose flag is set\n");
136 
137 
138  /***************************************************/
139  /* Remaining command line arguments (not options). */
140  /***************************************************/
141  while (optind < argc) {
142 
143  /* add route SRC DST */
144  if(!strcmp(argv[optind], "add") &&
145  !strcmp(argv[optind+1], "route") && optind+4 <= argc) {
146 
147  err = ce_gw_add(argv[optind+3], argv[optind+2],
148  gw_type, flags);
149  if (err != 0) {
150  fprintf(stderr, "%s: Error during add: %d",
151  argv[0], err);
152  return EXIT_FAILURE;
153  }
154 
155  if (bidirectional_flag == 1) {
156  err = ce_gw_add(argv[optind+2], argv[optind+3],
157  gw_type, flags);
158  if (err != 0) {
159  fprintf(stderr, "%s: Error during "
160  "add: %d", argv[0], err);
161  return EXIT_FAILURE;
162  }
163  }
164 
165  optind += 4;
166 
167  /* add dev [NAME] */
168  } else if (!strcmp(argv[optind], "add") &&
169  !strcmp(argv[optind+1], "dev") && optind+2 <= argc) {
170 
171  if (optind+3 <= argc) {
172  err = ce_gw_add(argv[optind+2], NULL, gw_type,
173  flags);
174  if (err != 0) {
175  fprintf(stderr, "%s: Error during "
176  "add: %d", argv[0], err);
177  return EXIT_FAILURE;
178  }
179 
180  optind += 3;
181  } else {
182 
183  err = ce_gw_add("cegw%d", NULL, gw_type, flags);
184  if (err != 0) {
185  fprintf(stderr, "%s: Error during "
186  "add: %d", argv[0], err);
187  return EXIT_FAILURE;
188  }
189 
190  optind += 2;
191  }
192 
193  /* del route ID */
194  } else if(!strcmp(argv[optind], "del") &&
195  !strcmp(argv[optind+1], "route") && optind+3 <= argc ) {
196 
197  uintmax_t num = strtoumax(argv[optind+2], NULL, 0);
198  if (num == UINTMAX_MAX && errno == ERANGE) {
199  fprintf(stderr, "%s: Error: Parameter "
200  "ID is not a number %d\n",
201  argv[0], errno);
202  }
203 
204  err = ce_gw_del((uint32_t) num, NULL);
205  if (err != 0) {
206  fprintf(stderr, "%s: Error during del: %d\n",
207  argv[0], err);
208  return EXIT_FAILURE;
209  }
210 
211  optind += 3;
212 
213  /* del dev DEV_NAME */
214  } else if(!strcmp(argv[optind], "del") &&
215  !strcmp(argv[optind+1], "dev") && optind+3 <= argc ) {
216 
217  err = ce_gw_del(0, argv[optind+2]);
218  if (err != 0) {
219  fprintf(stderr, "%s: Error during del: %d\n",
220  argv[0], err);
221  return EXIT_FAILURE;
222  }
223 
224  optind += 3;
225 
226  /* echo MSG */
227  } else if(!strcmp(argv[optind], "echo") && optind+2 <= argc) {
228 
229  err = ce_gw_echo(argv[optind+1]);
230  if (err != 0) {
231  fprintf(stderr, "%s: Error during echo: %d",
232  argv[0], err);
233  return EXIT_FAILURE;
234  }
235 
236  optind += 2;
237 
238  /* route */
239  } else if(!strcmp(argv[optind], "route") && optind+1 <= argc) {
240 
241  if (optind+2 <= argc) {
242  uintmax_t num = strtoumax(argv[optind+1],
243  NULL, 0);
244  if (num == UINTMAX_MAX && errno == ERANGE) {
245  fprintf(stderr, "%s: Error: Parameter "
246  "ID is not a number %d\n",
247  argv[0], errno);
248  }
249 
250  err = ce_gw_list(num);
251  optind += 2;
252 
253  } else {
254  err = ce_gw_list(0);
255  optind += 1;
256  }
257 
258  if (err != 0) {
259  fprintf(stderr, "%s: Error during list: %d",
260  argv[0], err);
261  return EXIT_FAILURE;
262  }
263 
264 
265  /* unrecognized command */
266  } else {
267  optind += 1;
268 
269  while(optind < argc) {
270  printf(" %s", argv[optind]);
271  optind += 1;
272  }
273 
274  printf("'\n");
275  return EXIT_FAILURE;
276  }
277  }
278 
279  nl_sk_fam_exit();
280  return EXIT_SUCCESS;
281 }
282