diff --git a/config.go b/config.go new file mode 100644 index 0000000..846b747 --- /dev/null +++ b/config.go @@ -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) + } +} diff --git a/main.go b/main.go index 7565d3a..9fd6811 100644 --- a/main.go +++ b/main.go @@ -2,14 +2,12 @@ package main import ( "fmt" - "net" "os" - "os/signal" - "syscall" ) func main() { - fmt.Println("Usage: pndpd respond ") + fmt.Println("Usage: pndpd readconfig ") + fmt.Println("Usage: pndpd respond ") fmt.Println("Usage: pndpd proxy ") 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]) } -} - -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) + if os.Args[1] == "readConfig" { + readConfig(os.Args[2]) } + } diff --git a/process.go b/process.go new file mode 100644 index 0000000..0ab9a87 --- /dev/null +++ b/process.go @@ -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 +} diff --git a/rawsocket.go b/rawsocket.go index a6e17c7..dd8e824 100644 --- a/rawsocket.go +++ b/rawsocket.go @@ -119,15 +119,17 @@ func listen(iface string, responder chan *NDRequest, requestType NDPType) { if err != nil { panic(err) } - fmt.Println("Source IP:") - fmt.Printf("% X\n", buf[:numRead][22:38]) - fmt.Println("Destination IP:") - fmt.Printf("% X\n", buf[:numRead][38:54]) - fmt.Println("Requested IP:") - fmt.Printf("% X\n", buf[:numRead][62:78]) - fmt.Println("Source MAC") - fmt.Printf("% X\n", buf[:numRead][80:86]) - fmt.Println() + if GlobalDebug { + fmt.Println("Source IP:") + fmt.Printf("% X\n", buf[:numRead][22:38]) + fmt.Println("Destination IP:") + fmt.Printf("% X\n", buf[:numRead][38:54]) + fmt.Println("Requested IP:") + fmt.Printf("% X\n", buf[:numRead][62:78]) + fmt.Println("Source MAC") + fmt.Printf("% X\n", buf[:numRead][80:86]) + fmt.Println() + } responder <- &NDRequest{ requestType: requestType, srcIP: buf[:numRead][22:38], diff --git a/responder.go b/responder.go index 2efcb55..b4b844b 100644 --- a/responder.go +++ b/responder.go @@ -90,10 +90,10 @@ func pkt(ownIP []byte, dstIP []byte, tgtip []byte, mac []byte, respondType NDPTy Port: 0, Addr: t, } - fmt.Println("Sending packet of type", respondType, "to") - fmt.Printf("% X\n", t) - - fmt.Println(globalFd) + if GlobalDebug { + fmt.Println("Sending packet of type", respondType, "to") + fmt.Printf("% X\n", t) + } err = syscall.Sendto(globalFd, response, 0, &d) if err != nil { fmt.Println(err.Error())