Preliminary config implementation

This commit is contained in:
Kioubit 2021-12-21 06:42:30 -05:00
parent 79f4cbf97d
commit 0729ff66fb
5 changed files with 174 additions and 63 deletions

79
config.go Normal file
View File

@ -0,0 +1,79 @@
package main
import (
"bufio"
"log"
"os"
"strings"
)
type configResponder struct {
Iface string
Filter string
}
type configProxy struct {
Iface1 string
Iface2 string
}
func readConfig(dest string) {
file, err := os.Open(dest)
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "//") {
continue
}
if strings.HasPrefix(line, "debug") {
if strings.Contains(line, "off") {
GlobalDebug = false
}
continue
}
if strings.HasPrefix(line, "responder") {
obj := configResponder{}
for {
scanner.Scan()
line = scanner.Text()
if strings.HasPrefix(line, "iface") {
obj.Iface = strings.TrimSpace(strings.TrimPrefix(line, "iface"))
}
if strings.HasPrefix(line, "filter") {
obj.Filter = strings.TrimSpace(strings.TrimPrefix(line, "filter"))
}
if strings.HasPrefix(line, "}") {
break
}
}
go simpleRespond(obj.Iface, parseFilter(obj.Filter))
}
if strings.HasPrefix(line, "proxy") {
obj := configProxy{}
for {
scanner.Scan()
line = scanner.Text()
if strings.HasPrefix(line, "iface1") {
obj.Iface1 = strings.TrimSpace(strings.TrimPrefix(line, "iface1"))
}
if strings.HasPrefix(line, "iface2") {
obj.Iface2 = strings.TrimSpace(strings.TrimPrefix(line, "iface2"))
}
if strings.HasPrefix(line, "}") {
break
}
}
go proxy(obj.Iface1, obj.Iface2)
}
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}

58
main.go
View File

@ -2,14 +2,12 @@ package main
import (
"fmt"
"net"
"os"
"os/signal"
"syscall"
)
func main() {
fmt.Println("Usage: pndpd respond <interface>")
fmt.Println("Usage: pndpd readconfig <path to file>")
fmt.Println("Usage: pndpd respond <interface> <optional whitelist of CIDRs separated with a semicolon>")
fmt.Println("Usage: pndpd proxy <interface1> <interface2>")
if len(os.Args) <= 1 {
@ -17,56 +15,18 @@ func main() {
os.Exit(1)
}
if os.Args[1] == "respond" {
simpleRespond(os.Args[2])
if len(os.Args) == 4 {
simpleRespond(os.Args[2], parseFilter(os.Args[3]))
} else {
simpleRespond(os.Args[2], nil)
}
}
if os.Args[1] == "proxy" {
proxy(os.Args[2], os.Args[3])
}
if os.Args[1] == "readConfig" {
readConfig(os.Args[2])
}
func simpleRespond(iface string) {
requests := make(chan *NDRequest, 100)
defer close(requests)
_, test, _ := net.ParseCIDR("fd44::/64")
go respond(iface, requests, NDP_ADV, []*net.IPNet{test})
go listen(iface, requests, NDP_SOL)
sigCh := make(chan os.Signal)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
select {
case <-sigCh:
fmt.Println("Exit")
os.Exit(0)
}
}
func proxy(iface1, iface2 string) {
req_iface1_sol_iface2 := make(chan *NDRequest, 100)
defer close(req_iface1_sol_iface2)
go listen(iface1, req_iface1_sol_iface2, NDP_SOL)
go respond(iface2, req_iface1_sol_iface2, NDP_SOL, nil)
req_iface2_sol_iface1 := make(chan *NDRequest, 100)
defer close(req_iface2_sol_iface1)
go listen(iface2, req_iface2_sol_iface1, NDP_SOL)
go respond(iface1, req_iface2_sol_iface1, NDP_SOL, nil)
req_iface1_adv_iface2 := make(chan *NDRequest, 100)
defer close(req_iface1_adv_iface2)
go listen(iface1, req_iface1_adv_iface2, NDP_ADV)
go respond(iface2, req_iface1_adv_iface2, NDP_ADV, nil)
req_iface2_adv_iface1 := make(chan *NDRequest, 100)
defer close(req_iface2_adv_iface1)
go listen(iface2, req_iface2_adv_iface1, NDP_ADV)
go respond(iface1, req_iface2_adv_iface1, NDP_ADV, nil)
sigCh := make(chan os.Signal)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
select {
case <-sigCh:
fmt.Println("Exit")
os.Exit(0)
}
}

70
process.go Normal file
View File

@ -0,0 +1,70 @@
package main
import (
"fmt"
"net"
"os"
"os/signal"
"strings"
"syscall"
)
var GlobalDebug = false
func simpleRespond(iface string, filter []*net.IPNet) {
requests := make(chan *NDRequest, 100)
defer close(requests)
go respond(iface, requests, NDP_ADV, filter)
go listen(iface, requests, NDP_SOL)
sigCh := make(chan os.Signal)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
select {
case <-sigCh:
fmt.Println("Exit")
os.Exit(0)
}
}
func proxy(iface1, iface2 string) {
req_iface1_sol_iface2 := make(chan *NDRequest, 100)
defer close(req_iface1_sol_iface2)
go listen(iface1, req_iface1_sol_iface2, NDP_SOL)
go respond(iface2, req_iface1_sol_iface2, NDP_SOL, nil)
req_iface2_sol_iface1 := make(chan *NDRequest, 100)
defer close(req_iface2_sol_iface1)
go listen(iface2, req_iface2_sol_iface1, NDP_SOL)
go respond(iface1, req_iface2_sol_iface1, NDP_SOL, nil)
req_iface1_adv_iface2 := make(chan *NDRequest, 100)
defer close(req_iface1_adv_iface2)
go listen(iface1, req_iface1_adv_iface2, NDP_ADV)
go respond(iface2, req_iface1_adv_iface2, NDP_ADV, nil)
req_iface2_adv_iface1 := make(chan *NDRequest, 100)
defer close(req_iface2_adv_iface1)
go listen(iface2, req_iface2_adv_iface1, NDP_ADV)
go respond(iface1, req_iface2_adv_iface1, NDP_ADV, nil)
sigCh := make(chan os.Signal)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
select {
case <-sigCh:
fmt.Println("Exit")
os.Exit(0)
}
}
func parseFilter(f string) []*net.IPNet {
s := strings.Split(f, ";")
result := make([]*net.IPNet, len(s))
for i, n := range s {
_, cidr, err := net.ParseCIDR(n)
if err != nil {
panic(err)
}
result[i] = cidr
}
return result
}

View File

@ -119,6 +119,7 @@ func listen(iface string, responder chan *NDRequest, requestType NDPType) {
if err != nil {
panic(err)
}
if GlobalDebug {
fmt.Println("Source IP:")
fmt.Printf("% X\n", buf[:numRead][22:38])
fmt.Println("Destination IP:")
@ -128,6 +129,7 @@ func listen(iface string, responder chan *NDRequest, requestType NDPType) {
fmt.Println("Source MAC")
fmt.Printf("% X\n", buf[:numRead][80:86])
fmt.Println()
}
responder <- &NDRequest{
requestType: requestType,
srcIP: buf[:numRead][22:38],

View File

@ -90,10 +90,10 @@ func pkt(ownIP []byte, dstIP []byte, tgtip []byte, mac []byte, respondType NDPTy
Port: 0,
Addr: t,
}
if GlobalDebug {
fmt.Println("Sending packet of type", respondType, "to")
fmt.Printf("% X\n", t)
fmt.Println(globalFd)
}
err = syscall.Sendto(globalFd, response, 0, &d)
if err != nil {
fmt.Println(err.Error())