mirror of
https://github.com/pnx/pinger.git
synced 2026-06-16 03:24:54 +02:00
Compare commits
26 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 30cee15b19 | |||
| 26de4fa647 | |||
| b9c0d0b416 | |||
| a4343fa706 | |||
| 7870fc361a | |||
| fffed4e4e1 | |||
| 57a969561e | |||
| 2747946264 | |||
| 5571ba3f38 | |||
| 111ff58fcf | |||
| aa05c99bea | |||
| ad48db3b0a | |||
| 4869175152 | |||
| 771e1b994a | |||
| 7dac879682 | |||
| 74a3e98e5b | |||
| c010b082da | |||
| ab292886a8 | |||
| cef5f5daba | |||
| e7c49dac1c | |||
| ede1205501 | |||
| dfc7865bc1 | |||
| fb4c8fea9c | |||
| 39d20366dc | |||
| afd054ff67 | |||
| 427a75f93e |
10 changed files with 176 additions and 63 deletions
41
.github/workflows/release.yml
vendored
Normal file
41
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
name: Release
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [ created ]
|
||||
|
||||
jobs:
|
||||
compile:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ linux, darwin, windows ]
|
||||
arch: [ amd64, 386 ]
|
||||
exclude:
|
||||
- os: darwin
|
||||
arch: 386
|
||||
name: Release - ${{matrix.os}}-${{matrix.arch}}
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.20"
|
||||
|
||||
- name: compile
|
||||
run: |
|
||||
GOOS=${{matrix.os}} GOARCH=${{matrix.arch}} make
|
||||
|
||||
- name: Upload release assets
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ github.event.release.upload_url }}
|
||||
asset_name: pinger-${{github.event.release.tag_name}}-${{matrix.os}}-${{matrix.arch}}
|
||||
asset_path: pinger
|
||||
asset_content_type: application/octal-stream
|
||||
27
.github/workflows/test.yml
vendored
Normal file
27
.github/workflows/test.yml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
jobs:
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.20'
|
||||
|
||||
- name: Fmt
|
||||
run: go fmt $(go list ./... | grep -v /vendor/)
|
||||
- name: Vet
|
||||
run: go vet $(go list ./... | grep -v /vendor/)
|
||||
- name: Test
|
||||
run: go test -race $(go list ./... | grep -v /vendor/)
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
*.exe
|
||||
pinger
|
||||
*.exe
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
# This file is a template, and might need editing before it works on your project.
|
||||
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||
#
|
||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||
# This specific template is located at:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Go.gitlab-ci.yml
|
||||
|
||||
image: golang:latest
|
||||
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- deploy
|
||||
|
||||
format:
|
||||
stage: test
|
||||
script:
|
||||
- go fmt $(go list ./... | grep -v /vendor/)
|
||||
- go vet $(go list ./... | grep -v /vendor/)
|
||||
- go test -race $(go list ./... | grep -v /vendor/)
|
||||
|
||||
compile:
|
||||
stage: build
|
||||
script:
|
||||
- mkdir -p bin
|
||||
- GOOS=windows GOARCH=386 go build -o bin/pinger-32.exe ./...
|
||||
- GOOS=windows GOARCH=amd64 go build -o bin/pinger-x64.exe ./...
|
||||
- GOOS=linux GOARCH=386 go build -o bin/pinger-linux-x86 ./...
|
||||
- GOOS=linux GOARCH=amd64 go build -o bin/pinger-linux-x64 ./...
|
||||
artifacts:
|
||||
paths:
|
||||
- bin
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
script: echo "Define your deployment script!"
|
||||
environment: production
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023-2026 Henrik Hautakoski
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
5
Makefile
Normal file
5
Makefile
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
GO=go
|
||||
|
||||
pinger : main.go
|
||||
$(GO) build -o $@ $^
|
||||
58
README.md
Normal file
58
README.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# Pinger
|
||||
|
||||
**Pinger** is a lightweight, high-performance network utility written in Go.
|
||||
It enables users to send ICMP echo requests (pings) to specified hosts, facilitating network diagnostics and monitoring.
|
||||
|
||||
## Features
|
||||
|
||||
* Send ICMP echo requests to specified hosts.
|
||||
* Measure round-trip time (RTT) for each ping.
|
||||
* Support for both IPv4 and IPv6 addresses.
|
||||
* Configurable number of ping attempts and intervals.
|
||||
* Lightweight and efficient, suitable for scripting and automation.
|
||||
|
||||
## Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* Go (version 1.20 or later) installed on your system.
|
||||
* make
|
||||
|
||||
### Steps
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/pnx/pinger.git
|
||||
cd pinger
|
||||
```
|
||||
|
||||
2. Build the application:
|
||||
|
||||
```bash
|
||||
make
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
See `./pinger -h`
|
||||
|
||||
### Example
|
||||
|
||||
```bash
|
||||
./pinger --udp -t 30s example.com
|
||||
```
|
||||
|
||||
This command sends UDP echo requests to example.com, stopping after 30 seconds
|
||||
|
||||
```bash
|
||||
./pinger -c 8 -i 1s example.com
|
||||
```
|
||||
|
||||
This command sends 8 ICMP echo requests to example.com, with a 1-second interval between pings.
|
||||
|
||||
NOTE: this requires root privileges
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
||||
8
go.mod
8
go.mod
|
|
@ -1,6 +1,6 @@
|
|||
module pinger
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/pborman/getopt/v2 v2.1.0
|
||||
|
|
@ -9,7 +9,7 @@ require (
|
|||
|
||||
require (
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
golang.org/x/net v0.5.0 // indirect
|
||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
)
|
||||
|
|
|
|||
12
go.sum
12
go.sum
|
|
@ -4,9 +4,9 @@ github.com/pborman/getopt/v2 v2.1.0 h1:eNfR+r+dWLdWmV8g5OlpyrTYHkhVNxHBdN2cCrJmO
|
|||
github.com/pborman/getopt/v2 v2.1.0/go.mod h1:4NtW75ny4eBw9fO1bhtNdYTlZKYX5/tBLtsOpwKIKd0=
|
||||
github.com/prometheus-community/pro-bing v0.1.0 h1:zjzLGhfNPP0bP1OlzGB+SJcguOViw7df12LPg2vUJh8=
|
||||
github.com/prometheus-community/pro-bing v0.1.0/go.mod h1:BpWlHurD9flHtzq8wrh8QGWYz9ka9z9ZJAyOel8ej58=
|
||||
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
|
||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
|
|||
25
main.go
25
main.go
|
|
@ -8,13 +8,11 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/pborman/getopt/v2"
|
||||
"github.com/prometheus-community/pro-bing"
|
||||
probing "github.com/prometheus-community/pro-bing"
|
||||
)
|
||||
|
||||
// printStats prints statistics from a ping.
|
||||
func printStats(pinger *probing.Pinger) {
|
||||
stats := pinger.Statistics()
|
||||
|
||||
func printStats(stats *probing.Statistics) {
|
||||
fmt.Printf("%d packets transmitted, %d packets received, %.2f%% packet loss\n",
|
||||
stats.PacketsSent, stats.PacketsRecv, stats.PacketLoss)
|
||||
|
||||
|
|
@ -22,8 +20,9 @@ func printStats(pinger *probing.Pinger) {
|
|||
stats.MinRtt, stats.AvgRtt, stats.MaxRtt, stats.StdDevRtt)
|
||||
}
|
||||
|
||||
func eventLoop(pinger *probing.Pinger) {
|
||||
ticker := time.NewTicker(time.Second * 4)
|
||||
func eventLoop(pinger *probing.Pinger, ticker *time.Ticker) {
|
||||
defer ticker.Stop()
|
||||
defer pinger.Stop()
|
||||
|
||||
// Setup signals on term and interrupt.
|
||||
sig := make(chan os.Signal, 1)
|
||||
|
|
@ -32,13 +31,12 @@ func eventLoop(pinger *probing.Pinger) {
|
|||
for {
|
||||
select {
|
||||
// Got signal. stop pinger and exit goroutine
|
||||
case <-sig:
|
||||
ticker.Stop()
|
||||
pinger.Stop()
|
||||
case s := <-sig:
|
||||
fmt.Printf("Recived signal: %s, exiting.\n", s)
|
||||
return
|
||||
// Ticker ticks. print stats.
|
||||
case <-ticker.C:
|
||||
printStats(pinger)
|
||||
printStats(pinger.Statistics())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -51,6 +49,7 @@ func main() {
|
|||
count := getopt.IntLong("count", 'c', 0, "Stop after this many packages has been sent (and received). If this option is not specified, pinger will operate until interrupted.")
|
||||
timeout := getopt.DurationLong("timeout", 't', 0, "Exit the program after this time is reached, regardless of how many packets have been received.")
|
||||
interval := getopt.DurationLong("interval", 'i', time.Second*2, "Wait time between each packet send")
|
||||
statsInterval := getopt.DurationLong("stats-interval", 0, time.Second*4, "How often stats should be printed to the console.")
|
||||
proto_udp := getopt.BoolLong("udp", 0, "Send UDP ping instead of a raw IMCP ping, IMCP required super-user privileges")
|
||||
record_rtt := getopt.BoolLong("rtt", 0, "Keep a record of rtts of all received packets.")
|
||||
|
||||
|
|
@ -58,7 +57,7 @@ func main() {
|
|||
getopt.Parse()
|
||||
|
||||
if *version {
|
||||
fmt.Println("Version 0.0.1")
|
||||
fmt.Println("Version 0.0.4")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
|
|
@ -79,17 +78,17 @@ func main() {
|
|||
pinger.Source = *source
|
||||
pinger.Count = *count
|
||||
pinger.RecordRtts = *record_rtt
|
||||
pinger.OnFinish = printStats
|
||||
if timeout != nil && *timeout > 0 {
|
||||
pinger.Timeout = *timeout
|
||||
}
|
||||
|
||||
// Enter event loop in another goroutine.
|
||||
go eventLoop(pinger)
|
||||
go eventLoop(pinger, time.NewTicker(*statsInterval))
|
||||
|
||||
// Run pinger in main thread.
|
||||
fmt.Println("PING", pinger.Addr())
|
||||
if err = pinger.Run(); err != nil {
|
||||
fmt.Println("Error:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue