main.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package main
  2. import (
  3. "bufio"
  4. "encoding/hex"
  5. "fmt"
  6. "log"
  7. "net"
  8. "os"
  9. "os/exec"
  10. "strings"
  11. "time"
  12. "github.com/songgao/packets/ethernet"
  13. "github.com/songgao/water"
  14. )
  15. //declare IP and subnet mask here
  16. var (
  17. self = net.ParseIP(os.Args[2])
  18. mask = net.IPv4Mask(255, 255, 255, 0)
  19. )
  20. //declare new interface here
  21. var ifce, _ = water.New(water.Config{
  22. DeviceType: water.TAP,
  23. })
  24. var RCV_B = 0 //recived in byte
  25. var TXT_B = 0 //sent in byte
  26. var RCV_T = 0 //number of packet recived
  27. var TXT_T = 0 //number of packet sended
  28. func main() {
  29. //for stat only
  30. go func() {
  31. for {
  32. //showing statistics here, every 5 seconds
  33. log.Println("Total recived: ", ByteCountSI(RCV_B), ", Total transmited: ", ByteCountSI(TXT_B))
  34. log.Println("Total recived: ", RCV_T, ", Total transmited: ", TXT_T)
  35. time.Sleep(5 * time.Second)
  36. }
  37. }()
  38. //create socket server
  39. go func() {
  40. fmt.Println("Launching server...") //show debug message
  41. // listen on all interfaces
  42. ln, _ := net.Listen("tcp", ":8081") //create new interface
  43. // accept connection on port
  44. conn, _ := ln.Accept() //accept connections
  45. // run loop forever (or until ctrl-c)
  46. for {
  47. // will listen for message to process ending in newline (\n)
  48. message, _ := bufio.NewReader(conn).ReadString('\n')
  49. // output message received
  50. //fmt.Print("RECV<<", string(message))
  51. RCV_B += len(string(message)) //for statistics
  52. RCV_T++ //for statistics
  53. data, err := hex.DecodeString(strings.ReplaceAll("\n", "", string(message))) //since data had \n, so replace it and convert to hex array
  54. if err != nil {
  55. //log.Println(err)
  56. }
  57. //log.Println("RECV<<", data)
  58. ifce.Write(data) //write to interface
  59. }
  60. }()
  61. //declare server
  62. // connect to server
  63. conns, _ := net.Dial("tcp", os.Args[1]+":8081")
  64. var frame ethernet.Frame //declare frame
  65. setupIfce(net.IPNet{IP: self, Mask: mask}, ifce.Name()) //setup interface info
  66. for {
  67. frame.Resize(1500) //MTU = 1500
  68. n, err := ifce.Read([]byte(frame)) //read from ifce
  69. if err != nil {
  70. log.Fatal(err)
  71. }
  72. frame = frame[:n] //fconvert frame to usabele array
  73. //log.Println("TRSV>>", hex.EncodeToString(frame))
  74. TXT_B += len(hex.EncodeToString(frame)) //for statistics
  75. TXT_T++ //for statistics
  76. /*
  77. log.Printf("Dst: %s\n", frame.Destination())
  78. log.Printf("Src: %s\n", frame.Source())
  79. log.Printf("Ethertype: % x\n", frame.Ethertype())
  80. log.Printf("Payload: % x\n", frame.Payload())
  81. log.Printf("HEX: % x\n", frame)
  82. */
  83. fmt.Fprintf(conns, hex.EncodeToString(frame)+"\n") //send to server
  84. /*
  85. a := hex.EncodeToString(frame)
  86. resp, err := http.Get("http://" + os.Args[1] + "/rcv?packet=" + a)
  87. if err != nil {
  88. fmt.Println(err)
  89. } else {
  90. defer resp.Body.Close()
  91. }
  92. */
  93. }
  94. }
  95. func setupIfce(ipNet net.IPNet, dev string) {
  96. sargs := fmt.Sprintf("interface ip set address name=REPLACE_ME source=static addr=REPLACE_ME mask=REPLACE_ME gateway=none")
  97. args := strings.Split(sargs, " ")
  98. args[4] = fmt.Sprintf("name=%s", dev)
  99. args[6] = fmt.Sprintf("addr=%s", ipNet.IP)
  100. args[7] = fmt.Sprintf("mask=%d.%d.%d.%d", ipNet.Mask[0], ipNet.Mask[1], ipNet.Mask[2], ipNet.Mask[3])
  101. cmd := exec.Command("netsh", args...)
  102. if err := cmd.Run(); err != nil {
  103. log.Println(err)
  104. }
  105. }
  106. //https://yourbasic.org/golang/formatting-byte-size-to-human-readable-format/
  107. func ByteCountSI(b int) string {
  108. const unit = 1000
  109. if b < unit {
  110. return fmt.Sprintf("%d B", b)
  111. }
  112. div, exp := int(unit), 0
  113. for n := b / unit; n >= unit; n /= unit {
  114. div *= unit
  115. exp++
  116. }
  117. return fmt.Sprintf("%.1f %cB",
  118. float64(b)/float64(div), "kMGTPE"[exp])
  119. }