diff --git a/luci-app-zzz/Makefile b/luci-app-zzz/Makefile
new file mode 100644
index 0000000..da7a36e
--- /dev/null
+++ b/luci-app-zzz/Makefile
@@ -0,0 +1,8 @@
+include $(TOPDIR)/rules.mk
+
+LUCI_TITLE:=LuCI support for NYN 802.1x Authentication Client
+LUCI_DEPENDS:=+zzz +luci-base
+
+include $(TOPDIR)/feeds/luci/luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/luci-app-zzz/luasrc/controller/zzz.lua b/luci-app-zzz/luasrc/controller/zzz.lua
new file mode 100644
index 0000000..789d721
--- /dev/null
+++ b/luci-app-zzz/luasrc/controller/zzz.lua
@@ -0,0 +1,73 @@
+-- /usr/lib/lua/luci/controller/zzz.lua
+module("luci.controller.zzz", package.seeall)
+
+function index()
+ if not nixio.fs.access("/etc/config/zzz") then
+ return
+ end
+
+ -- Menu
+ entry({"admin", "network", "zzz"}, cbi("zzz"), "ZZZ", 60).dependent = false
+
+ -- Settings
+ entry({"admin", "network", "zzz", "service_control"}, call("service_control")).leaf = true
+
+ -- Status API
+ entry({"admin", "network", "zzz", "get_status"}, call("act_status")).leaf = true
+end
+
+function service_control()
+ local sys = require "luci.sys"
+ local action = luci.http.formvalue("action")
+ local result = { success = false, message = "" }
+
+ if action then
+ local cmd = ""
+ if action == "start" then
+ cmd = "/etc/rc.d/S99zzz start"
+ elseif action == "stop" then
+ cmd = "/etc/rc.d/S99zzz stop"
+ elseif action == "restart" then
+ cmd = "/etc/rc.d/S99zzz stop && sleep 2 && /etc/rc.d/S99zzz start"
+ end
+
+ if cmd ~= "" then
+ local ret = sys.call(cmd)
+ if ret == 0 then
+ result.success = true
+ result.message = action .. " 成功"
+ else
+ result.success = false
+ result.message = action .. " 失败"
+ end
+ end
+ end
+
+ luci.http.prepare_content("application/json")
+ luci.http.write_json(result)
+end
+
+function act_status()
+ local sys = require "luci.sys"
+ local util = require "luci.util"
+ local status = {}
+
+ -- Get status
+ status.running = (sys.call("pgrep -f zzz >/dev/null") == 0)
+
+ -- Get process info
+ if status.running then
+ status.process_info = util.trim(sys.exec("ps | grep -v grep | grep zzz"))
+ end
+
+ -- Get log
+ local log_file = "/tmp/zzz.log"
+ if nixio.fs.access(log_file) then
+ status.log = util.trim(sys.exec("tail -20 " .. log_file))
+ else
+ status.log = util.trim(sys.exec("logread | grep zzz | tail -10"))
+ end
+
+ luci.http.prepare_content("application/json")
+ luci.http.write_json(status)
+end
diff --git a/luci-app-zzz/luasrc/model/cbi/zzz.lua b/luci-app-zzz/luasrc/model/cbi/zzz.lua
new file mode 100644
index 0000000..c6a3e03
--- /dev/null
+++ b/luci-app-zzz/luasrc/model/cbi/zzz.lua
@@ -0,0 +1,117 @@
+-- /usr/lib/lua/luci/model/cbi/zzz.lua
+local m, s, o
+local sys = require "luci.sys"
+
+-- control
+local start_action = luci.http.formvalue("cbid.zzz.auth.start_service")
+local stop_action = luci.http.formvalue("cbid.zzz.auth.stop_service")
+local restart_action = luci.http.formvalue("cbid.zzz.auth.restart_service")
+
+if start_action then
+ sys.call("/etc/rc.d/S99zzz start")
+elseif stop_action then
+ sys.call("/etc/rc.d/S99zzz stop")
+elseif restart_action then
+ sys.call("/etc/rc.d/S99zzz stop; sleep 2; /etc/rc.d/S99zzz start")
+end
+
+m = Map("zzz", "zzz 802.1x 认证客户端",
+ "配置使用 zzz 客户端进行网络访问的 802.1x 认证")
+
+-- Authentication Settings
+s = m:section(TypedSection, "auth", "认证设置")
+s.anonymous = true
+s.addremove = false
+
+-- Service Status
+o = s:option(DummyValue, "_status", "当前状态")
+o.rawhtml = true
+o.cfgvalue = function()
+ local sys = require "luci.sys"
+ local running = sys.call("pgrep zzz >/dev/null") == 0
+ if running then
+ return "✔ 正在运行中"
+ else
+ return "✘ 未运行"
+ end
+end
+
+-- control buttons
+control_buttons = s:option(DummyValue, "_control", "服务控制")
+control_buttons.rawhtml = true
+control_buttons.cfgvalue = function()
+ return [[
+
+
+
+
+
+ ]]
+end
+
+-- Username
+o = s:option(Value, "user", "用户名", "802.1x 认证用户名")
+o.password = true
+o.rmempty = false
+
+-- Password
+o = s:option(Value, "password", "密码", "802.1x 认证密码")
+o.password = true
+o.rmempty = false
+
+-- Network Device
+o = s:option(ListValue, "device", "网络接口", "用于认证的网络接口")
+o.rmempty = false
+o:value("eth0", "eth0")
+o:value("eth1", "eth1")
+o:value("wan", "WAN")
+
+-- Add network interface
+local interfaces = sys.net.devices()
+for _, iface in ipairs(interfaces) do
+ if iface ~= "lo" then
+ o:value(iface, iface)
+ end
+end
+
+-- Auto start
+auto_start = s:option(Flag, "auto_start", "启用定时启动")
+auto_start.description = "启用后将在每周一至周五的 7:00 自动启动服务"
+auto_start.rmempty = false
+
+-- Get Status
+auto_start.cfgvalue = function(self, section)
+ local has_cron = sys.call("crontab -l 2>/dev/null | grep 'S99zzz' >/dev/null") == 0
+ return has_cron and "1" or "0"
+end
+
+-- Crontab
+auto_start.write = function(self, section, value)
+ if value == "1" then
+ -- 启用定时任务:每周一至周五 7:00 启动
+ sys.call("(crontab -l 2>/dev/null | grep -v 'S99zzz' | grep -v '# zzz auto') | crontab - 2>/dev/null")
+ sys.call("(crontab -l 2>/dev/null; echo '0 7 * * 1,2,3,4,5 /etc/rc.d/S99zzz start # zzz auto start') | crontab -")
+ sys.call("/etc/init.d/cron enable && /etc/init.d/cron restart")
+ else
+ -- 禁用定时任务
+ sys.call("(crontab -l 2>/dev/null | grep -v 'S99zzz' | grep -v '# zzz auto') | crontab - 2>/dev/null")
+ sys.call("/etc/init.d/cron restart")
+ end
+end
+
+-- Crontab Status
+timer_status_display = s:option(DummyValue, "_timer_status_display", "定时任务状态")
+timer_status_display.rawhtml = true
+timer_status_display.cfgvalue = function()
+ local cron_output = sys.exec("crontab -l 2>/dev/null | grep 'S99zzz' || echo '未设置'")
+ if cron_output:match("S99zzz") then
+ return "✔ 已启用 (每周一至周五 7:00 自动启动)"
+ else
+ return "✘ 未启用"
+ end
+end
+
+return m
diff --git a/zzz/Makefile b/zzz/Makefile
new file mode 100644
index 0000000..5e63a80
--- /dev/null
+++ b/zzz/Makefile
@@ -0,0 +1,64 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=zzz
+PKG_VERSION:=0.1.1
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=Dichgrem
+PKG_LICENSE:=MIT
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/zzz
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=ZZZ 802.1x Authentication Client
+ URL:=https://github.com/diredocks/zzz
+ DEPENDS:=
+endef
+
+define Package/zzz/description
+ A 802.1x authentication client for OpenWrt routers.
+ Cross-compiled C version for optimal performance and compatibility.
+endef
+
+define Package/zzz/conffiles
+/etc/config/zzz
+/etc/zzz/config.ini
+endef
+
+define Build/Prepare
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/zzz/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_DIR) $(1)/etc/zzz
+
+ # Install precompiled binary based on architecture
+ $(if $(CONFIG_TARGET_x86_64),$(INSTALL_BIN) ./files/bin/zzz-x86-linux-gnu $(1)/usr/bin/zzz)
+ $(if $(CONFIG_TARGET_armvirt_64),$(INSTALL_BIN) ./files/bin/zzz-aarch64-linux-gnu $(1)/usr/bin/zzz)
+ $(if $(CONFIG_TARGET_bcm27xx_bcm2711),$(INSTALL_BIN) ./files/bin/zzz-aarch64-linux-gnu $(1)/usr/bin/zzz)
+ $(if $(CONFIG_TARGET_ath79_generic),$(INSTALL_BIN) ./files/bin/zzz-mipsel-linux-musleabi $(1)/usr/bin/zzz)
+ $(if $(CONFIG_TARGET_ramips_mt7621),$(INSTALL_BIN) ./files/bin/zzz-mipsel-linux-musleabi $(1)/usr/bin/zzz)
+ $(if $(CONFIG_TARGET_mediatek_mt7622),$(INSTALL_BIN) ./files/bin/zzz-aarch64-linux-gnu $(1)/usr/bin/zzz)
+ $(if $(CONFIG_TARGET_rockchip_armv8),$(INSTALL_BIN) ./files/bin/zzz-aarch64-linux-gnu $(1)/usr/bin/zzz)
+ # Fallback - try to detect architecture
+ $(if $(findstring aarch64,$(ARCH)),$(INSTALL_BIN) ./files/bin/zzz-aarch64-linux-gnu $(1)/usr/bin/zzz)
+ $(if $(findstring mips,$(ARCH)),$(INSTALL_BIN) ./files/bin/zzz-mipsel-linux-musleabi $(1)/usr/bin/zzz)
+ $(if $(findstring x86,$(ARCH)),$(INSTALL_BIN) ./files/bin/zzz-x86-linux-gnu $(1)/usr/bin/zzz)
+
+ $(INSTALL_BIN) ./files/usr/bin/zzz-device-info $(1)/usr/bin/
+ $(INSTALL_CONF) ./files/etc/config/zzz $(1)/etc/config/
+ $(INSTALL_CONF) ./files/etc/zzz/config.ini $(1)/etc/zzz/
+ $(INSTALL_BIN) ./files/etc/init.d/zzz $(1)/etc/init.d/
+endef
+
+$(eval $(call BuildPackage,zzz))
diff --git a/zzz/files/bin/zzz-aarch64-linux-gnu b/zzz/files/bin/zzz-aarch64-linux-gnu
new file mode 100644
index 0000000..54a758a
Binary files /dev/null and b/zzz/files/bin/zzz-aarch64-linux-gnu differ
diff --git a/zzz/files/bin/zzz-mipsel-linux-musleabi b/zzz/files/bin/zzz-mipsel-linux-musleabi
new file mode 100644
index 0000000..0485644
Binary files /dev/null and b/zzz/files/bin/zzz-mipsel-linux-musleabi differ
diff --git a/zzz/files/bin/zzz-x86-linux-gnu b/zzz/files/bin/zzz-x86-linux-gnu
new file mode 100644
index 0000000..55ce48e
Binary files /dev/null and b/zzz/files/bin/zzz-x86-linux-gnu differ
diff --git a/zzz/files/etc/config/zzz b/zzz/files/etc/config/zzz
new file mode 100644
index 0000000..2e796d9
--- /dev/null
+++ b/zzz/files/etc/config/zzz
@@ -0,0 +1,7 @@
+config general 'general'
+ option enabled '0'
+
+config auth 'auth'
+ option username ''
+ option password ''
+ option device 'eth0'
diff --git a/zzz/files/etc/init.d/zzz b/zzz/files/etc/init.d/zzz
new file mode 100644
index 0000000..6a7fff9
--- /dev/null
+++ b/zzz/files/etc/init.d/zzz
@@ -0,0 +1,54 @@
+#!/bin/sh /etc/rc.common
+
+START=99
+USE_PROCD=1
+
+CONFIG=/etc/zzz/config.ini
+
+start_service() {
+ # 检查是否启用
+ local enabled=$(uci -q get zzz.general.enabled)
+ [ "$enabled" = "1" ] || {
+ echo "zzz is disabled"
+ return 1
+ }
+
+ generate_config
+
+ procd_open_instance
+ procd_set_param command /usr/bin/zzz "$CONFIG"
+ procd_set_param respawn
+ procd_close_instance
+}
+
+stop_service() {
+ procd_kill zzz
+}
+
+generate_config() {
+ mkdir -p /etc/zzz
+
+ # 获取UCI配置
+ local username=$(uci -q get zzz.auth.username)
+ local password=$(uci -q get zzz.auth.password)
+ local device=$(uci -q get zzz.auth.device)
+
+ # 检查必要参数
+ [ -z "$username" ] && {
+ logger -t zzz "Error: username not configured"
+ return 1
+ }
+
+ [ -z "$password" ] && {
+ logger -t zzz "Error: password not configured"
+ return 1
+ }
+
+ # 生成INI配置文件
+ cat >"$CONFIG" </dev/null 2>&1; then
+ zzz -mode info 2>/dev/null | grep -E "(Found|device|hardware_description)" | while read line; do
+ echo "$line"
+ done
+else
+ echo "zzz binary not found. Showing available network interfaces:"
+ for dev in /sys/class/net/*; do
+ if [ -d "$dev" ]; then
+ iface=$(basename "$dev")
+ if [ "$iface" != "lo" ]; then
+ echo "Device: $iface"
+ if [ -f "$dev/address" ]; then
+ echo " MAC: $(cat "$dev/address")"
+ fi
+ if [ -f "$dev/operstate" ]; then
+ echo " State: $(cat "$dev/operstate")"
+ fi
+ echo ""
+ fi
+ fi
+ done
+fi