hartkopp/can-isotp

best way to programatically test if the module is installed?

Opened this issue · 6 comments

I'm trying to figure out a clean way to detect if can-isotp is installed before trying to use it (and potentially getting an error that is not clear if it has to do with a missing module or some other problem).

On first boot

lsmod|grep can_isotp

yields nothing. However, after running

isotprecv -s 123 -d 321 -l can0

I get

$ lsmod|grep can_isotp
can_isotp              32768  0
can                    28672  1 can_isotp
$

So, it looks the the module is loaded automatically on use. I can't figure out how the kernel decides to load modules automatically when needed. Is there a clean way to trigger this to happen manually? I can run sudo modprobe can_isotp, but I don't want to do that as root. Somehow the isotprecv command can do it without being root.

I know I could run

$ uname -r
5.15.0-1053-raspi
$

to see if it has a modern kernel installed, but I don't think this is a good approach because it seems complicated to parse the kernel version string above with so many variants. Also, people can manually install the kernel module, or have a custom kernel that doesn't have the module installed.

Any suggestions?

I'll be doing this in python by the way, but a solution that works in bash should be general enough for me to port to python.

Possibly modinfo can_isotp can be used to see if it is installed, but I'm not sure if it can tell me if it is actually able to successfully load.

Also, when running isotprecv -s 123 -d 321 -l can0 I get

can: controller area network core
NET: Registered PF_CAN protocol family
can: isotp protocol

/var/log/syslog

.

Not sure if there is a way to trigger the registering of the PF_CAN protocol family other than trying to open a socket?

You know, you can create a socket without binding it to an address.
It will fail if the module isn't loaded, succeed without interfering with the bus if it is installed.

Seems like it is what you need. Is there an issue I don't know of?

I thought there might be a cleaner way, but I think that might work.

Does this approach work even if there are no CAN interfaces present on the machine?

yes, the interface is part of the address, which is required to call bind, but not create the socket structure.
To create the socket, you need to know the protocol, e.g : family, message type, protocol ID (CAN, datagram, ISOTP)

Example here: https://github.com/linux-can/can-utils/blob/master/isotpsend.c#L254-L286
Line 254 should fail if the module isn't loaded