{"id":13575673,"url":"https://github.com/pandax381/microps","last_synced_at":"2025-05-14T15:11:40.752Z","repository":{"id":6961560,"uuid":"8213863","full_name":"pandax381/microps","owner":"pandax381","description":"An implementation of a small TCP/IP protocol stack for learning.","archived":false,"fork":false,"pushed_at":"2024-12-17T23:37:34.000Z","size":398,"stargazers_count":1099,"open_issues_count":1,"forks_count":400,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-04-12T02:57:47.350Z","etag":null,"topics":["tcp-ip","tcpip-stack","tuntap"],"latest_commit_sha":null,"homepage":"","language":"C","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/pandax381.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-02-15T06:42:28.000Z","updated_at":"2025-04-11T02:49:23.000Z","dependencies_parsed_at":"2022-08-03T10:00:36.465Z","dependency_job_id":"9dde2490-a9d4-4eb6-9a81-bd6f228a4df6","html_url":"https://github.com/pandax381/microps","commit_stats":{"total_commits":178,"total_committers":11,"mean_commits":"16.181818181818183","dds":0.151685393258427,"last_synced_commit":"2780b729639e5d05b5858bb64d11037f435c2332"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pandax381%2Fmicrops","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pandax381%2Fmicrops/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pandax381%2Fmicrops/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pandax381%2Fmicrops/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pandax381","download_url":"https://codeload.github.com/pandax381/microps/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254170059,"owners_count":22026219,"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":["tcp-ip","tcpip-stack","tuntap"],"created_at":"2024-08-01T15:01:03.187Z","updated_at":"2025-05-14T15:11:40.710Z","avatar_url":"https://github.com/pandax381.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"microps\n=======\n\nmicrops is an implementation of a small TCP/IP protocol stack for learning.\n\n+ If you love the Go language: https://github.com/pandax381/lectcp\n+ Porting to xv6: https://github.com/pandax381/xv6-net\n+ Porting to MikanOS: https://github.com/pandax381/mikanos-net\n\nDocuments\n\n+ [Step by Step Development Guides](https://drive.google.com/drive/folders/1k2vymbC3vUk5CTJbay4LLEdZ9HemIpZe) (Japanese) \n\n## Features\n\nAbstraction Layer\n\n- [x] Physical device abstraction\n  - [x] Define structure for physical device abstraction (`struct net_device`)\n  - [x] Support multiple link protocols and physical devices\n- [x] Logical interface abstraction\n  - [x] Define structure for logical interface abstraction (`struct net_iface`)\n  - [x] Support multiple address family and logical interfaces\n\nDevices\n\n- [x] Null\n- [x] Loopback\n- [x] Ethernet\n  - [x] TUN/TAP (Linux)\n  - [x] PF_PACKET (Linux)\n\nProtocols\n\n- [x] Ethernet\n- [x] ARP\n- [x] IP\n- [x] ICMP\n- [x] UDP\n- [x] TCP\n\nAPI\n\n- [x] Socket like API\n\nLogs\n\n```\n18:43:46.153 [I] net_protocol_register: registerd, type=ARP(0x0806) (net.c:223)\n18:43:46.153 [I] net_timer_register: registerd: ARP Timer interval={1, 0} (net.c:257)\n18:43:46.153 [I] net_protocol_register: registerd, type=IP(0x0800) (net.c:223)\n18:43:46.153 [I] ip_protocol_register: registerd, type=ICMP(0x01) (ip.c:440)\n18:43:46.153 [I] ip_protocol_register: registerd, type=UDP(0x11) (ip.c:440)\n18:43:46.153 [I] ip_protocol_register: registerd, type=TCP(0x06) (ip.c:440)\n18:43:46.153 [I] net_timer_register: registerd: TCP Timer interval={0, 100000} (net.c:257)\n18:43:46.153 [I] net_device_register: registerd, dev=net0, type=0x0000 (net.c:74)\n18:43:46.153 [D] null_init: initialized, dev=net0 (driver/null.c:46)\n18:43:46.153 [I] net_device_register: registerd, dev=net1, type=0x0001 (net.c:74)\n18:43:46.153 [D] loopback_init: initialized, dev=net1 (driver/loopback.c:49)\n18:43:46.153 [I] ip_route_add: network=127.0.0.0, netmask=255.0.0.0, nexthop=0.0.0.0, iface=127.0.0.1 dev=net1 (ip.c:136)\n18:43:46.153 [I] ip_iface_register: registerd: dev=net1, unicast=127.0.0.1, netmask=127.0.0.1, broadcast=255.0.0.0 (ip.c:233)\n18:43:46.153 [I] net_device_register: registerd, dev=net2, type=0x0002 (net.c:74)\n18:43:46.153 [D] ether_tap_init: ethernet device initialized, dev=net2 (driver/ether_tap_linux.c:174)\n18:43:46.153 [I] ip_route_add: network=192.0.2.0, netmask=255.255.255.0, nexthop=0.0.0.0, iface=192.0.2.2 dev=net2 (ip.c:136)\n18:43:46.153 [I] ip_iface_register: registerd: dev=net2, unicast=192.0.2.2, netmask=192.0.2.2, broadcast=255.255.255.0 (ip.c:233)\n18:43:46.153 [I] ip_route_add: network=0.0.0.0, netmask=0.0.0.0, nexthop=192.0.2.1, iface=192.0.2.2 dev=net2 (ip.c:136)\n18:43:46.153 [D] net_run: open all devices... (net.c:314)\n18:43:46.153 [I] net_device_open: dev=net2, state=up (net.c:92)\n18:43:46.153 [I] net_device_open: dev=net1, state=up (net.c:92)\n18:43:46.153 [I] net_device_open: dev=net0, state=up (net.c:92)\n18:43:46.153 [D] net_run: create background thread... (net.c:318)\n18:43:46.154 [D] net_run: running... (net.c:324)\n18:43:57.931 [D] ether_poll_helper: dev=net2, type=ARP(0x0806), len=42 (ether.c:127)\n        src: 0e:4e:af:bc:64:c6\n        dst: ff:ff:ff:ff:ff:ff\n       type: 0x0806 (ARP)\n18:43:57.931 [D] net_input_handler: queue pushed (num:1), dev=net2, type=ARP(0x0806), len=28 (net.c:191)\n18:43:57.931 [D] net_thread: queue poped (num:0), dev=net2, type=ARP(0x0806), len=28 (net.c:286)\n18:43:57.931 [D] arp_input: dev=net2, opcode=Request(0x0001), len=28 (arp.c:239)\n        hrd: 0x0001\n        pro: 0x0800\n        hln: 6\n        pln: 4\n         op: 0x0001 (Request)\n        sha: 0e:4e:af:bc:64:c6\n        spa: 192.0.2.1\n        tha: 00:00:00:00:00:00\n        tpa: 192.0.2.2\n18:43:57.931 [D] arp_cache_insert: INSERT: pa=192.0.2.1, ha=0e:4e:af:bc:64:c6 (arp.c:163)\n18:43:57.931 [D] arp_reply: dev=net2, opcode=Reply(0x0002), len=28 (arp.c:213)\n        hrd: 0x0001\n        pro: 0x0800\n        hln: 6\n        pln: 4\n         op: 0x0002 (Reply)\n        sha: 00:00:5e:00:53:01\n        spa: 192.0.2.2\n        tha: 0e:4e:af:bc:64:c6\n        tpa: 192.0.2.1\n18:43:57.931 [D] net_device_output: dev=net2, type=ARP(0x0806), len=28 (net.c:156)\n18:43:57.931 [D] ether_transmit_helper: dev=net2, type=ARP(0x0806), len=60 (ether.c:101)\n        src: 00:00:5e:00:53:01\n        dst: 0e:4e:af:bc:64:c6\n       type: 0x0806 (ARP)\n18:43:57.931 [D] ether_poll_helper: dev=net2, type=IP(0x0800), len=98 (ether.c:127)\n        src: 0e:4e:af:bc:64:c6\n        dst: 00:00:5e:00:53:01\n       type: 0x0800 (IP)\n18:43:57.931 [D] net_input_handler: queue pushed (num:1), dev=net2, type=IP(0x0800), len=84 (net.c:191)\n18:43:57.932 [D] net_thread: queue poped (num:0), dev=net2, type=IP(0x0800), len=84 (net.c:286)\n18:43:57.932 [D] ip_input: dev=net2, iface=192.0.2.2, protocol=ICMP(0x01), len=84 (ip.c:303)\n        vhl: 0x45 [v: 4, hl: 5 (20)]\n        tos: 0x00\n      total: 84 (payload: 64)\n         id: 41026\n     offset: 0x4000 [flags=2, offset=0]\n        ttl: 64\n   protocol: 1 (ICMP)\n        sum: 0x1663 (0x1663)\n        src: 192.0.2.1\n        dst: 192.0.2.2\n18:43:57.932 [D] icmp_input: 192.0.2.1 =\u003e 192.0.2.2, type=Echo(8), len=64, iface=192.0.2.2 (icmp.c:100)\n       type: 8 (Echo)\n       code: 0\n        sum: 0xb692 (0xb692)\n         id: 55\n        seq: 1\n18:43:57.932 [D] icmp_output: 192.0.2.2 =\u003e 192.0.2.1, type=EchoReply(0), len=64 (icmp.c:138)\n       type: 0 (EchoReply)\n       code: 0\n        sum: 0xbe92 (0xbe92)\n         id: 55\n        seq: 1\n18:43:57.932 [D] ip_output_core: dev=net2, iface=192.0.2.1, protocol=ICMP(0x01), len=84 (ip.c:357)\n        vhl: 0x45 [v: 4, hl: 5 (20)]\n        tos: 0x00\n      total: 84 (payload: 64)\n         id: 128\n     offset: 0x0000 [flags=0, offset=0]\n        ttl: 255\n   protocol: 1 (ICMP)\n        sum: 0x3725 (0x3725)\n        src: 192.0.2.2\n        dst: 192.0.2.1\n18:43:57.932 [D] arp_resolve: resolved, pa=192.0.2.1, ha=0e:4e:af:bc:64:c6 (arp.c:301)\n18:43:57.932 [D] net_device_output: dev=net2, type=IP(0x0800), len=84 (net.c:156)\n18:43:57.932 [D] ether_transmit_helper: dev=net2, type=IP(0x0800), len=98 (ether.c:101)\n        src: 00:00:5e:00:53:01\n        dst: 0e:4e:af:bc:64:c6\n       type: 0x0800 (IP)\n^C18:44:01.605 [D] net_shutdown: terminate background thread... (net.c:334)\n18:44:01.606 [D] net_shutdown: close all devices... (net.c:341)\n18:44:01.606 [I] net_device_close: dev=net2, state=down (net.c:110)\n18:44:01.606 [I] net_device_close: dev=net1, state=down (net.c:110)\n18:44:01.606 [I] net_device_close: dev=net0, state=down (net.c:110)\n18:44:01.606 [D] net_shutdown: shutdown (net.c:345)\n```\n\n## Tutorial\n\n#### 1. Build\n\n```\n$ git clone git@github.com:pandax381/microps.git\n$ cd microps\n$ make\n```\n\n#### 2. Prepare Tap device\n\n```\n$ sudo ip tuntap add mode tap user $USER name tap0\n$ sudo ip addr add 192.0.2.1/24 dev tap0\n$ sudo ip link set tap0 up\n```\n\n\u003e It is temporary and will disappear after reboot.\n\n#### 3. Run sample application\n\n```\n$ ./app/tcps.exe 7\n11:48:55.884 [I] net_protocol_register: registerd, type=ARP(0x0806) (net.c:223)\n11:48:55.884 [I] net_timer_register: registerd: ARP Timer interval={1, 0} (net.c:257)\n11:48:55.884 [I] net_protocol_register: registerd, type=IP(0x0800) (net.c:223)\n...\n11:48:55.884 [D] net_run: running... (net.c:324)\n11:48:55.884 [D] tcp_bind: success: addr=0.0.0.0, port=7 (tcp.c:1156)\n```\n\n\u003e TCP Echo Server start on port 7. (default address is 192.0.2.2/24)\n\n#### 4. Test (Operate in another terminal)\n\n+ Ping\n\n```\n$ ping 192.0.2.2\nPING 192.0.2.2 (192.0.2.2) 56(84) bytes of data.\n64 bytes from 192.0.2.2: icmp_seq=1 ttl=255 time=0.660 ms\n64 bytes from 192.0.2.2: icmp_seq=2 ttl=255 time=0.688 ms\n64 bytes from 192.0.2.2: icmp_seq=3 ttl=255 time=0.574 ms\n...\n```\n\n+ TCP communication\n```\n$ nc 192.0.2.2 7\nfoo\nfoo\nbar\nbar\n```\n\n\u003e Sending text will be sent back by the Echo Server.\n\n## License\n\nmicrops is under the MIT License: See [LICENSE](./LICENSE) file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpandax381%2Fmicrops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpandax381%2Fmicrops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpandax381%2Fmicrops/lists"}