Skip to content

Commit

Permalink
Add source code.
Browse files Browse the repository at this point in the history
  • Loading branch information
gamemann committed Jun 3, 2020
1 parent 29e11e3 commit 6ae24f8
Show file tree
Hide file tree
Showing 5 changed files with 446 additions and 0 deletions.
71 changes: 71 additions & 0 deletions src/asn/asn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package asn

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"time"
)

type Prefixes struct {
Prefix string `json:"prefix"`
}

type Data struct {
Prefixes []Prefixes `json:"ipv4_prefixes"`
}

type Response struct {
Status string `json:"status"`
Data Data `json:"data"`
}

func ListPrefixes(ASN int) []string {
// Initialize empty list.
var list []string

// Build URL.
url := "https://api.bgpview.io/asn/AS" + strconv.Itoa(ASN) + "/prefixes"

// Setup HTTP GET request.
client := &http.Client{Timeout: time.Second * 5}
req, _ := http.NewRequest("GET", url, nil)

// Perform GET request.
resp, err := client.Do(req)

// Check for errors.
if err != nil {
fmt.Println(err)
}

// Ensure to close body at end of execution.
defer resp.Body.Close()

// Read output.
body, err := ioutil.ReadAll(resp.Body)

// Check for errors.
if err != nil {
fmt.Println(err)
}

// Create JSON response.
var jsonResp Response

// Prase JSON response.
err = json.Unmarshal([]byte(string(body)), &jsonResp)

if err != nil {
fmt.Println(err)
}

// Loop through each prefix and add to list.
for _, v := range jsonResp.Data.Prefixes {
list = append(list, v.Prefix)
}

return list
}
56 changes: 56 additions & 0 deletions src/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package config

import (
"encoding/json"
"fmt"
"os"
)

type Config struct {
Token string `json:"token"`
Port int `json:"port"`
UpdateTime int `json:"updatetime"`
}

func ReadConfig(cfg *Config, filename string) bool {
// Open config file.
file, err := os.Open(filename)

// Check for errors.
if err != nil {
fmt.Println("Error opening config file.")

return false
}

// Defer file close.
defer file.Close()

// Create stat.
stat, _ := file.Stat()

// Make data.
data := make([]byte, stat.Size())

// Read data.
_, err = file.Read(data)

// Check for errors.
if err != nil {
fmt.Println("Error reading config file.")

return false
}

// Parse JSON data.
err = json.Unmarshal([]byte(data), cfg)

// Check for errors.
if err != nil {
fmt.Println("Error parsing JSON Data.")

return false
}

return true
}
79 changes: 79 additions & 0 deletions src/iplist.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package main

import (
"./config"
"./list"
"./webserver"
"log"
"os"
"os/signal"
"syscall"
"time"
)

func UpdateEverything(lists *list.Lists, timer *time.Ticker) {
destroy := make(chan struct{})

for {
select {
case <-timer.C:
// First retreive new lists
*lists = list.GetLists()

// Update the public files.
list.UpdateLists(lists)
case <-destroy:
timer.Stop()

return
}
}
}

func main() {
// Initialize config.
cfg := config.Config{}

// Read config file.
config.ReadConfig(&cfg, "settings.conf")

// Create lists variable.
var lists list.Lists

// Get all initial lists.
lists = list.GetLists()

// Update the public files.
list.UpdateLists(&lists)

// Create timer that'll update the lists every x seconds.
ticker := time.NewTicker(time.Duration(cfg.UpdateTime) * time.Second)
go UpdateEverything(&lists, ticker)

// Create web server.
log.Fatal(webserver.CreateWebServer(cfg.Token, cfg.Port))

// Signal.
sigc := make(chan os.Signal, 1)
signal.Notify(sigc, syscall.SIGINT)

x := 0

// Create a loop so the program doesn't exit. Look for signals and if SIGINT, stop the program.
for x < 1 {
kill := false
s := <-sigc

switch s {
case os.Interrupt:
kill = true
}

if kill {
break
}

// Sleep every second to avoid unnecessary CPU consumption.
time.Sleep(time.Duration(1) * time.Second)
}
}
170 changes: 170 additions & 0 deletions src/list/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package list

import (
"../asn"
"bufio"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
)

type JSONList struct {
ASNs []int `json:"ASN"`
Prefixes []string `json:"Prefix"`
}

type List struct {
Name string
Prefixes []string
}

type Lists struct {
Lists []List
}

func UpdateLists(lists *Lists) {
// Loop through each list and update.
for _, v := range lists.Lists {
UpdateList(&v)
}
}

func UpdateList(list *List) bool {
// Open file.
file, err := os.OpenFile("public/"+list.Name+".txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)

// Check for errors.
if err != nil {
fmt.Println(err)

return false
}

// Remove contents of file.
file.Truncate(0)
file.Seek(0, 0)

// Loop through each prefix and write them to the file as a new line.
w := bufio.NewWriter(file)

for _, v := range list.Prefixes {
_, _ = w.WriteString(v + "\n")
}

// Flush buffer.
w.Flush()

// Close file.
file.Close()

return true
}

func ParseList(name string) JSONList {
// Initiate empty List struct.
var list JSONList

// Open JSON list file.
file, err := os.Open("lists/" + name + ".json")

// Check for errors.
if err != nil {
fmt.Println("Error opening list \"" + name + "\".")

return list
}

// Defer file close.
defer file.Close()

// Create stat.
stat, _ := file.Stat()

// Make data.
data := make([]byte, stat.Size())

// Read data.
_, err = file.Read(data)

// Check for errors.
if err != nil {
fmt.Println("Error reading config file.")

return list
}

// Parse JSON data.
err = json.Unmarshal([]byte(string(data)), &list)

// Check for errors.
if err != nil {
fmt.Println("Error parsing JSON Data.")

return list
}

return list
}

func ExtractList(json JSONList) []string {
// Create empty prefixes list.
var prefixes []string

// Loop through each AS and do appropriate lookups. After lookups, append to list.
for _, v := range json.ASNs {
prefixes = append(prefixes, asn.ListPrefixes(v)...)
}

// Loop through each additional prefix and add.
for _, v := range json.Prefixes {
prefixes = append(prefixes, v)
}

return prefixes
}

func GetLists() Lists {
// Initialize empty lists slice.
var lists Lists

// Read a directory.
files, err := ioutil.ReadDir("lists/")

// Check for errors.
if err != nil {
fmt.Println(err)
}

for _, f := range files {
// Check if this is a directory.
if f.IsDir() {
continue
}

// Get file name without extension.
name := strings.TrimSuffix(f.Name(), filepath.Ext(f.Name()))

// Parse specific list.
jsonlists := ParseList(name)

// Extract all IPs including ASN prefixes.
prefixes := ExtractList(jsonlists)

// Create list.
var list List

// Assign name.
list.Name = name

// Append prefixes to list.
list.Prefixes = append(list.Prefixes, prefixes...)

// Add list to lists variable.
lists.Lists = append(lists.Lists, list)
}

return lists
}
Loading

0 comments on commit 6ae24f8

Please sign in to comment.