170 lines
5.2 KiB
Go
170 lines
5.2 KiB
Go
|
|
package wlan
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"encoding/json"
|
|||
|
|
"fmt"
|
|||
|
|
"net"
|
|||
|
|
"net/http"
|
|||
|
|
"os/exec"
|
|||
|
|
"regexp"
|
|||
|
|
"strings"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
type ApiResponse struct {
|
|||
|
|
Status string `json:"status"`
|
|||
|
|
Error string `json:"error,omitempty"`
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type NetworkInfo struct {
|
|||
|
|
IP string `json:"ip"`
|
|||
|
|
Netmask string `json:"netmask"`
|
|||
|
|
Gateway string `json:"gateway"`
|
|||
|
|
MAC string `json:"mac"`
|
|||
|
|
Connected bool `json:"connected"`
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Подключение к Wi-Fi
|
|||
|
|
func ConnectWiFi(w http.ResponseWriter, r *http.Request) {
|
|||
|
|
ssid := r.FormValue("ssid")
|
|||
|
|
password := r.FormValue("password")
|
|||
|
|
|
|||
|
|
cmd := exec.Command("nmcli", "dev", "wifi", "connect", ssid, "password", password)
|
|||
|
|
err := cmd.Run()
|
|||
|
|
if err != nil {
|
|||
|
|
http.Error(w, "Ошибка подключения", http.StatusInternalServerError)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
json.NewEncoder(w).Encode(ApiResponse{Status: "OK"})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Отключение Wi-Fi
|
|||
|
|
func DisconnectWiFi(w http.ResponseWriter, r *http.Request) {
|
|||
|
|
cmd := exec.Command("nmcli", "dev", "disconnect", "wlan0")
|
|||
|
|
err := cmd.Run()
|
|||
|
|
if err != nil {
|
|||
|
|
http.Error(w, "Ошибка отключения", http.StatusInternalServerError)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
json.NewEncoder(w).Encode(ApiResponse{Status: "OK"})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Включение точки доступа
|
|||
|
|
func EnableHotspot(w http.ResponseWriter, r *http.Request) {
|
|||
|
|
ssid := r.FormValue("ssid")
|
|||
|
|
password := r.FormValue("password")
|
|||
|
|
|
|||
|
|
cmd := exec.Command("nmcli", "dev", "wifi", "hotspot", "ifname", "wlan0", "ssid", ssid, "password", password)
|
|||
|
|
err := cmd.Run()
|
|||
|
|
if err != nil {
|
|||
|
|
http.Error(w, "Ошибка включения точки доступа", http.StatusInternalServerError)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
json.NewEncoder(w).Encode(ApiResponse{Status: "OK"})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Отключение точки доступа
|
|||
|
|
func DisableHotspot(w http.ResponseWriter, r *http.Request) {
|
|||
|
|
cmd := exec.Command("nmcli", "con", "delete", "Wi-Fi Hotspot")
|
|||
|
|
err := cmd.Run()
|
|||
|
|
if err != nil {
|
|||
|
|
http.Error(w, "Ошибка отключения точки доступа", http.StatusInternalServerError)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
json.NewEncoder(w).Encode(ApiResponse{Status: "OK"})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Установка статического IP
|
|||
|
|
func SetStaticIP(w http.ResponseWriter, r *http.Request) {
|
|||
|
|
ip := r.FormValue("ip")
|
|||
|
|
gateway := r.FormValue("gateway")
|
|||
|
|
dns := r.FormValue("dns")
|
|||
|
|
|
|||
|
|
cmd := exec.Command("sh", "-c", fmt.Sprintf(
|
|||
|
|
"nmcli con modify wlan0 ipv4.method manual ipv4.addresses %s ipv4.gateway %s ipv4.dns %s && nmcli con up wlan0",
|
|||
|
|
ip, gateway, dns,
|
|||
|
|
))
|
|||
|
|
err := cmd.Run()
|
|||
|
|
if err != nil {
|
|||
|
|
http.Error(w, "Ошибка установки статического IP", http.StatusInternalServerError)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
json.NewEncoder(w).Encode(ApiResponse{Status: "OK"})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Включение DHCP
|
|||
|
|
func EnableDHCP(w http.ResponseWriter, r *http.Request) {
|
|||
|
|
cmd := exec.Command("nmcli", "con", "modify", "wlan0", "ipv4.method", "auto")
|
|||
|
|
err := cmd.Run()
|
|||
|
|
if err != nil {
|
|||
|
|
http.Error(w, "Ошибка включения DHCP", http.StatusInternalServerError)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
json.NewEncoder(w).Encode(ApiResponse{Status: "OK"})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Получение списка сетей
|
|||
|
|
func ListNetworks(w http.ResponseWriter, r *http.Request) {
|
|||
|
|
w.Header().Set("Content-Type", "application/json")
|
|||
|
|
cmd := exec.Command("nmcli", "--fields", "SSID,SECURITY,SIGNAL,BARS", "-t", "-f", "SSID,SECURITY,SIGNAL,BARS", "dev", "wifi", "list")
|
|||
|
|
out, err := cmd.Output()
|
|||
|
|
if err != nil {
|
|||
|
|
http.Error(w, "Ошибка получения списка сетей", http.StatusInternalServerError)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
networks := parseNetworks(string(out))
|
|||
|
|
json.NewEncoder(w).Encode(networks)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func parseNetworks(output string) []map[string]string {
|
|||
|
|
lines := strings.Split(output, "\n")[1:]
|
|||
|
|
networks := make([]map[string]string, 0)
|
|||
|
|
for _, line := range lines {
|
|||
|
|
if line == "" {
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
fields := strings.Split(line, ":")
|
|||
|
|
network := make(map[string]string)
|
|||
|
|
network["ssid"] = fields[0]
|
|||
|
|
network["security"] = fields[1]
|
|||
|
|
network["signal"] = fields[2]
|
|||
|
|
network["bars"] = fields[3]
|
|||
|
|
networks = append(networks, network)
|
|||
|
|
}
|
|||
|
|
return networks
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Информация о текущем соединении
|
|||
|
|
func GetNetworkInfo(w http.ResponseWriter, r *http.Request) {
|
|||
|
|
info := NetworkInfo{Connected: false}
|
|||
|
|
|
|||
|
|
// MAC
|
|||
|
|
outMac, _ := exec.Command("ip", "link", "show", "wlan0").Output()
|
|||
|
|
macRegex := regexp.MustCompile(`link/ether ([0-9a-f:]+)`)
|
|||
|
|
if match := macRegex.FindStringSubmatch(string(outMac)); len(match) > 1 {
|
|||
|
|
info.MAC = match[1]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// IP и маска
|
|||
|
|
outIP, _ := exec.Command("ip", "-4", "addr", "show", "wlan0").Output()
|
|||
|
|
ipRegex := regexp.MustCompile(`inet ([0-9.]+)/[0-9]+`)
|
|||
|
|
if matchIP := ipRegex.FindStringSubmatch(string(outIP)); len(matchIP) > 1 {
|
|||
|
|
info.IP = matchIP[1]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
netmaskRegex := regexp.MustCompile(`inet [0-9.]+/[0-9]+`)
|
|||
|
|
if matchNetmask := netmaskRegex.FindStringSubmatch(string(outIP)); len(matchNetmask) > 0 {
|
|||
|
|
_, ipNet, _ := net.ParseCIDR(matchNetmask[0])
|
|||
|
|
info.Netmask = ipNet.Mask.String()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Шлюз
|
|||
|
|
outGateway, _ := exec.Command("ip", "route", "show", "default").Output()
|
|||
|
|
gatewayRegex := regexp.MustCompile(`default via ([0-9.]+)`)
|
|||
|
|
if matchGateway := gatewayRegex.FindStringSubmatch(string(outGateway)); len(matchGateway) > 1 {
|
|||
|
|
info.Gateway = matchGateway[1]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
info.Connected = info.IP != "" && info.Gateway != ""
|
|||
|
|
json.NewEncoder(w).Encode(info)
|
|||
|
|
}
|