{"id":13439839,"url":"https://github.com/canndrew/netsim","last_synced_at":"2025-07-30T08:07:34.574Z","repository":{"id":57644585,"uuid":"115723114","full_name":"canndrew/netsim","owner":"canndrew","description":"Network simulation in Rust","archived":false,"fork":false,"pushed_at":"2024-12-18T07:08:59.000Z","size":535,"stargazers_count":200,"open_issues_count":5,"forks_count":22,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-28T10:07:06.029Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/canndrew.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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,"publiccode":null,"codemeta":null}},"created_at":"2017-12-29T13:05:38.000Z","updated_at":"2025-03-17T08:35:14.000Z","dependencies_parsed_at":"2025-02-26T04:11:55.769Z","dependency_job_id":"ef95838e-97db-4286-91e5-7864d1ab3d82","html_url":"https://github.com/canndrew/netsim","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canndrew%2Fnetsim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canndrew%2Fnetsim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canndrew%2Fnetsim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canndrew%2Fnetsim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/canndrew","download_url":"https://codeload.github.com/canndrew/netsim/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247166168,"owners_count":20894654,"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":[],"created_at":"2024-07-31T03:01:17.522Z","updated_at":"2025-04-04T11:09:34.097Z","avatar_url":"https://github.com/canndrew.png","language":"Rust","funding_links":[],"categories":["Libraries","Rust","库 Libraries","库"],"sub_categories":["Network programming","网络编程 Network programming","网络编程"],"readme":"# netsim\n\n`netsim` is a Rust library which allows you to:\n\n* Run tests in network-isolated threads.\n* Test networking code on simulated networks.\n* Capture and inspect packets produced by your code.\n* Inject and meddle with network packets.\n\n[Documentation](https://docs.rs/netsim/)\n\n## Examples\n\n### Example 1: Isolating tests.\n\nSuppose you have multiple tests that need to bind to the same port for some reason. By using\n`#[netsim::isolate]` you can run your test suite without having to use `--test-threads=1` and\nwithout having to stop any daemons running on your dev machine.\n\n```no_run\n#[test]\n#[netsim::isolate]\nfn a_test() {\n    let _listener = std::net::TcpListener::bind(\"0.0.0.0:80\").unwrap();\n}\n\n#[test]\n#[netsim::isolate]\nfn another_test_that_runs_in_parallel() {\n    let _listener = std::net::TcpListener::bind(\"0.0.0.0:80\").unwrap();\n}\n```\n\n### Example 2: Capturing a packet.\n\nThe `#[netsim::isolate]` attribute showcased above is just a convenient way to setup a `Machine`\nand spawn a task onto it. To capture a packet you'll need to do these steps yourself. You'll also\nneed to give the machine a network interface to send the packet on.\n\nIn this example we create a UDP socket and use it to send the message \"hello\" towards an arbitary\naddress. The packet then arrives on our `IpIface`, hoping to be routed somewhere, and we can check\nthat it still contains the correct message.\n\n```rust\nlet local_addr: SocketAddrV4 = \"10.1.2.3:5555\".parse().unwrap();\nlet remote_addr: SocketAddrV4 = \"1.1.1.1:53\".parse().unwrap();\nlet machine = Machine::new().unwrap();\nlet mut iface = {\n    machine\n    .add_ip_iface()\n    .ipv4_addr(*local_addr.ip())\n    .ipv4_default_route()\n    .build()\n    .unwrap()\n};\nmachine.spawn(async move {\n    let socket = UdpSocket::bind(local_addr).await.unwrap();\n    socket.send_to(b\"hello\", remote_addr).await.unwrap();\n}).await.unwrap();\n\nlet packet = loop {\n    let packet = iface.next().await.unwrap().unwrap();\n    let IpPacketVersion::V4(packet) = packet.version_box() else { continue };\n    let Ipv4PacketProtocol::Udp(packet) = packet.protocol_box() else { continue };\n    break packet;\n};\nassert_eq!(packet.data(), b\"hello\");\n```\n\n### More, longer examples.\n\nCheck out the [examples](https://github.com/canndrew/netsim/tree/master/examples) directory in\nthis repo.\n\n## Limitations\n\n`netsim` currently only supports Linux since it makes use of the Linux containerization APIs.\n\n## License\n\nMIT or BSD-3-Clause at your option.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanndrew%2Fnetsim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcanndrew%2Fnetsim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanndrew%2Fnetsim/lists"}