Skip to content

Instantly share code, notes, and snippets.

@IanMercer
Created April 26, 2020 21:36
Show Gist options
  • Save IanMercer/f1a312b8513fe985a1b2055954f9ac56 to your computer and use it in GitHub Desktop.
Save IanMercer/f1a312b8513fe985a1b2055954f9ac56 to your computer and use it in GitHub Desktop.
Syslog service for dotnet to monitor WIFI and Switch connections and DHCP Requests
/*
This example Syslog service receives Syslog messages over UDP and publishes them internally using Rx
to an observable stream `Messages`.
If you point all your Ubiquity (TPLink or other) SysLog messages to a device running this code listening on
port 514 you can parse the messages and:
1) Determine which access point each cell phone is connected to.
2) Generate an alert every time a new device connects to your network.
3) Track guests by creating a 'honeypot' SSID like "Google Starbucks" that catches most visitors with Wifi on.
4) Generate an alert if a device hasn't renewed its DHCP address for some period of time (detect device failures).
*/
using System;
using System.Net;
using System.Net.Sockets;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Reactive.Threading.Tasks;
namespace Services.Syslog
{
public interface ISyslogService
{
IObservable<SyslogMessage> GetStream();
}
public class SyslogService : ISyslogService
{
private readonly Subject<SyslogMessage> messageBus = new Subject<SyslogMessage>();
private readonly ILogger log;
public IObservable<SyslogMessage> Messages => messageBus;
private readonly ICancellationService cancellationService;
public SyslogService(ICancellationService cancellationService, ILogger log)
{
this.cancellationService = cancellationService;
this.log = log;
}
public IObservable<SyslogMessage> GetStream()
{
var anyIp = new IPEndPoint(IPAddress.Any, 514);
var stream = UdpStream(anyIp).Select(Parse);
return stream;
}
private SyslogMessage Parse(UdpReceiveResult result)
{
var endpoint = result.RemoteEndPoint;
var text = System.Text.Encoding.ASCII.GetString(result.Buffer);
int priority = 8 + 1; // TODO
var timestamp = DateTime.Now;
string hostname = result.RemoteEndPoint.ToString();
return new SyslogMessage(endpoint, priority, timestamp, hostname, text);
}
public static IObservable<UdpReceiveResult> UdpStream(IPEndPoint endpoint)
{
return Observable.Using(() => new UdpClient(endpoint),
udpClient => Observable.Defer(() => udpClient.ReceiveAsync().ToObservable()).Repeat());
}
}
public class SyslogMessage
{
public SyslogMessage(IPEndPoint endPoint, int priority, DateTime timestamp, string hostname, string message)
{
this.EndPoint = endPoint;
this.Facility = priority/8;
this.Severity = priority%8;
this.Timestamp = timestamp;
this.Hostname = hostname;
this.Message = message;
}
public IPEndPoint EndPoint { get; }
public int Facility { get; }
public int Severity { get; }
public DateTime Timestamp { get; }
public string Hostname { get; }
public string Message { get; }
public override string ToString()
{
return
$"Facility: {Facility} Severity: {Severity} Timestamp: {Timestamp} Hostname: {Hostname} Message: {Message}";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment