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
Netlink
int ce_gw_add (char *dst_name, char *src_name, uint8_t type, uint32_t flags)
 add a virtual ethernet device or a route More...
 
int ce_gw_del (uint32_t id, char *dev_name)
 Deletes a device or a route in Kernel Module. More...
 
int ce_gw_list (uint32_t id)
 Print informations of actual active routes to stdout. More...
 
int ce_gw_echo (char *message)
 send a message and return the received message from Kernel. (for testing) More...
 
int nl_sk_fam_init (void)
 creakte socket and family and connect More...
 
void nl_sk_fam_exit (void)
 freeing the alloccated memory. The Function free the memory allocated by nl_sk_fam_init(). More...
 

Detailed Description

Function Documentation

int ce_gw_add ( char *  src_name,
char *  dst_name,
uint8_t  type,
uint32_t  flags 
)

add a virtual ethernet device or a route

Parameters
dst_nameThe textual name of the device wich will be the dst. OR the name of the device, if you want to add a device.
src_nameThe textual name of the device wich will be the src. Must be NULL if you want do add a device.
typeThe Type of the route. For adding dev some settings according to the type will be set.
flagsThe Flags of the route. For adding dev some settings according to the type will be set. See netlink.h for the falgs.
See Also
related callbacks: nl_cb_general_errno()

Definition at line 212 of file netlink.c.

References CE_GW_A_DST, CE_GW_A_FLAGS, CE_GW_A_MAX, CE_GW_A_SRC, CE_GW_A_TYPE, CE_GW_C_ADD, ce_gw_genl_policy, genl_fam, IFACE_VERSION, nl_sk, NO_FLAG, and USER_HDR_SIZE.

Referenced by main().

213 {
214  int err = 0;
215  struct nl_msg *msg;
216 
217  /* create */
218  msg = nlmsg_alloc();
219  if(msg == NULL) {
220  fprintf(stderr,"add: Message allocation failed.\n");
221  return -ENOMEM;
222  }
223 
224  void *user_hdr;
225  user_hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ,
226  genl_family_get_id(genl_fam), USER_HDR_SIZE,
228  if (user_hdr == NULL)
229  fprintf(stderr, "add: Message Haeder creation failed\n");
230 
231  if (src_name != NULL) { /* indicates that it is add route command */
232  NLA_PUT_STRING(msg, CE_GW_A_SRC, src_name);
233  } /* else it is add dev command */
234 
235  /* Attributes needed by both, add route and add dev */
236  NLA_PUT_STRING(msg, CE_GW_A_DST, dst_name);
237  NLA_PUT_U8(msg, CE_GW_A_TYPE, type);
238  NLA_PUT_U32(msg, CE_GW_A_FLAGS, flags);
239 
240  /* vaildate */
241  struct nlmsghdr *msghdr = nlmsg_hdr(msg);
242  err = genlmsg_validate(msghdr, USER_HDR_SIZE,
244  if (err != 0) {
245  fprintf(stderr, "add: Validation of Message Failed: %i\n", err);
246  return -1;
247  }
248 
249  /* send */
250  nl_send_auto(nl_sk, msg);
251 
252  err = nl_wait_for_ack(nl_sk);
253  if (err != 0) {
254  fprintf(stderr,
255  "add: ACK is missing or Error returned. "
256  "Operation might fail: %i\n", err);
257  }
258 
259  nlmsg_free(msg);
260 
261  return 0;
262 
263 nla_put_failure:
264  fprintf(stderr, "Attribute Modification failed: %d\n",-EMSGSIZE);
265  nlmsg_free(msg);
266  return -EMSGSIZE;
267 }

Here is the caller graph for this function:

int ce_gw_del ( uint32_t  id,
char *  dev_name 
)

Deletes a device or a route in Kernel Module.

Parameters
idThe id of the route you want to delete. param dev_name must be NULL when you want to delete a route.
dev_nameThe textual name of the virtual device you want to delete. The device must be previously added by ce_gw_add(). param id must be 0 if you want to delete a device.
Precondition
param id must be == 0 OR param dev_name must be == NULL
Return values
0on success
<0on failure
See Also
related callbacks: nl_cb_general_errno()

Definition at line 269 of file netlink.c.

References CE_GW_A_DST, CE_GW_A_ID, CE_GW_A_MAX, CE_GW_C_DEL, ce_gw_genl_policy, genl_fam, IFACE_VERSION, nl_sk, NO_FLAG, and USER_HDR_SIZE.

Referenced by main().

270 {
271  int err;
272  struct nl_msg *msg;
273  if (id != 0 && dev_name != NULL) {
274  err = -EINVAL;
275  return err;
276  }
277 
278  /* create */
279  msg = nlmsg_alloc();
280  if(msg == NULL) {
281  fprintf(stderr,"del: Message allocation failed.\n");
282  return -1;
283  }
284 
285  void *user_hdr;
286  user_hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ,
287  genl_family_get_id(genl_fam), USER_HDR_SIZE,
289  if (user_hdr == NULL)
290  fprintf(stderr, "del: Message Haeder creation failed\n");
291 
292  NLA_PUT_U32(msg, CE_GW_A_ID, id);
293  if (dev_name != NULL) { /* del dev is called */
294  NLA_PUT_STRING(msg, CE_GW_A_DST, dev_name);
295  }
296 
297  /* vaildate */
298  struct nlmsghdr *msghdr = nlmsg_hdr(msg);
299  err = genlmsg_validate(msghdr, USER_HDR_SIZE,
301  if (err != 0) {
302  fprintf(stderr, "del: Validation of Message Failed: %i\n", err);
303  return -1;
304  }
305 
306  /* send */
307  nl_send_auto(nl_sk, msg);
308 
309  err = nl_wait_for_ack(nl_sk);
310  if (err != 0) {
311  fprintf(stderr,
312  "add: ACK is missing or Error returned. "
313  "Operation might fail: %i\n", err);
314  }
315 
316  nlmsg_free(msg);
317  return 0;
318 
319 nla_put_failure:
320  fprintf(stderr, "Attribute Modification failed: %d\n",-EMSGSIZE);
321  nlmsg_free(msg);
322  return -EMSGSIZE;
323 }

Here is the caller graph for this function:

int ce_gw_echo ( char *  message)

send a message and return the received message from Kernel. (for testing)

Parameters
messageA String message you want to send.
Return values
Themessage you get from the Kernel. NULL on failure.

Definition at line 460 of file netlink.c.

References CE_GW_A_DATA, CE_GW_A_MAX, CE_GW_C_ECHO, ce_gw_genl_policy, genl_fam, IFACE_VERSION, nl_cb_echo_answer(), nl_sk, NO_FLAG, and USER_HDR_SIZE.

Referenced by main().

461 {
462  int rc; /* return codes */
463  struct nl_msg *msg;
464 
465  /* create */
466  msg = nlmsg_alloc();
467  if(msg == NULL) {
468  fprintf(stderr,"echo: Message allocation failed.\n");
469  return -1;
470  }
471 
472  void *user_hdr;
473  user_hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ,
474  genl_family_get_id(genl_fam), USER_HDR_SIZE,
476  if (user_hdr == NULL)
477  fprintf(stderr, "echo: Message Haeder creation failed.\n");
478 
479  NLA_PUT_STRING(msg, CE_GW_A_DATA, message);
480 
481  /* vaildate */
482  struct nlmsghdr *msghdr = nlmsg_hdr(msg);
483  if ((rc = genlmsg_validate(msghdr,0,CE_GW_A_MAX, ce_gw_genl_policy)) != 0) {
484  fprintf(stderr, "echo: Validation of Message Failed: %i\n", rc);
485  return -1;
486  }
487 
488  /* send */
489  nl_socket_disable_auto_ack(nl_sk);
490  nl_send_auto(nl_sk, msg);
491 
492  /* create callback system */
493  struct nl_cb *cb = nl_cb_alloc(NL_CB_DEBUG);
494  nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM , nl_cb_echo_answer, NULL);
495  nl_recvmsgs(nl_sk, cb);
496  nl_cb_put(cb);
497 
498 
499  nlmsg_free(msg);
500 
501  return 0;
502 
503 nla_put_failure:
504  fprintf(stderr, "Attribute Modification failed: %d\n",-EMSGSIZE);
505  nlmsg_free(msg);
506  return -1;
507 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ce_gw_list ( uint32_t  id)

Print informations of actual active routes to stdout.

Parameters
idset it to 0 if you want to list all routes. Else set it to the route id you want to print of the route for wich you want the informations printed.
Return values
0on success
<0on failure
See Also
related callbacks: nl_cb_list_entry(), nl_cb_list_finish(), nl_cb_general_errno()
Todo:
perhaps return a list with the information, so that the caller could parse the data himself (for example he will search for something or want to pint out in an other method than the standart)

Definition at line 384 of file netlink.c.

References CE_GW_A_ID, CE_GW_A_MAX, CE_GW_C_LIST, ce_gw_genl_policy, genl_fam, IFACE_VERSION, nl_cb_general_errno(), nl_cb_list_entry(), nl_cb_list_finish(), nl_sk, NO_FLAG, and USER_HDR_SIZE.

Referenced by main().

385 {
386  int err;
387  struct nl_msg *msg;
388 
389  /* create */
390  msg = nlmsg_alloc();
391  if(msg == NULL) {
392  fprintf(stderr,"echo: Message allocation failed.\n");
393  return -1;
394  }
395 
396  void *user_hdr;
397  user_hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ,
398  genl_family_get_id(genl_fam), USER_HDR_SIZE,
400  if (user_hdr == NULL)
401  fprintf(stderr, "echo: Message Haeder creation failed.\n");
402 
403  NLA_PUT_U32(msg, CE_GW_A_ID, id);
404 
405  /* vaildate */
406  struct nlmsghdr *msghdr = nlmsg_hdr(msg);
407  err = genlmsg_validate(msghdr, 0, CE_GW_A_MAX, ce_gw_genl_policy);
408  if (err != 0) {
409  fprintf(stderr, "echo: Validation of Message Failed: %i\n",
410  err);
411  return -1;
412  }
413 
414  /* send */
415  nl_socket_disable_auto_ack(nl_sk);
416  nl_send_auto(nl_sk, msg);
417 
418  /* create callback system */
419  struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
420  nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, nl_cb_list_entry, NULL);
421  nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl_cb_list_finish, NULL);
422  nl_cb_err(cb, NL_CB_CUSTOM, nl_cb_general_errno, NULL);
423 
424  printf(" ID SRC DST TYPE HANDLED DROPPED FLAGS\n");
425 
426  nl_recvmsgs(nl_sk, cb);
427 
428  nl_cb_put(cb);
429  nlmsg_free(msg);
430 
431  return 0;
432 
433 nla_put_failure:
434  fprintf(stderr, "Attribute Modification failed: %d\n",-EMSGSIZE);
435  nlmsg_free(msg);
436  return -1;
437 }

Here is the call graph for this function:

Here is the caller graph for this function:

void nl_sk_fam_exit ( void  )

freeing the alloccated memory. The Function free the memory allocated by nl_sk_fam_init().

See Also
nl_sk_fam_init()

Definition at line 559 of file netlink.c.

References genl_fam, and nl_sk.

Referenced by main().

560 {
561  nl_close(nl_sk);
562  genl_family_put(genl_fam);
563  nl_socket_free(nl_sk);
564 }

Here is the caller graph for this function:

int nl_sk_fam_init ( void  )

creakte socket and family and connect

It creates the netlink socket and connect, as well as the netlink family. This function must called once before any other netlink operation.

See Also
nl_sk_fam_exit()
Return values
0on success, negative value on failure

Definition at line 510 of file netlink.c.

References CE_GW_A_MAX, GE_FAMILY_NAME, GE_FAMILY_VERSION, genl_fam, nl_cb_general_errno(), nl_sk, and USER_HDR_SIZE.

Referenced by main().

511 {
512  int err;
513 
514  /* create gneric netlink socket */
515  nl_sk = nl_socket_alloc();
516  if ( nl_sk == NULL ) {
517  fprintf (stderr, "Socket allocation failed.\n");
518  return -1;
519  }
520 
521  err = genl_connect(nl_sk);
522  if (err != 0) {
523  fprintf (stderr, "Connetion to socket failed: %d\n", err);
524  return err;
525  }
526 
527  err = nl_socket_modify_err_cb(nl_sk, NL_CB_CUSTOM,
528  nl_cb_general_errno, NULL);
529  if (err != 0) {
530  fprintf (stderr, "Error Callback modification failed: %d\n",
531  err);
532  }
533 
534  /* create generic netlink family */
535  genl_fam = genl_family_alloc();
536  if (genl_fam == NULL) {
537  fprintf (stderr, "Family allocation failed.\n");
538  return -1;
539  }
540 
541  genl_family_set_name(genl_fam, GE_FAMILY_NAME);
542  genl_family_set_version(genl_fam, GE_FAMILY_VERSION);
543  genl_family_set_maxattr(genl_fam, CE_GW_A_MAX);
544  genl_family_set_hdrsize(genl_fam, USER_HDR_SIZE);
545 
546  genl_family_set_id(genl_fam,
547  (err = genl_ctrl_resolve(nl_sk, GE_FAMILY_NAME)));
548  if (err < 0) {
549  fprintf(stderr,
550  "Could not resolve Netlink Family ID from kernel. "
551  "Is the module loaded?: %d\n", err);
552  return err;
553  }
554 
555  return 0;
556 }

Here is the call graph for this function:

Here is the caller graph for this function: