1

Is there a way to enumerate all CAN devices on Linux?

It's easy to get a list of the available adapter names plus their indices using if_nameindex but I can't see an obvious way to use that to then iterate though those to find out which are can or not (apart from an ugly hack to see if 'can' is in the name).

I suppose I could create a socket using PF_CAN and then try and bind with each of the indices. I would expect only the CAN interfaces will return successfully but again it feels like a hack.

I've also had a look at the socket ioctls in sys/ioctl.h but I can't see anything there that would be useful. I thought maybe using SIOCGIFADDR would work and I'd be able to get the sa_family field but that doesn't work either.

  • Have you looked at _libsocketcan_ source code it make use of _netlink_ API to request information about sockets. (http://www.pengutronix.de/software/libsocketcan/download/). The function _do_set_nl_link_ in _libsocketcan.c_ fetch CAN interface specific attributes. – Nelstaar Sep 02 '15 at 09:44
  • No I hadn't found that thanks and it looks interesting. I shall give it a try and see how it goes. I guess I knew it was going to involve the netlink API but was a bit put off as it looks pretty heavyweight. Doesn't look like it would be difficult to add an _can_do_enumerate_ public function. – Gary Metalle Sep 03 '15 at 10:29
  • I had a quick play with this last night creating a couple of vcan interfaces but the library doesn't seem to cope with virtual links. I'll have to cross-compile it and try it on a device that has real CAN links. It's interesting that I think the library does find the interfaces but it comes back with "no link data found". – Gary Metalle Sep 04 '15 at 07:19
  • Was the interface UP ? – Nelstaar Sep 04 '15 at 14:58
  • I added two vcans and one was up and one was down. The code as it stands doesn't seem to recognise vcan interfaces so a call to _can_get_state_ will fail. I've looked in the code and it's because there is no IFLA_INFO_DATA and the call to _do_get_nl_link_ exits the loop and returns "no link data found". – Gary Metalle Sep 05 '15 at 10:25
  • It is still possible to add a routine to enumerate all can or vcan interfaces though by looping and getting the interface names using IFLA_IFNAME. I've also noticed that IFLA_INFO_KIND will return "vcan" for the vcan interfaces so presumably returns "can" for a real one. Shame that can't use this API for bring the vcan interface UP and DOWN though as that would have been useful. Not to mention get the operating state. – Gary Metalle Sep 05 '15 at 10:28
  • If you share your code I can test it. You shall share it in responding your own question I think – Nelstaar Sep 05 '15 at 14:33
  • Can't post much text here and don't have a server to upload the example to. I basically wrote a simple C++ app that called _can_get_state_: int res = ::can_get_state(can_interface, &state); cout << "Call to can_get_state was " << (res == 0 ? "successful" : "unsuccesful") << endl; if (res == 0) { cout << "CAN Interface: " << can_interface << " is " << state << endl; } – Gary Metalle Sep 05 '15 at 17:29
  • sorry about the formatting the options are really limited here. Why don't they let you put a line break where you want one lol. – Gary Metalle Sep 05 '15 at 17:31
  • Actually this [http://www.netfilter.org/projects/libmnl/index.html] libmnl library is quite good and has some good examples. If you look in the examples/rtnl folder there's an example called _rtnl-link-dump2_ that lists all interfaces including vcan/can plus the oper state of the interface. Unfortunately I couldn't get the _rtnl-link-set_ example to change a vcan from down to up but I didn't spend much time looking why (error is operation not permitted). – Gary Metalle Sep 05 '15 at 18:40

0 Answers0