Skip to content

Commit

Permalink
🏷️ Version 1.0.0
Browse files Browse the repository at this point in the history
**Added**:
* `Search` will return the manufacturer of the given MAC address.
  • Loading branch information
kkrypt0nn committed Jan 12, 2023
0 parents commit 1e11ccc
Show file tree
Hide file tree
Showing 8 changed files with 48,712 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/go-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Go Test

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.19

- name: Build
run: go build -v ./...

- name: Test
run: go test -v ./...
674 changes: 674 additions & 0 deletions LICENSE.md

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# gomanuf

[![Go Reference](https://pkg.go.dev/badge/github.com/kkrypt0nn/gomanuf.svg)](https://pkg.go.dev/github.com/kkrypt0nn/gomanuf) ![Repository License](https://img.shields.io/github/license/kkrypt0nn/gomanuf?style=flat-square) ![Code Size](https://img.shields.io/github/languages/code-size/kkrypt0nn/gomanuf?style=flat-square) ![Last Commit](https://img.shields.io/github/last-commit/kkrypt0nn/gomanuf?style=flat-square)

`gomanuf` is a very simple library used for [Project Absence](https://github.com/ProjectAbsence) to get the manufacturer of a specific MAC address.

## Installation
If you want to use this library for one of your projects, you can install it like any other Go library

```shell
go get github.com/kkrypt0nn/gomanuf
```

## Example
```go
package main

import (
"fmt"
"github.com/kkrypt0nn/gomanuf"
)

func main() {
manuf, _ := gomanuf.Search("C4:A8:1D:73:D7:8C")
fmt.Println(manuf)
}

```

## License
This library was made with 💜 by Krypton and is under the [GPL v3](LICENSE.md) license.
11 changes: 11 additions & 0 deletions example/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import (
"fmt"
"github.com/kkrypt0nn/gomanuf"
)

func main() {
manuf, _ := gomanuf.Search("C4:A8:1D:73:D7:8C")
fmt.Println(manuf)
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/kkrypt0nn/gomanuf

go 1.19
93 changes: 93 additions & 0 deletions gomanuf.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package gomanuf

import (
"fmt"
"os"
"regexp"
"strings"
)

var data map[string]string
var slash28 map[string]string
var slash36 map[string]string

var macRegex, _ = regexp.Compile("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$")

func init() {
data = make(map[string]string)
slash28 = make(map[string]string)
slash36 = make(map[string]string)
file, err := os.ReadFile("manuf.txt")
if err != nil {
panic(err)
}
lines := strings.Split(string(file), "\n")
for i := 0; i < len(lines); i++ {
line := lines[i]
fields := strings.Split(line, "\t")

// Ignore the comments and empty lines
if strings.HasPrefix(fields[0], "#") || line == "" {
continue
}

mac := fields[0]
manuf := fields[1]
if len(fields) > 2 {
manuf = fields[2]
}
if strings.Contains(mac, ":00/28") {
slash28[mac] = manuf
} else if strings.Contains(mac, ":00/36") {
slash36[mac] = manuf
}

data[mac] = manuf
}
}

func checkSlash28(mac string) string {
mac = mac[:10] + "0:00:00/28"
for address, manuf := range slash28 {
if address == mac {
return manuf
}
}
return ""
}

func checkSlash36(mac string) string {
mac = mac[:13] + "0:00/36"
for address, manuf := range slash36 {
if address == mac {
return manuf
}
}
return ""
}

// Search will return the manufacturer of the given MAC address.
func Search(mac string) (string, error) {
mac = strings.Replace(strings.ToUpper(mac), "-", ":", -1)
if !macRegex.MatchString(mac) {
return "Invalid MAC address", fmt.Errorf("invalid MAC address")
}
for address, manuf := range data {
if strings.HasPrefix(mac, address) {
// Check if manufacturer is one of those manufacturer that have MACs with /28 or /36
if manuf == "IEEE Registration Authority" {
check28 := checkSlash28(mac)
if check28 != "" {
return check28, nil
}
check36 := checkSlash36(mac)
if check36 != "" {
return check36, nil
}
}

return manuf, nil
}
}
return "unknown", nil
}
66 changes: 66 additions & 0 deletions gomanuf_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package gomanuf

import "testing"

func TestDLink(t *testing.T) {
manuf, _ := Search("C4:A8:1D:73:D7:8C")
if manuf == "D-Link International" {
t.Log("D-Link International MAC address found.")
return
}
t.Errorf("Found %s instead of D-Link International!", manuf)
}

func TestNetgear(t *testing.T) {
manuf, _ := Search("9C:D3:6D:9A:CA:81")
if manuf == "Netgear" {
t.Log("Netgear MAC address found.")
return
}
t.Errorf("Found %s instead of Netgear!", manuf)
}

func TestShanghaiBroadwanCommunications(t *testing.T) {
manuf, _ := Search("40:ED:98:6F:DB:AC")
if manuf == "Shanghai Broadwan Communications Co.,Ltd" {
t.Log("Shanghai Broadwan Communications Co.,Ltd MAC address found.")
return
}
t.Errorf("Found %s instead of Shanghai Broadwan Communications Co.,Ltd!", manuf)
}

func TestPiranhaEMS(t *testing.T) {
manuf, _ := Search("70:B3:D5:8C:CD:BE")
if manuf == "Piranha EMS Inc." {
t.Log("Piranha EMS Inc. MAC address found.")
return
}
t.Errorf("Found %s instead of Piranha EMS Inc.!", manuf)
}

func TestIEEERegistrationAuthority(t *testing.T) {
manuf, _ := Search("3C:24:F0:F0:BE:CF")
if manuf == "IEEE Registration Authority" {
t.Log("IEEE Registration Authority MAC address found.")
return
}
t.Errorf("Found %s instead of IEEE Registration Authority!", manuf)
}

func TestSamsungElectronics(t *testing.T) {
manuf, _ := Search("24:FC:E5:AD:BB:89")
if manuf == "Samsung Electronics Co.,Ltd" {
t.Log("Samsung Electronics Co.,Ltd MAC address found.")
return
}
t.Errorf("Found %s instead of Samsung Electronics Co.,Ltd!", manuf)
}

func TestInvalidAddress(t *testing.T) {
manuf, _ := Search("G4:FC:E5:AD:BB:89")
if manuf == "Invalid MAC address" {
t.Log("Invalid MAC address MAC address found.")
return
}
t.Errorf("Found %s instead of Invalid MAC address!", manuf)
}
Loading

0 comments on commit 1e11ccc

Please sign in to comment.