From 601227a20fd415ecacf39765f19cdf72acc689f4 Mon Sep 17 00:00:00 2001 From: eltrac Date: Thu, 5 Nov 2026 11:20:32 +0800 Subject: asn: move asn/ to pkg/asn/; add lookup.goq only export Lookup() and IsDatacenter() --- asn/mapping.go | 105 ----------------------------------------------------- pkg/asn/lookup.go | 18 +++++++++ pkg/asn/mapping.go | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 105 deletions(-) delete mode 100644 asn/mapping.go create mode 100644 pkg/asn/lookup.go create mode 100644 pkg/asn/mapping.go diff --git a/asn/mapping.go b/asn/mapping.go deleted file mode 100644 index 79372a2..0000000 --- a/asn/mapping.go +++ /dev/null @@ -1,105 +0,0 @@ -package asn - -import ( - "fmt" - "io" - "log" - "net/http" - "os" - "path/filepath" - - "github.com/adrg/xdg" - "github.com/gocarina/gocsv" -) - -const SOURCE string = "https://cdn.jsdelivr.net/gh/ipverse/as-metadata@master/as.csv" - -type AsnEntry struct { - ASN int `csv:"asn"` - Handle string `csv:"handle"` - Description string `csv:"description"` - CountryCode string `csv:"country-code"` -} - -type AsnMap map[int]AsnEntry - -// localPath returns the destination of local copy of asn metadata -func localPath() string { - return filepath.Join(xdg.DataHome, "/audidi/as.csv") -} - -// downloadAsnSource downloads ASN metadata source to disk -func downloadAsnSource() error { - resp, err := http.Get(SOURCE) - if err != nil { - return fmt.Errorf("error fetching ASN metadata: %s", err) - } - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("error fetching ASN metadata: http %d", resp.StatusCode) - } - defer resp.Body.Close() - - file, err := os.Create(localPath()) - if err != nil { - return fmt.Errorf("can't open file to write ASN metadata: %s", err) - } - - if _, err := io.Copy(file, resp.Body); err != nil { - return fmt.Errorf("can't copy ASN metadata to file: %s", err) - } - - return nil -} - -// useAsnSource returns either a local cached version of -// ASN source bytes or download from source -func useAsnSource() ([]byte, error) { - path := localPath() - os.MkdirAll(filepath.Dir(path), os.ModePerm) - - if info, err := os.Stat(path); os.IsNotExist(err) || info.Size() == 0 { - log.Println("downloading ASN metadata...") - if err := downloadAsnSource(); err != nil { - return nil, err - } - log.Println("ASN metadata downloaded") - } - - bytes, err := os.ReadFile(path) - if err != nil { - return nil, fmt.Errorf("can't open file to read ASN metadata: %s", err) - } - - return bytes, nil -} - -// parseMetadata parse raw bytes of ASN metadata into readable entries -func parseMetadata(bytes []byte) ([]AsnEntry, error) { - var entries []AsnEntry - - if err := gocsv.UnmarshalBytes(bytes, &entries); err != nil { - return nil, fmt.Errorf("can't parse ASN metadata: %s", err) - } - - return entries, nil -} - -// GetMapping returns a pointer to ASN-metadata mappings -func GetMapping() *AsnMap { - bytes, err := useAsnSource() - if err != nil { - log.Fatalln("Failed to load ASN metadata: ", err) - } - - entries, err := parseMetadata(bytes) - if err != nil { - log.Fatalln("Failed to parse ASN metadata (Delete data and retry): ", err) - } - - mapping := make(AsnMap) - for _, entry := range entries { - mapping[entry.ASN] = entry - } - - return &mapping -} diff --git a/pkg/asn/lookup.go b/pkg/asn/lookup.go new file mode 100644 index 0000000..4851a6f --- /dev/null +++ b/pkg/asn/lookup.go @@ -0,0 +1,18 @@ +package asn + +var AsnTable AsnMap + +// Lookup return metadata of given AS +func Lookup(ASN int) AsnEntry { + if len(AsnTable) == 0 { + AsnTable = getMapping() + } + + return AsnTable[ASN] +} + +// IsDatacenter return bool value whether an AS is datajjij center or not +func IsDatacenter(ASN int) bool { + // TODO + return false +} diff --git a/pkg/asn/mapping.go b/pkg/asn/mapping.go new file mode 100644 index 0000000..14272de --- /dev/null +++ b/pkg/asn/mapping.go @@ -0,0 +1,105 @@ +package asn + +import ( + "fmt" + "io" + "log" + "net/http" + "os" + "path/filepath" + + "github.com/adrg/xdg" + "github.com/gocarina/gocsv" +) + +const SOURCE string = "https://cdn.jsdelivr.net/gh/ipverse/as-metadata@master/as.csv" + +type AsnEntry struct { + ASN int `csv:"asn"` + Handle string `csv:"handle"` + Description string `csv:"description"` + CountryCode string `csv:"country-code"` +} + +type AsnMap map[int]AsnEntry + +// localPath returns the destination of local copy of asn metadata +func localPath() string { + return filepath.Join(xdg.DataHome, "/audidi/as.csv") +} + +// downloadAsnSource downloads ASN metadata source to disk +func downloadAsnSource() error { + resp, err := http.Get(SOURCE) + if err != nil { + return fmt.Errorf("error fetching ASN metadata: %s", err) + } + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("error fetching ASN metadata: http %d", resp.StatusCode) + } + defer resp.Body.Close() + + file, err := os.Create(localPath()) + if err != nil { + return fmt.Errorf("can't open file to write ASN metadata: %s", err) + } + + if _, err := io.Copy(file, resp.Body); err != nil { + return fmt.Errorf("can't copy ASN metadata to file: %s", err) + } + + return nil +} + +// useAsnSource returns either a local cached version of +// ASN source bytes or download from source +func useAsnSource() ([]byte, error) { + path := localPath() + os.MkdirAll(filepath.Dir(path), os.ModePerm) + + if info, err := os.Stat(path); os.IsNotExist(err) || info.Size() == 0 { + log.Println("downloading ASN metadata...") + if err := downloadAsnSource(); err != nil { + return nil, err + } + log.Println("ASN metadata downloaded") + } + + bytes, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("can't open file to read ASN metadata: %s", err) + } + + return bytes, nil +} + +// parseMetadata parse raw bytes of ASN metadata into readable entries +func parseMetadata(bytes []byte) ([]AsnEntry, error) { + var entries []AsnEntry + + if err := gocsv.UnmarshalBytes(bytes, &entries); err != nil { + return nil, fmt.Errorf("can't parse ASN metadata: %s", err) + } + + return entries, nil +} + +// GetMapping returns a pointer to ASN-metadata mappings +func getMapping() AsnMap { + bytes, err := useAsnSource() + if err != nil { + log.Fatalln("Failed to load ASN metadata: ", err) + } + + entries, err := parseMetadata(bytes) + if err != nil { + log.Fatalln("Failed to parse ASN metadata (Delete data and retry): ", err) + } + + mapping := make(AsnMap) + for _, entry := range entries { + mapping[entry.ASN] = entry + } + + return mapping +} -- cgit v1.2.3