| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- package ovpm
- import (
- "bufio"
- "io"
- "strconv"
- "strings"
- "time"
- )
- // clEntry reprsents a parsed entry that is present on OpenVPN
- // log section CLIENT LIST.
- type clEntry struct {
- CommonName string `json:"common_name"`
- RealAddress string `json:"real_address"`
- BytesReceived uint64 `json:"bytes_received"`
- BytesSent uint64 `json:"bytes_sent"`
- ConnectedSince time.Time `json:"connected_since"`
- }
- // rtEntry reprsents a parsed entry that is present on OpenVPN
- // log section ROUTING TABLE.
- type rtEntry struct {
- VirtualAddress string `json:"virtual_address"`
- CommonName string `json:"common_name"`
- RealAddress string `json:"real_address"`
- LastRef time.Time `json:"last_ref"`
- }
- // parseStatusLog parses the received OpenVPN status log file.
- // And then returns the parsed client information.
- func parseStatusLog(f io.Reader) ([]clEntry, []rtEntry) {
- // Parsing stages.
- const stageCL int = 0
- const stageRT int = 1
- const stageFin int = 2
- // Parsing variables.
- var currStage int
- var skipFor int
- var cl []clEntry
- var rt []rtEntry
- // Scan and parse the file by dividing it into chunks.
- scanner, skipFor := bufio.NewScanner(f), 3
- for lc := 0; scanner.Scan(); lc++ {
- if skipFor > 0 {
- skipFor--
- continue
- }
- txt := scanner.Text()
- switch currStage {
- case stageCL:
- if strings.Contains(txt, "ROUTING TABLE") {
- currStage = stageRT
- skipFor = 1
- continue
- }
- dat := strings.Split(txt, ",")
- cl = append(cl, clEntry{
- CommonName: trim(dat[0]),
- RealAddress: trim(dat[1]),
- BytesReceived: stoui64(trim(dat[2])),
- BytesSent: stoui64(trim(dat[3])),
- ConnectedSince: stodt(trim(dat[4])),
- })
- case stageRT:
- if strings.Contains(txt, "GLOBAL STATS") {
- currStage = stageFin
- break
- }
- dat := strings.Split(txt, ",")
- rt = append(rt, rtEntry{
- VirtualAddress: trim(dat[0]),
- CommonName: trim(dat[1]),
- RealAddress: trim(dat[2]),
- LastRef: stodt(trim(dat[3])),
- })
- }
- }
- if err := scanner.Err(); err != nil {
- panic(err)
- }
- return cl, rt
- }
- // stoi64 converts string to uint64.
- func stoui64(s string) uint64 {
- i, err := strconv.ParseInt(s, 0, 64)
- if err != nil {
- panic(err)
- }
- return uint64(i)
- }
- // stodt converts string to date time.
- func stodt(s string) time.Time {
- t, err := time.ParseInLocation(time.ANSIC, s, time.Local)
- if err != nil {
- panic(err)
- }
- return t
- }
- // trim will trim all leading and trailing whitespace from the s.
- func trim(s string) string {
- return strings.TrimSpace(s)
- }
|