Giter Club home page Giter Club logo

ptcpdump's Introduction

ptcpdump

amd64-e2e arm64-e2e

ptcpdump is the tcpdump(8) implementation using eBPF, with an extra feature: it adds process info as packet comments for each Packet when possible. Inspired by jschwinger233/skbdump.

Table of Contents

Features

  • Process-aware
    • Aware of the process information associated with the packets.
    • Supports filtering packets by process ID and process name.
  • Container-aware and Kubernetes-aware
    • Aware of the container and pod information associated with the packets.
    • Supports multiple container runtimes: Docker Engine and containerd
    • Supports filtering packets by container ID, container name and pod name.
  • Supports using pcap-filter(7) syntax for filtering packets.
  • Directly applies filters in the kernel space.
  • Supports saving captured packets in the PcapNG format for offline analysis with third-party tools such as Wireshark.

Installation

You can download the statically linked executable for x86_64 and arm64 from the releases page.

Requirements

Linux kernel version >= 5.2.

πŸ”

Usage

Example commands

Filter like tcpdump:

sudo ptcpdump -i eth0 tcp
sudo ptcpdump -i eth0 tcp and port 80 and host 10.10.1.1
sudo ptcpdump -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0'

Multiple interfaces:

sudo ptcpdump -i eth0 -i lo

Filter by process:

sudo ptcpdump -i any --pid 1234
sudo ptcpdump -i any --pname curl

Capture by process via run target program:

sudo ptcpdump -i any -- curl ubuntu.com

Filter by container:

sudo ptcpdump -i any --container-id 36f0310403b1
sudo ptcpdump -i any --container-name test

Filter by Pod:

sudo ptcpdump -i any --pod-name test.default

Save data in PcapNG format:

sudo ptcpdump -i any -w demo.pcapng
sudo ptcpdump -i any -w - port 80 | tcpdump -n -r -
sudo ptcpdump -i any -w - port 80 | tshark -r -

πŸ”

Example output

Default:

09:32:09.718892 vethee2a302f wget.3553008 In IP 10.244.0.2.33426 > 139.178.84.217.80: Flags [S], seq 4113492822, win 64240, length 0, ParentProc [python3.834381], Container [test], Pod [test.default]
09:32:09.718941 eth0 wget.3553008 Out IP 172.19.0.2.33426 > 139.178.84.217.80: Flags [S], seq 4113492822, win 64240, length 0, ParentProc [python3.834381], Container [test], Pod [test.default]

With -v:

13:44:41.529003 eth0 In IP (tos 0x4, ttl 45, id 45428, offset 0, flags [DF], proto TCP (6), length 52)
    139.178.84.217.443 > 172.19.0.2.42606: Flags [.], cksum 0x5284, seq 3173118145, ack 1385712707, win 118, options [nop,nop,TS val 134560683 ecr 1627716996], length 0
    Process (pid 553587, cmd /usr/bin/wget, args wget kernel.org)
    ParentProc (pid 553296, cmd /bin/sh, args sh)
    Container (name test, id d9028334568bf75a5a084963a8f98f78c56bba7f45f823b3780a135b71b91e95, image docker.io/library/alpine:3.18, labels {"io.cri-containerd.kind":"container","io.kubernetes.container.name":"test","io.kubernetes.pod.name":"test","io.kubernetes.pod.namespace":"default","io.kubernetes.pod.uid":"9e4bc54b-de48-4b1c-8b9e-54709f67ed0c"})
    Pod (name test, namespace default, UID 9e4bc54b-de48-4b1c-8b9e-54709f67ed0c, labels {"run":"test"}, annotations {"kubernetes.io/config.seen":"2024-07-21T12:41:00.460249620Z","kubernetes.io/config.source":"api"})

πŸ”

Flags

Usage:
  ptcpdump [flags] [expression] [-- command [args]]

Examples:
  sudo ptcpdump -i any tcp
  sudo ptcpdump -i eth0 -i lo
  sudo ptcpdump -i eth0 --pid 1234 port 80 and host 10.10.1.1
  sudo ptcpdump -i any --pname curl
  sudo ptcpdump -i any -- curl ubuntu.com
  sudo ptcpdump -i any -w ptcpdump.pcapng
  sudo ptcpdump -i any -w - port 80 | tcpdump -n -r -
  sudo ptcpdump -i any -w - port 80 | tshark -r -
  ptcpdump -r ptcpdump.pcapng

Expression: see "man 7 pcap-filter"

Flags:
  --container-id string        Filter by container id (only TCP and UDP packets are supported)
  --container-name string      Filter by container name (only TCP and UDP packets are supported)
  --containerd-address string  Address of containerd service (default "/run/containerd/containerd.sock")
  --count                      Print only on stdout the packet count when reading capture file instead of parsing/printing the packets
  --cri-runtime-address string Address of CRI container runtime service (default: uses in order the first successful one of [/run/containerd/containerd.sock, /run/crio/crio.sock, /var/run/cri-dockerd.sock, /var/run/dockershim.sock])
  -Q, --direction string       Choose send/receive direction for which packets should be captured. Possible values are 'in', 'out' and 'inout' (default "inout")
  --docker-address string      Address of Docker Engine service (default "/var/run/docker.sock")
  -f, --follow-forks           Trace child processes as they are created by currently traced processes when filter by process
  -h, --help                   help for ptcpdump
  -i, --interface strings      Interfaces to capture (default [lo])
      --list-interfaces        Print the list of the network interfaces available on the system
      --log-level string       Set the logging level ("debug", "info", "warn", "error", "fatal") (default "warn")
      --oneline                Print parsed packet output in a single line
      --pid uint               Filter by process ID (only TCP and UDP packets are supported)
      --pname string           Filter by process name (only TCP and UDP packets are supported)
      --pod-name string        Filter by pod name (format: NAME.NAMESPACE, only TCP and UDP packets are supported)
      --print                  Print parsed packet output, even if the raw packets are being saved to a file with the -w flag
  -r, --read-file string       Read packets from file (which was created with the -w option). e.g. ptcpdump.pcapng
  -c, --receive-count uint     Exit after receiving count packets
  -s, --snapshot-length uint32 Snarf snaplen bytes of data from each packet rather than the default of 262144 bytes (default 262144)
  -v, --verbose count          When parsing and printing, produce (slightly more) verbose output
      --version                Print the ptcpdump and libpcap version strings and exit
  -w, --write-file string      Write the raw packets to file rather than parsing and printing them out. They can later be printed with the -r option. Standard output is used if file is '-'. e.g. ptcpdump.pcapng

πŸ”

Compare with tcpdump

Options tcpdump ptcpdump
expression βœ… βœ…
-i interface, --interface=interface βœ… βœ…
-w x.pcapng βœ… βœ… (with process info)
-w x.pcap βœ… βœ… (without process info)
-w - βœ… βœ…
-r x.pcapng, -r x.pcap βœ… βœ…
-r - βœ…
--pid process_id βœ…
--pname process_name βœ…
--container-id container_id βœ…
--container-name container_name βœ…
--pod-name pod_name.namespace βœ…
-f, --follow-forks βœ…
-- command [args] βœ…
--oneline βœ…
--print βœ… βœ…
-c count βœ… βœ…
-Q direction, --direction=direction βœ… βœ…
-D, --list-interfaces βœ… βœ…
-A βœ…
-B bufer_size, --buffer-size=buffer_size βœ…
--count βœ… βœ…
-C *file_size βœ…
-d βœ…
-dd βœ…
-ddd βœ…
-e βœ…
-f βœ… β›”
-F file βœ…
-G rotate_seconds βœ…
-h, --help βœ… βœ…
--version βœ… βœ…
-H βœ…
-l, --monitor-mode βœ…
--immediate-mode βœ…
-j tstamp_type, --time-stamp-type=tstamp_type βœ…
-J, --list-time-stamp-types βœ…
--time-stamp-precision=tstamp_precision βœ…
--micro βœ…
--nano βœ…
-K, --dont-verify-checksums βœ…
-l βœ…
-L, --list-data-link-types βœ…
-m module βœ…
-M secret βœ…
-n βœ… βœ…
-N βœ…
-#, --number βœ… βœ…
-O, --no-optimize βœ…
-p, --no-promiscuous-mode βœ… β›”
-S, --absolute-tcp-sequence-numbers βœ…
-s snaplen, --snapshot-length=snaplen βœ… βœ…
-T type βœ…
-t βœ… βœ…
-tt βœ…
-ttt βœ…
-tttt βœ…
-u βœ…
-U, --packet-buffered βœ…
-v βœ… βœ…
-vv βœ…
-vvv βœ…
-V file βœ…
-W filecont βœ…
-x βœ…
-xx βœ…
-X βœ…
-XX βœ…
-y datalinktype, --linktype=datalinktype βœ…
-z postrotate-command βœ…
-Z user, --relinquish-privileges=user βœ…

πŸ”

Build

  1. Build eBPF programs:

    make build-bpf
    
  2. Build ptcpdump:

    make build
    

πŸ”

ptcpdump's People

Contributors

dependabot[bot] avatar florianl avatar mozillazg avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ptcpdump's Issues

Report counts when ptcpdump finished capturing packets

Like tcpdump:

When tcpdump finishes capturing packets, it will report counts of:

  • packets ``captured'' (this is the number of packets that tcpdump has received and processed);

  • packets ``received by filter'' (the meaning of this depends on the OS on which you're running tcpdump, and possibly on the way the OS was configured - if a filter was specified on the command line, on some OSes it counts packets regardless of whether they were matched by the filter expression and, even if they were matched by the filter expression, regardless of whether tcpdump has read and processed them yet, on other OSes it counts only packets that were matched by the filter expression regardless of whether tcpdump has read and processed them yet, and on other OSes it counts only packets that were matched by the filter expression and were processed by tcpdump);

  • packets ``dropped by kernel'' (this is the number of packets that were dropped, due to a lack of buffer space, by the packet capture mechanism in the OS on which tcpdump is running, if the OS reports that information to applications; if not, it will be reported as 0).

https://www.tcpdump.org/manpages/tcpdump.1-4.99.4.html

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Location: .github/renovate.json5
Error type: The renovate configuration file contains some invalid settings
Message: packageRules[0]: Each packageRule must contain at least one match* or exclude* selector. Rule: {"extends":["schedule:monthly"]}

load program failed: invalid argument arg#0 type is not a struct

./ptcpdump -i any
Failed on centos based OS, linux kernel version: 5.4.241
but works on ubuntu server 24.04

FATAL cmd/log.go:16] Verifier error: load program: invalid argument:
        func#0 @0
        arg#0 type is not a struct
        Unrecognized arg#0 type PTR
        0: R1=ctx(id=0,off=0,imm=0) R10=fp0
        ; u64 cookie = bpf_get_socket_cookie(ctx);
        0: (85) call bpf_get_socket_cookie#46
        1: R0_w=inv(id=0) R10=fp0
        ; u64 cookie = bpf_get_socket_cookie(ctx);
        1: (7b) *(u64 *)(r10 -24) = r0
        2: R0_w=inv(id=0) R10=fp0 fp-24_w=mmmmmmmm
        ; if (cookie <= 0) {
        2: (15) if r0 == 0x0 goto pc+529
         R0_w=inv(id=0) R10=fp0 fp-24_w=mmmmmmmm
        3: R0_w=inv(id=0) R10=fp0 fp-24_w=mmmmmmmm
        ; struct task_struct *task = (struct task_struct *)bpf_get_current_task();
        3: (85) call bpf_get_current_task#35
        unknown func bpf_get_current_task#35
        processed 4 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0

build for arm64 error

/home/parallels/Desktop/work/ptcpdump/bpf/ptcpdump.c:375:5: error: incomplete definition of type 'struct user_pt_regs'
int BPF_KPROBE(kprobe__security_sk_classify_flow, struct sock *sk) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./headers/bpf/bpf_tracing.h:817:20: note: expanded from macro 'BPF_KPROBE'
return ____##name(___bpf_kprobe_args(args));
^~~~~~~~~~~~~~~~~~~~~~~~
./headers/bpf/bpf_tracing.h:797:41: note: expanded from macro '___bpf_kprobe_args'
#define ___bpf_kprobe_args(args...) ___bpf_apply(___bpf_kprobe_args, ___bpf_narg(args))(args)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./headers/bpf/bpf_helpers.h:195:29: note: expanded from macro '___bpf_apply'
#define ___bpf_apply(fn, n) ___bpf_concat(fn, n)
^
note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
:101:1: note: expanded from here
___bpf_kprobe_args1
^
./headers/bpf/bpf_tracing.h:789:72: note: expanded from macro '___bpf_kprobe_args1'
#define ___bpf_kprobe_args1(x) ___bpf_kprobe_args0(), (void *)PT_REGS_PARM1(ctx)
^~~~~~~~~~~~~~~~~~
./headers/bpf/bpf_tracing.h:485:44: note: expanded from macro 'PT_REGS_PARM1'
#define PT_REGS_PARM1(x) (__PT_REGS_CAST(x)->__PT_PARM1_REG)
~~~~~~~~~~~~~~~~~^
/home/parallels/Desktop/work/ptcpdump/bpf/ptcpdump.c:375:5: note: forward declaration of 'struct user_pt_regs'
./headers/bpf/bpf_tracing.h:817:20: note: expanded from macro 'BPF_KPROBE'
return ____##name(___bpf_kprobe_args(args));
^
./headers/bpf/bpf_tracing.h:797:41: note: expanded from macro '___bpf_kprobe_args'
#define ___bpf_kprobe_args(args...) ___bpf_apply(___bpf_kprobe_args, ___bpf_narg(args))(args)
^
./headers/bpf/bpf_helpers.h:195:29: note: expanded from macro '___bpf_apply'
#define ___bpf_apply(fn, n) ___bpf_concat(fn, n)
^
note: (skipping 2 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
./headers/bpf/bpf_tracing.h:789:72: note: expanded from macro '___bpf_kprobe_args1'
#define ___bpf_kprobe_args1(x) ___bpf_kprobe_args0(), (void *)PT_REGS_PARM1(ctx)
^
./headers/bpf/bpf_tracing.h:485:27: note: expanded from macro 'PT_REGS_PARM1'
#define PT_REGS_PARM1(x) (__PT_REGS_CAST(x)->__PT_PARM1_REG)
^
./headers/bpf/bpf_tracing.h:228:42: note: expanded from macro '__PT_REGS_CAST'
#define __PT_REGS_CAST(x) ((const struct user_pt_regs *)(x))
^
1 error generated.
Error: can't execute clang: exit status 1
exit status 1
bpf/bpf.go:18: running "go": exit status 1
make: *** [Makefile:61: build-bpf] Error 1
parallels@ubuntu-linux-22-04-desktop:/Desktop/work/ptcpdump$ make
make: Nothing to be done for 'libpcap'.
parallels@ubuntu-linux-22-04-desktop:
/Desktop/work/ptcpdump$


I use Apple(m2 max οΌ‰ to build a virtual machine and use the current project. It cannot be compiled or used normally. Do you have any plans to support it? Thank you very much for your contribution.

Truncated packets

Hi! Any reason why you have fixed max packet payload size to 1500?
I have MTUs which is bigger then this, like 65536, and it for sure gets cut.
Do you think it can be set automatically based on MTU? I guess it mostly affects memory usage?

Cannot run in Arch linux 6.6.39-1-lts

2024-07-19 08:57:53 WARN skip Docker Engine integration
2024-07-19 08:57:58 WARN skip containerd integration
2024-07-19 08:57:58 WARN skip kubernetes integration
2024-07-19 08:57:58 WARN current system doest not enable netfilter based NAT feature, skip attach kprobe/nf_nat_packet
2024-07-19 08:57:58 WARN current system doest not enable netfilter based NAT feature, skip attach kprobe/nf_nat_manip_pkt
2024-07-19 08:57:58 FATAL cmd/log.go:18] attach tc hooks: netlink receive: no such file or directory

Arch linux 6.6.39-1-lts

[Feature Request] Follow fork flag

Like what strace works. https://man7.org/linux/man-pages/man1/strace.1.html

   -f
   --follow-forks
               Trace  child  processes  as they are created by currently traced processes as a result of the fork(2),
               vfork(2) and clone(2) system calls.  Note that -p PID -f will attach all threads of process PID if  it
               is multi-threaded, not only thread with thread_id = PID.

Example
test.sh

curl https://baidu.com
curl https://qq.com

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): update all lvh-images main (patch)
  • fix(deps): update all go dependencies master (patch) (github.com/containerd/containerd, github.com/docker/docker, github.com/florianl/go-tc, k8s.io/cri-api, k8s.io/cri-client)
  • fix(deps): update all go dependencies master (minor) (github.com/cilium/ebpf, github.com/containerd/typeurl/v2)

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/release-test.yml
  • actions/checkout v4@692973e3d937129bcbf40652eb9f2f61becf3332
  • actions/setup-go v5@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32
  • goreleaser/goreleaser-action v6@286f3b13b1b49da4ac219696163fb8c1c93e1200
  • actions/upload-artifact v4@0b2256b8c012f0828dc542b3febcab082c67f72b
  • actions/upload-artifact v4@0b2256b8c012f0828dc542b3febcab082c67f72b
.github/workflows/release.yml
  • actions/checkout v4@692973e3d937129bcbf40652eb9f2f61becf3332
  • actions/setup-go v5@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32
  • goreleaser/goreleaser-action v6@286f3b13b1b49da4ac219696163fb8c1c93e1200
.github/workflows/test.yml
  • actions/checkout v4@692973e3d937129bcbf40652eb9f2f61becf3332
  • actions/setup-go v5@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32
  • actions/upload-artifact v4@0b2256b8c012f0828dc542b3febcab082c67f72b
  • actions/checkout v4@692973e3d937129bcbf40652eb9f2f61becf3332
  • actions/download-artifact v4@fa0a91b85d4f404e444e00e005971372dc801d16
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
  • cilium/little-vm-helper v0.0.19@97c89f004bd0ab4caeacfe92ebc956e13e362e6b
gomod
go.mod
  • go 1.22.0
  • github.com/cilium/ebpf v0.15.0
  • github.com/containerd/containerd v1.7.19
  • github.com/containerd/containerd/api v1.7.19
  • github.com/containerd/typeurl/v2 v2.1.1
  • github.com/docker/docker v26.1.4+incompatible
  • github.com/florianl/go-tc v0.4.3
  • github.com/gopacket/gopacket v1.2.0
  • github.com/jschwinger233/elibpcap v0.0.0-20231010035657-e99300096f5e@e99300096f5e
  • github.com/mholt/archiver/v4 v4.0.0-alpha.8
  • github.com/phuslu/log v1.0.107
  • github.com/shirou/gopsutil/v3 v3.24.5
  • github.com/spf13/cobra v1.8.1
  • github.com/x-way/pktdump v0.0.5
  • golang.org/x/sys v0.22.0
  • k8s.io/cri-client v0.31.0-alpha.3
  • k8s.io/klog/v2 v2.130.1
  • github.com/containerd/errdefs v0.1.0
  • go.opentelemetry.io/otel/trace v1.28.0
  • k8s.io/cri-api v0.31.0-alpha.3
regex
.github/workflows/test.yml
  • quay.io/lvh-images/kernel-images 4.19-20240717.161638
  • quay.io/lvh-images/kernel-images 5.4-20240717.161638
  • quay.io/lvh-images/kernel-images 5.10-20240717.161638
  • quay.io/lvh-images/kernel-images 5.15-20240717.161638
  • quay.io/lvh-images/kernel-images 6.1-20240717.161638
  • quay.io/lvh-images/kernel-images 6.6-20240717.161638
  • quay.io/lvh-images/kernel-images bpf-20240717.161638
  • quay.io/lvh-images/kernel-images bpf-next-20240718.013136

  • Check this box to trigger a request for Renovate to run again on this repository

Unable to display POD information correctly

The PCAPNG package I captured with the following command cannot display POD-related information. Do you need to make any additional settings?

ptcpdump -c 500  -vvv -i any --pod-name  wiz-soundai-boss-9c45c7bdc-jvfm7.default  -w test.pcap

test.pcapng.zip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.