-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
446 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
Oops, something went wrong.