{"id":15007474,"url":"https://github.com/mildsunrise/node_bpf","last_synced_at":"2025-07-07T06:33:02.821Z","repository":{"id":39517582,"uuid":"286754895","full_name":"mildsunrise/node_bpf","owner":"mildsunrise","description":"🔬 eBPF / libbpf bindings for Node.js","archived":false,"fork":false,"pushed_at":"2022-03-12T22:30:52.000Z","size":1497,"stargazers_count":34,"open_issues_count":1,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-26T19:49:57.664Z","etag":null,"topics":["bpf","kprobes","linux-kernel","nodejs"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mildsunrise.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-11T13:41:06.000Z","updated_at":"2025-05-21T09:54:23.000Z","dependencies_parsed_at":"2022-08-29T16:02:27.415Z","dependency_job_id":null,"html_url":"https://github.com/mildsunrise/node_bpf","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/mildsunrise/node_bpf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mildsunrise%2Fnode_bpf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mildsunrise%2Fnode_bpf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mildsunrise%2Fnode_bpf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mildsunrise%2Fnode_bpf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mildsunrise","download_url":"https://codeload.github.com/mildsunrise/node_bpf/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mildsunrise%2Fnode_bpf/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264027568,"owners_count":23546100,"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":["bpf","kprobes","linux-kernel","nodejs"],"created_at":"2024-09-24T19:10:13.146Z","updated_at":"2025-07-07T06:33:02.759Z","avatar_url":"https://github.com/mildsunrise.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bpf\n\nNode.js bindings to libbpf. BPF is a Virtual Machine (and associated bytecode definition) embedded in the Linux kernel. This module allows you to:\n\n - Assemble \u0026 compile BPF programs\n\n - Use the kernel's `ebpf` interface:\n   - Load programs into the kernel\n   - Attach them to events\n   - Create \u0026 manipulate eBPF maps\n   - Other: perf events, check feature availability, pin objects to BPFFS, query program bytecode, BTF data, etc.\n\n## Status\n\nNot enough functionality for standalone use yet.\n\nThere's a generic API to create ([`createMap`][]) and manipulate ([`IMap`][]) eBPF maps of any type, including map-in-map support, but only some map types are currently tested. There's no BTF support for now.\n\nIt has a [raw version][`RawMap`] (which operates with binary `Buffer`s directly), and a [high-level version][`ConvMap`] which uses a conversion supplied by the user.\n\nApart from the generic API, there's a few other sub-APIs for specific map types, such as [`IArrayMap`][] for `ARRAY` maps. These also have raw and high-level versions.\n\n## Usage\n\nThere's prebuilds for x86, x64, arm32v7 and arm64v8, so you don't need anything in those cases.\n\nFor other archs, libbpf and its dependencies are included so you only need a compiler:\n\n~~~ bash\nsudo apt install build-essential\n~~~\n\nThen, install this module:\n\n~~~ bash\nnpm install bpf\n~~~\n\nlibbpf is kernel agnostic, but not all of the exposed features may be supported by the running kernel, even if they are present in the API and typings. This extends to everything (functions, flags, map types, ...). For some notable cases, we make a mention in the docs, but for a full reference of features and their required kernel versions, go [here](https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md). If a feature isn't supported by your kernel and you try to use it, you'll likely get an `EINVAL` error.\n\n## Examples\n\n### Raw map operations\n\n~~~ javascript\nconst bpf = require('bpf')\n\n// Create a HASH map, with 4-byte keys and values\nconst ref = bpf.createMap({\n  type: bpf.MapType.HASH,\n  keySize: 4, valueSize: 4,\n  maxEntries: 10\n})\n\n// Wrap it in `RawMap` to operate with it\nconst map = new bpf.RawMap(ref)\n\n// Add some entries\nconst key1 = Buffer.of(0,0,0,1), key2 = Buffer.of(0,0,9,2)\nmap.set(key1, Buffer.from('abcd'))\nmap.set(key2, Buffer.from('w00t'))\n\n// Print entries (warning: HASH has no order)\nfor (const [k, v] of map)\n  console.log('entry', k.toString('hex'), '=', v.toString('ascii'))\n// entry 00000902 = w00t\n// entry 00000001 = abcd\n\nmap.get(key2) // -\u003e \u003cBuffer 77 30 30 74\u003e\nmap.delete(key2) // -\u003e true\nmap.get(key2) // -\u003e undefined\n~~~\n\n### Using conversions\n\n~~~ javascript\n// We'll have NUL-terminated strings as keys, and uint32 values\nconst ref = bpf.createMap({\n  type: bpf.MapType.HASH,\n  keySize: 16, valueSize: 4,\n  maxEntries: 7\n})\n// bpf already provides a conversion for uint32, for convenience\n// So we only need to write one for the keys\nconst stringConversion = {\n  parse: (buf) =\u003e {\n    const size = buf.indexOf(0)\n    return buf.slice(0, size === -1 ? buf.length : size).toString()\n  },\n  format: (buf, x) =\u003e {\n    buf.fill(0)\n    buf.write(x)\n  }\n}\nconst map = new bpf.ConvMap(ref, stringConversion, bpf.u32type)\n\nmap.set('a cat', 1)\nmap.set('foo', 3458)\nmap.set('test', 5)\n\n[...map] // -\u003e [ ['foo', 3458], ['test', 5], ['a cat', 1] ]\n~~~\n\n### Array maps\n\n~~~ javascript\nconst doubleConversion = {\n  parse: (buf) =\u003e buf.readDoubleLE(),\n  format: (buf, x) =\u003e buf.writeDoubleLE(x),\n}\n\nconst ref = bpf.createMap({\n  type: bpf.MapType.ARRAY,\n  keySize: 4, // always 4\n  valueSize: 8,\n  maxEntries: 5 // array length\n})\nconst array = new bpf.ConvArrayMap(ref, doubleConversion)\n\n// Or equivalently...\nconst array2 = bpf.createArrayMap(5, 8, doubleConversion)\n\n// Values are initialized to zero\n[...array] // -\u003e [ 0, 0, 0, 0, 0 ]\n\narray.set(3, 106.5)\n[...array] // -\u003e [ 0, 0, 0, 106.5, 0 ]\n~~~\n\n### Using your own FD\n\n~~~ javascript\nconst fd = getMapFDFromSomewhereElse()\n\n// By default it duplicates the FD, leaving the original FD unaffected\nconst ref = bpf.createMapRef(fd)\nref.fd === fd  // -\u003e false\n\n// Use the `transfer` option if you want bpf to take its ownership\nconst ref2 = bpf.createMapRef(fd, { transfer: true })\nref2.fd === fd  // -\u003e true\n\nconst map = new RawMap(ref)\n// ...\n~~~\n\n### Map-in-map\n\n~~~ javascript\n// our values will be ARRAY maps\nconst innerParams = {\n  type: bpf.MapType.ARRAY,\n  keySize: 4, valueSize: 4,\n  maxEntries: 5\n}\nconst createInnerMap = () =\u003e\n  new bpf.ConvArrayMap(bpf.createMap(innerParams), bpf.u32type)\n\n// create an ARRAY_OF_MAPS, passing the inner parameters\nconst ref = bpf.createMap({\n  type: bpf.MapType.ARRAY_OF_MAPS,\n  keySize: 4, valueSize: 4,\n  maxEntries: 7,\n  innerMap: innerParams\n})\nconst map = new bpf.ConvMap(ref, bpf.u32type, bpf.u32type)\n\n// the map is initially empty\n[...map] // -\u003e []\n\n// to set an entry, pass the FD of a suitable map\nconst value1 = createInnerMap()\nmap.set(2, value1.ref.fd)\n\n// when getting, the *ID* will be returned instead\nmap.get(2) === value1.ref.id  // -\u003e true\n~~~\n\n\n\n[`createMap`]: https://bpf.alba.sh/docs/modules.html#createMap\n[`IMap`]: https://bpf.alba.sh/docs/interfaces/IMap.html\n[`RawMap`]: https://bpf.alba.sh/docs/classes/RawMap.html\n[`ConvMap`]: https://bpf.alba.sh/docs/classes/ConvMap.html\n[`TypeConversion`]: https://bpf.alba.sh/docs/interfaces/TypeConversion.html\n[`IArrayMap`]: https://bpf.alba.sh/docs/interfaces/IArrayMap.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmildsunrise%2Fnode_bpf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmildsunrise%2Fnode_bpf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmildsunrise%2Fnode_bpf/lists"}