{"id":13437181,"url":"https://github.com/mguentner/cannelloni","last_synced_at":"2026-01-11T01:54:32.356Z","repository":{"id":2510494,"uuid":"30972974","full_name":"mguentner/cannelloni","owner":"mguentner","description":"a SocketCAN over Ethernet tunnel","archived":false,"fork":false,"pushed_at":"2025-03-12T21:34:26.000Z","size":297,"stargazers_count":351,"open_issues_count":14,"forks_count":86,"subscribers_count":32,"default_branch":"master","last_synced_at":"2025-03-12T22:23:41.748Z","etag":null,"topics":["can-bus","socketcan"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mguentner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":["mguentner"]}},"created_at":"2015-02-18T16:03:30.000Z","updated_at":"2025-03-12T21:15:06.000Z","dependencies_parsed_at":"2024-04-16T04:46:24.523Z","dependency_job_id":"a0d5f1f1-a690-4cdd-b519-8b47633bfdac","html_url":"https://github.com/mguentner/cannelloni","commit_stats":{"total_commits":102,"total_committers":15,"mean_commits":6.8,"dds":"0.36274509803921573","last_synced_commit":"f2dd2141919a53c3e4325e271ffc88d3d18e2974"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mguentner%2Fcannelloni","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mguentner%2Fcannelloni/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mguentner%2Fcannelloni/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mguentner%2Fcannelloni/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mguentner","download_url":"https://codeload.github.com/mguentner/cannelloni/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244370872,"owners_count":20442309,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["can-bus","socketcan"],"created_at":"2024-07-31T03:00:54.866Z","updated_at":"2026-01-11T01:54:32.318Z","avatar_url":"https://github.com/mguentner.png","language":"C++","funding_links":["https://github.com/sponsors/mguentner"],"categories":["C++","Utils"],"sub_categories":["CAN-over-IP"],"readme":"# cannelloni\n*a SocketCAN over Ethernet tunnel*\n\n[![Chat on Matrix](https://matrix.to/img/matrix-badge.svg)](https://matrix.to/#/#cannelloni:matrix.org)\n\ncannelloni is written in C++11 and uses UDP, TCP or SCTP to transfer CAN frames\nbetween two machines.\n\nFeatures:\n\n- frame aggregation in Ethernet frames (multiple CAN frames in one\n  Ethernet frame)\n- IPv4/IPv6\n- efficient protocol\n- very high data rates possible (10 Mbit/s +)\n- custom timeouts for certain IDs (see below)\n- easy debugging\n- CAN FD support on interfaces that support it\n- UDP support (fast, unreliable transport)\n- TCP support (reliable transport)\n- SCTP support (optional, reliable transport)\n\n# Important Usage Notice\ncannelloni is **not suited** for production deployments. Use it only in environments where packet loss is tolerable.\nThere is **no guarantee** that CAN frames will reach their destination at all **and/or** in the right order.\n\n# Ecosystem\n\n- https://github.com/PhilippFux/ESP32_CAN_Interface\n- https://github.com/tuvok/qtCannelloniCanBus\n- https://github.com/mguentner/cannelloni_ports (currently only a lwIP implementation)\n- https://github.com/epozzobon/lasagne (another esp32)\n- https://github.com/GENIVI/CANdevStudio\n\n## Compilation\n\ncannelloni uses cmake to generate a Makefile.\nYou can build cannelloni using the following command.\n\n```\ncmake -B build -DCMAKE_BUILD_TYPE=Release\ncmake --build build\n```\n\nIf you do not want or need SCTP support, you can disable it\nby setting `-DSCTP_SUPPORT=OFF`.\nSCTP support is also disabled if you don't have `lksctp-tools`\ninstalled.\n\n## Installation\n\nJust install it using\n\n```\n  cmake --install build\n```\n\n## Usage\n\n### Example\n\nTwo machines 1 and 2 need to be connected:\n\n![](doc/firstexp.png)\n\nMachine 2 needs to be connected to the physical CAN Bus that is attached\nto Machine 1.\n\nStart cannelloni on Machine 1:\n\n```\ncannelloni -I slcan0 -R 192.168.0.3 -r 20000 -l 20000\n```\ncannelloni will now listen on port 20000 and has Machine 2 configured as\nits remote.\n\nPrepare vcan on Machine 2:\n\n```\nsudo modprobe vcan\nsudo ip link add name vcan0 type vcan\nsudo ip link set dev vcan0 up\n```\n\nWhen operating with `vcan` interfaces always keep in mind that they\neasily surpass the possible data rate of any physical CAN interface.\nAn application that just sends whenever the bus is ready would simply\nsend with many Mbit/s.\nThe receiving end, a physical CAN interface with a net. data rate of\n\u003c= 1 Mbit/s would not be able to keep up.\nIt is therefore a good idea to rate limit a `vcan` interface to\nprevent packet loss.\n\n```\nsudo tc qdisc add dev vcan0 root tbf rate 300kbit latency 100ms burst 1000\n```\nThis command will rate limit `vcan0` to 300 kbit/s.\nTry to match the rate limit with your physical interface on the remote.\nKeep also in mind that this also increases the overall latency!\n\nNow start cannelloni on Machine 2:\n```\ncannelloni -I vcan0 -R 192.168.0.2 -r 20000 -l 20000\n```\n\nThe tunnel is now complete and can be used on both machines.\nSimply try it by using `candump` and/or `cangen`.\n\nIf something does not work, try the debug switch `-d cut` to find out\nwhat is wrong.\n\n### Timeouts\n\n*UDP + SCTP only!*\n\n\ncannelloni either sends a full UDP frame or all CAN frames that\nare queued when the timeout that has been specified by the `-t` option\nhas been reached.\nThe default value is 100000 us, so the worst case latency for any can\nframe is\n\n```\nLw ~= 100ms + Ethernet latency + Delay on Receiver\n```\n\nIf you have high priority frames but you also want a small ethernet\noverhead, you can create a csv in the format\n```\nCAN_ID,Timeout in us\n```\nto specify these frames. You can use the `#` character to comment your\nframes.\n\nFor example, if the frames with the IDs 5 and 15 should be send after\na shorter timeout you can create a file with the following content.\n\n```\n# 15ms\n5,15000\n# 50ms\n15,50000\n```\n\nYou can load this file into each cannelloni instance with the `-T\nfile.csv` option.\nPlease note that the whole buffer will be flushed and not only the two\nframes.\n\nIf you enable timer debugging using `-d t` you should see that the table\nhas been loaded successfully into cannelloni:\n\n```\n[...]\nINFO:cannelloni.cpp[148]:main:Custom timeout table loaded:\nINFO:cannelloni.cpp[149]:main:*---------------------*\nINFO:cannelloni.cpp[150]:main:|  ID  | Timeout (us) |\nINFO:cannelloni.cpp[153]:main:|     5|         15000|\nINFO:cannelloni.cpp[153]:main:|    15|         50000|\nINFO:cannelloni.cpp[154]:main:*---------------------*\nINFO:cannelloni.cpp[155]:main:Other Frames:100000 us.\n[...]\n```\n\n# Transports\n\n## UDP\n\ncannelloni supports UDP for stable connections where no packet loss\nis expected. Here two instances communicate using defined ports.\n\nUsage example\n\nIP: 192.168.0.2\n```\ncannelloni -I vcan0 -R 192.168.0.3 -r 12000 -l 13000\n```\n\nIP: 192.168.0.3\n```\ncannelloni -I vcan0 -R 192.168.0.2 -r 13000 -l 12000\n```\n\nSet the *MTU* using `-m` depending on your connection. Default is\n1500 bytes.\n\n## SCTP\n\nWith SCTP it is possible to use cannelloni over lossy connections\nwhere packet loss and re-ordering is very likely.\nThe SCTP implementation uses the server-client model (for now).\nOne instance binds on a fixed port and the other instance (client)\nconnects to it.\n\nUsage example:\n\nIP: 192.168.0.2 (Server)\n```\ncannelloni -I vcan0 -S s\n```\n\nIP: 192.168.0.3 (Client)\n```\ncannelloni -I vcan0 -S c -R 192.168.0.2\n```\n\nIf there is no remote IP supplied to the server instance, every client\n(any IP) will be accepted. Only one client can be connected at a time.\nAfter the client disconnects, the server waits for a new client.\n\n## TCP\n\nUsage example:\n\nIP: 192.168.0.2 (Server)\n```\ncannelloni -I vcan0 -C s\n```\n\nIP: 192.168.0.3 (Client)\n```\ncannelloni -I vcan0 -C c -R 192.168.0.2\n```\n\nWith TCP, no frame buffer is used an frames are immediately transmitted,\nframe sorting and timeouts do not apply here.\n\n# Frame sorting\n\nCAN frames can be sorted by their ID in each ethernet frame to write\nhigh priority frames first on the receiving CAN bus.\n\nThis can be achieved by supplying the `-s` option.\n\n# Filtering\n\ncannelloni does not support filtering, if however you want to only bridge a\ncertain set of CAN IDs, you can first forward the frames of interest to virtual CAN\ninterface. From there you will send using cannelloni.\n\nThis can be achieved with `cangw` which is part of [can-utils](https://github.com/linux-can/can-utils/) and its respective\nkernel module is also present in upstream Linux.\n\nLet's look at an example where currently `can0` is sent to a remote machine:\n\n```\ncannelloni -I can0 -R 192.168.0.3 -r 12000\n```\n\nLet's say you want to only receive CAN frames with the ID `0x042` at the remote machine.\nFirst, load two kernel modules, `can_gw` and `vcan`:\n\n```\nmodprobe vcan\nmodprobe can_gw\n```\n\nNow, start a virtual CAN bus:\n\n```\nip link add name vcan0 type vcan\nip link set dev vcan0 up mtu 16\n```\n\nAdd a rule to the gateway that will forward frames with IDs that match `0x042 \u0026 0xC00007F0`. Note that\nthe bitmask accounts for the type `can_id` which is 4 bytes long.\n\n```\ncangw -A -s can0 -d vcan0 -f 042:C00007FF -e\n```\n\nIf you start candump now on `vcan0`, you should only see frames with ID `0x042`.\nNow change the cannelloni command to\n\n```\ncannelloni -I vcan0 -R 192.168.0.3 -r 12000\n```\n\nNow you should see those `0x042` frames also at the remote machine.\n\nIf you want to also send frames from the remote to your original `can0`, you need\nto add a rule for that as well!\n\n# Paper\n\ncannelloni was discussed in the paper *Mapping CAN-to-Ethernet communication channels within virtualized embedded environments* on\nthe Conference *Industrial Embedded Systems (SIES), 2015 10th IEEE International Symposium*.\n\nDOI: [10.1109/SIES.2015.7185064](http://dx.doi.org/10.1109/SIES.2015.7185064)\n\nThe papers documentes a PoC how to virtualize CAN controllers similiar to the approach\nXen uses (netback/-front).\n\n# Contributing\n\nPlease fork the repository, create a *separate* branch and create a PR\nfor your work.\n\n# License\n\nCopyright 2014-2023 Maximilian Güntner \u003ccode@mguentner.de\u003e\n\ncannelloni is licensed under the GPL, version 2. See gpl-2.0.txt for\nmore information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmguentner%2Fcannelloni","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmguentner%2Fcannelloni","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmguentner%2Fcannelloni/lists"}