MoniTraffic.sh
                        
                             · 2.4 KiB · Bash
                        
                    
                    
                      
                        原始檔案
                      
                    
                      
                    
                        
                          
                        
                    
                    
                
                
                
            #!/bin/bash
function monitor_traffic() {
    if [ -z "$1" ]; then
        echo "Usage: $0 <network_interface>"
        echo "Available network interfaces:"
        ip link show | awk -F': ' '/^[0-9]+: /{print $2}'
        exit 1
    fi
    INTERFACE=$1
    DURATION=10 # Duration in seconds for each capture window
    # Output header only once
    printf "IP Address\tDownload (bytes)\tUpload (bytes)\n"
    # Handle SIGINT (Ctrl+C) to gracefully exit the loop
    trap "echo 'Exiting...'; exit 0" SIGINT
    while true; do
        # Temp file to store tcpdump output
        TMP_FILE=$(mktemp)
        trap "rm -f $TMP_FILE" EXIT # Ensure cleanup on exit or interruption
        # Capture IPv4 traffic on the specified interface for the specified duration
        sudo timeout $DURATION tcpdump -i $INTERFACE -nn -q -tt 'ip' > $TMP_FILE 2>/dev/null
        # Calculate traffic statistics
        awk '
        /IP/ {
            # Extract source and destination IPs using a stricter pattern to ensure only IPs are captured
            if (match($3, /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)) {
                src_ip = substr($3, RSTART, RLENGTH)
            }
            if (match($5, /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)) {
                dst_ip = substr($5, RSTART, RLENGTH)
            }
            # Calculate packet size (bytes) - field 8 (better validation)
            size = $NF
            if (size ~ /^[0-9]+$/) {
                # Count download (dst_ip) and upload (src_ip) for traffic
                download[dst_ip] += size
                upload[src_ip] += size
            }
        }
        END {
            # Create a combined total_bytes array for sorting
            for (ip in download) {
                total_bytes[ip] = download[ip] + upload[ip]
            }
            # Sort IPs by total bytes in descending order
            n = asorti(total_bytes, sorted_ips, "@val_num_desc")
            for (i = 1; i <= n; i++) {
                ip = sorted_ips[i]
                download_data = download[ip] > 0 ? download[ip] : 0
                upload_data = upload[ip] > 0 ? upload[ip] : 0
                printf "%-15s\t%-15d\t%-15d\n", ip, download_data, upload_data
            }
        }' $TMP_FILE
        # Print separator line
        echo "======================================="
        # Clean up the temporary file
        rm -f $TMP_FILE
    done
}
# Call function with passed argument (network interface)
monitor_traffic $1
                | 1 | #!/bin/bash | 
| 2 | |
| 3 | function monitor_traffic() { | 
| 4 | if [ -z "$1" ]; then | 
| 5 | echo "Usage: $0 <network_interface>" | 
| 6 | echo "Available network interfaces:" | 
| 7 | ip link show | awk -F': ' '/^[0-9]+: /{print $2}' | 
| 8 | exit 1 | 
| 9 | fi | 
| 10 | |
| 11 | INTERFACE=$1 | 
| 12 | DURATION=10 # Duration in seconds for each capture window | 
| 13 | |
| 14 | # Output header only once | 
| 15 | printf "IP Address\tDownload (bytes)\tUpload (bytes)\n" | 
| 16 | |
| 17 | # Handle SIGINT (Ctrl+C) to gracefully exit the loop | 
| 18 | trap "echo 'Exiting...'; exit 0" SIGINT | 
| 19 | |
| 20 | while true; do | 
| 21 | # Temp file to store tcpdump output | 
| 22 | TMP_FILE=$(mktemp) | 
| 23 | trap "rm -f $TMP_FILE" EXIT # Ensure cleanup on exit or interruption | 
| 24 | |
| 25 | # Capture IPv4 traffic on the specified interface for the specified duration | 
| 26 | sudo timeout $DURATION tcpdump -i $INTERFACE -nn -q -tt 'ip' > $TMP_FILE 2>/dev/null | 
| 27 | |
| 28 | # Calculate traffic statistics | 
| 29 | awk ' | 
| 30 | /IP/ { | 
| 31 | # Extract source and destination IPs using a stricter pattern to ensure only IPs are captured | 
| 32 | if (match($3, /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)) { | 
| 33 | src_ip = substr($3, RSTART, RLENGTH) | 
| 34 | } | 
| 35 | if (match($5, /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)) { | 
| 36 | dst_ip = substr($5, RSTART, RLENGTH) | 
| 37 | } | 
| 38 | |
| 39 | # Calculate packet size (bytes) - field 8 (better validation) | 
| 40 | size = $NF | 
| 41 | if (size ~ /^[0-9]+$/) { | 
| 42 | # Count download (dst_ip) and upload (src_ip) for traffic | 
| 43 | download[dst_ip] += size | 
| 44 | upload[src_ip] += size | 
| 45 | } | 
| 46 | } | 
| 47 | END { | 
| 48 | # Create a combined total_bytes array for sorting | 
| 49 | for (ip in download) { | 
| 50 | total_bytes[ip] = download[ip] + upload[ip] | 
| 51 | } | 
| 52 | |
| 53 | # Sort IPs by total bytes in descending order | 
| 54 | n = asorti(total_bytes, sorted_ips, "@val_num_desc") | 
| 55 | |
| 56 | for (i = 1; i <= n; i++) { | 
| 57 | ip = sorted_ips[i] | 
| 58 | download_data = download[ip] > 0 ? download[ip] : 0 | 
| 59 | upload_data = upload[ip] > 0 ? upload[ip] : 0 | 
| 60 | printf "%-15s\t%-15d\t%-15d\n", ip, download_data, upload_data | 
| 61 | } | 
| 62 | }' $TMP_FILE | 
| 63 | |
| 64 | # Print separator line | 
| 65 | echo "=======================================" | 
| 66 | |
| 67 | # Clean up the temporary file | 
| 68 | rm -f $TMP_FILE | 
| 69 | done | 
| 70 | } | 
| 71 | |
| 72 | # Call function with passed argument (network interface) | 
| 73 | monitor_traffic $1 | 
| 74 | 
                    
                        
                        Program.cs
                        
                             · 3.2 KiB · C#
                        
                    
                    
                      
                        原始檔案
                      
                    
                      
                    
                        
                          
                        
                    
                    
                
                
                
                //<PackageReference Include="Aiursoft.AiurObserver.Command" Version="8.0.4" />
    //<PackageReference Include="Aiursoft.AiurObserver.Extensions" Version="8.0.3" />
    //<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
using Aiursoft.AiurObserver;
using Aiursoft.AiurObserver.Command;
using Microsoft.Extensions.Logging;
using Aiursoft.AiurObserver.Extensions;
namespace Moni;
public abstract class Program
{
    private BlockRule[] _rules = new[]
    {
        // 8MiB/s, 80MiB in 10 seconds
        new BlockRule
        {
            MaxBytesTransferred = 0x500_0000,
            IntervalSeconds = 10
        },
        // 6MiB/s, 360MiB in 60 seconds
        new BlockRule
        {
            MaxBytesTransferred = 0x1680_0000,
            IntervalSeconds = 60
        },
        // 5MiB/s, 1500MiB in 300 seconds (5 minutes)
        new BlockRule
        {
            MaxBytesTransferred = 0x5DC0_0000,
            IntervalSeconds = 300
        },
        // 4MiB/s, 2400MiB in 600 seconds (10 minutes)
        new BlockRule
        {
            MaxBytesTransferred = 0x9600_0000,
            IntervalSeconds = 600
        },
        // 3MiB/s, 3600MiB in 1200 seconds (20 minutes)
        new BlockRule
        {
            MaxBytesTransferred = 0xE10_0000,
            IntervalSeconds = 1200
        }
    };
    private static Dictionary<string, long> IpTrafficUsage { get; } = new();
    
    public static async Task Main(string[] args)
    {
        if (args.Length != 1)
        {
            Console.WriteLine("Please provide the network interface name.");
            return;
        }
        
        var interfaceName = args[0];
        
        var logger = LoggerFactory.Create(logging => logging.AddConsole()).CreateLogger<LongCommandRunner>();
        var runner = new LongCommandRunner(logger);
        // Returns every 10 seconds
        runner.Output.InNewThread().Subscribe(OnLog);
        
        await runner.Run(
            bin: "/usr/bin/bash",
            arg: $"/usr/local/bin/moninet {interfaceName}",
            path: "/");
    }
    private static Task OnLog(string rawOutput)
    {
        var outputLines = rawOutput.Split("\n");
        foreach (var line in outputLines.Select(outputLine => outputLine.Trim()))
        {
            if (line.StartsWith("IP Address")) continue;
            if (line.StartsWith("===")) continue;
            var parts = line.Split(" ", StringSplitOptions.RemoveEmptyEntries)
                .Select(part => part.Trim())
                .ToArray();
            if (parts.Length != 3) continue;
            var ipAddr = parts[0];
            var download = long.Parse(parts[1]);
            var upload = long.Parse(parts[2]);
            Console.WriteLine($"In the past 10 seconds, remote IP {ipAddr} downloaded {download} bytes and uploaded {upload} bytes.");
            var totalTraffic = download + upload;
            IpTrafficUsage[ipAddr] = IpTrafficUsage.TryGetValue(ipAddr, out var usage) ? usage + totalTraffic : totalTraffic;
        }
        return Task.CompletedTask;
    }
}
public class BlockRule
{
    public long MaxBytesTransferred { get; set; }
    
    public int IntervalSeconds { get; set; }
}
                | 1 | //<PackageReference Include="Aiursoft.AiurObserver.Command" Version="8.0.4" /> | 
| 2 | //<PackageReference Include="Aiursoft.AiurObserver.Extensions" Version="8.0.3" /> | 
| 3 | //<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" /> | 
| 4 | |
| 5 | using Aiursoft.AiurObserver; | 
| 6 | using Aiursoft.AiurObserver.Command; | 
| 7 | using Microsoft.Extensions.Logging; | 
| 8 | using Aiursoft.AiurObserver.Extensions; | 
| 9 | |
| 10 | namespace Moni; | 
| 11 | |
| 12 | public abstract class Program | 
| 13 | { | 
| 14 | private BlockRule[] _rules = new[] | 
| 15 | { | 
| 16 | // 8MiB/s, 80MiB in 10 seconds | 
| 17 | new BlockRule | 
| 18 | { | 
| 19 | MaxBytesTransferred = 0x500_0000, | 
| 20 | IntervalSeconds = 10 | 
| 21 | }, | 
| 22 | // 6MiB/s, 360MiB in 60 seconds | 
| 23 | new BlockRule | 
| 24 | { | 
| 25 | MaxBytesTransferred = 0x1680_0000, | 
| 26 | IntervalSeconds = 60 | 
| 27 | }, | 
| 28 | // 5MiB/s, 1500MiB in 300 seconds (5 minutes) | 
| 29 | new BlockRule | 
| 30 | { | 
| 31 | MaxBytesTransferred = 0x5DC0_0000, | 
| 32 | IntervalSeconds = 300 | 
| 33 | }, | 
| 34 | // 4MiB/s, 2400MiB in 600 seconds (10 minutes) | 
| 35 | new BlockRule | 
| 36 | { | 
| 37 | MaxBytesTransferred = 0x9600_0000, | 
| 38 | IntervalSeconds = 600 | 
| 39 | }, | 
| 40 | // 3MiB/s, 3600MiB in 1200 seconds (20 minutes) | 
| 41 | new BlockRule | 
| 42 | { | 
| 43 | MaxBytesTransferred = 0xE10_0000, | 
| 44 | IntervalSeconds = 1200 | 
| 45 | } | 
| 46 | }; | 
| 47 | |
| 48 | private static Dictionary<string, long> IpTrafficUsage { get; } = new(); | 
| 49 | |
| 50 | public static async Task Main(string[] args) | 
| 51 | { | 
| 52 | if (args.Length != 1) | 
| 53 | { | 
| 54 | Console.WriteLine("Please provide the network interface name."); | 
| 55 | return; | 
| 56 | } | 
| 57 | |
| 58 | var interfaceName = args[0]; | 
| 59 | |
| 60 | var logger = LoggerFactory.Create(logging => logging.AddConsole()).CreateLogger<LongCommandRunner>(); | 
| 61 | var runner = new LongCommandRunner(logger); | 
| 62 | |
| 63 | // Returns every 10 seconds | 
| 64 | runner.Output.InNewThread().Subscribe(OnLog); | 
| 65 | |
| 66 | await runner.Run( | 
| 67 | bin: "/usr/bin/bash", | 
| 68 | arg: $"/usr/local/bin/moninet {interfaceName}", | 
| 69 | path: "/"); | 
| 70 | } | 
| 71 | |
| 72 | private static Task OnLog(string rawOutput) | 
| 73 | { | 
| 74 | var outputLines = rawOutput.Split("\n"); | 
| 75 | foreach (var line in outputLines.Select(outputLine => outputLine.Trim())) | 
| 76 | { | 
| 77 | if (line.StartsWith("IP Address")) continue; | 
| 78 | if (line.StartsWith("===")) continue; | 
| 79 | var parts = line.Split(" ", StringSplitOptions.RemoveEmptyEntries) | 
| 80 | .Select(part => part.Trim()) | 
| 81 | .ToArray(); | 
| 82 | if (parts.Length != 3) continue; | 
| 83 | |
| 84 | var ipAddr = parts[0]; | 
| 85 | var download = long.Parse(parts[1]); | 
| 86 | var upload = long.Parse(parts[2]); | 
| 87 | Console.WriteLine($"In the past 10 seconds, remote IP {ipAddr} downloaded {download} bytes and uploaded {upload} bytes."); | 
| 88 | var totalTraffic = download + upload; | 
| 89 | IpTrafficUsage[ipAddr] = IpTrafficUsage.TryGetValue(ipAddr, out var usage) ? usage + totalTraffic : totalTraffic; | 
| 90 | } | 
| 91 | |
| 92 | return Task.CompletedTask; | 
| 93 | } | 
| 94 | } | 
| 95 | |
| 96 | public class BlockRule | 
| 97 | { | 
| 98 | public long MaxBytesTransferred { get; set; } | 
| 99 | |
| 100 | public int IntervalSeconds { get; set; } | 
| 101 | } | 
                    
                        
                        install.sh
                        
                             · 161 B · Bash
                        
                    
                    
                      
                        原始檔案
                      
                    
                      
                    
                        
                          
                        
                    
                    
                
                
                
            sudo wget https://gist.aiursoft.cn/anduin/e66120d03c9945dda921d0fb2039cb38/raw/HEAD/MoniTraffic.sh -O /usr/local/bin/moninet
sudo chmod +x /usr/local/bin/moninet
                | 1 | sudo wget https://gist.aiursoft.cn/anduin/e66120d03c9945dda921d0fb2039cb38/raw/HEAD/MoniTraffic.sh -O /usr/local/bin/moninet | 
| 2 | sudo chmod +x /usr/local/bin/moninet |