func StrTobyte16(s string) [16]byte {
	var r [16]byte
	if len(s) > 16 {
		copy(r[:], s)
	} else {
		copy(r[16-len(s):], s)
	}
	return r
}
StrTobyte16 converts string to 16 bytes
package disc
import (
	"bufio"
	"encoding/csv"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/exec"
	"runtime"
	"strings"
	"syscall"
	"time"
	"golang.org/x/net/icmp"
	"golang.org/x/net/ipv4"
	"golang.org/x/net/ipv6"
	"github.com/olekukonko/tablewriter"
	"github.com/mehrdadrad/mylg/cli"
)
const (
	IEEEOUI = "http://standards.ieee.org/develop/regauth/oui/oui.csv"
)
type ARP struct {
	IP        string
	MAC       string
	Interface string
	Host      string
}
type disc struct {
	Table []ARP
	OUI   map[string]string
	IsBSD bool
	SKey  string
}
func New(args string) *disc {
	key, flag := cli.Flag(args)
	if _, ok := flag["help"]; ok {
		help()
		return nil
	}
	return &disc{
		IsBSD: IsBSD(),
		OUI:   make(map[string]string, 25000),
		SKey:  key,
	}
}
func WalkIP(cidr string) chan string {
	c := make(chan string, 2048)
	go func() {
		defer close(c)
		ip, ipnet, err := net.ParseCIDR(cidr)
		if err != nil {
			println(err.Error())
			return
		}
		for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); nextIP(ip) {
			select {
			case c <- ip.String():
			default:
				break
			}
		}
	}()
	return c
}
func (a *disc) PingLan() {
	var (
		isV6 bool
		b    [16]byte
	)
	ifs, _ := net.Interfaces()
	for _, i := range ifs {
		addrs, _ := i.Addrs()
		if i.Flags != 19 {
			continue
		}
		for _, addr := range addrs {
			if strings.IndexAny(addr.String(), "::") != -1 {
				isV6 = true
			} else {
				fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
				if err != nil {
					println(err.Error())
					return
				}
				syscall.SetsockoptInt(fd, 0x0, syscall.IP_TTL, 1)
				for ipStr := range WalkIP(addr.String()) {
					copy(b[:], net.ParseIP(ipStr).To4())
					addr := syscall.SockaddrInet4{
						Port: 33434,
						Addr: [4]byte{b[0], b[1], b[2], b[3]},
					}
					m, _ := (&icmp.Message{
						Type: ipv4.ICMPTypeEcho, Code: 0,
						Body: &icmp.Echo{
							ID: 2016, Seq: 1,
							Data: make([]byte, 52-28),
						},
					}).Marshal(nil)
					if err := syscall.Sendto(fd, m, 0, &addr); err != nil {
						if b[3] != 0 && b[3] != 255 {
							println(err.Error())
						}
					}
				}
				syscall.Close(fd)
			}
		}
		if isV6 {
			fd, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_RAW, syscall.IPPROTO_ICMPV6)
			if err != nil {
				println(err.Error())
				return
			}
			syscall.SetsockoptInt(fd, syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, 1)
			copy(b[:], net.ParseIP(fmt.Sprintf("ff02::1")).To16())
			addr := syscall.SockaddrInet6{
				Port:   33434,
				ZoneId: uint32(i.Index),
				Addr:   b,
			}
			m, _ := (&icmp.Message{
				Type: ipv6.ICMPTypeEchoRequest, Code: 0,
				Body: &icmp.Echo{
					ID: 2016, Seq: 1,
					Data: make([]byte, 52-48),
				},
			}).Marshal(nil)
			if err := syscall.Sendto(fd, m, 0, &addr); err != nil {
				println(err.Error())
			}
			isV6 = false
			syscall.Close(fd)
		}
	}
}
func nextIP(ip net.IP) {
	for j := len(ip) - 1; j >= 0; j-- {
		ip[j]++
		if ip[j] > 0 {
			break
		}
	}
}