diff --git a/README.en.md b/README.en.md
index 676ade9..9bc29e9 100644
--- a/README.en.md
+++ b/README.en.md
@@ -30,6 +30,7 @@ Demo URL: [https://iplist.opencck.org](https://iplist.opencck.org)
| ipset | Dnsmasq ipset |
| clashx | ClashX |
| kvas | Keenetic KVAS |
+| bat | Keenetic Routes .bat |
| amnezia | Amnezia filter list |
## Configuration
diff --git a/README.md b/README.md
index 2e22e8f..09fb1a8 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,7 @@ Demo URL: [https://iplist.opencck.org](https://iplist.opencck.org)
| ipset | Dnsmasq ipset |
| clashx | ClashX |
| kvas | Keenetic KVAS |
+| bat | Keenetic Routes .bat |
| amnezia | Amnezia filter list |
## Настройки
diff --git a/src/App/Controller/BatController.php b/src/App/Controller/BatController.php
new file mode 100644
index 0000000..432e43d
--- /dev/null
+++ b/src/App/Controller/BatController.php
@@ -0,0 +1,65 @@
+setHeaders(['content-type' => 'text/plain']);
+
+ $sites = SiteFactory::normalizeArray($this->request->getQueryParameters()['site'] ?? []);
+ $data = $this->request->getQueryParameter('data') ?? '';
+ if ($data == '') {
+ return "# Error: The 'data' GET parameter is required in the URL to access this page";
+ }
+ if (!in_array($data, ['ip4', 'cidr4'])) {
+ return "# Error: The 'data' GET parameter must be 'ip4' or 'cidr4'";
+ }
+
+ $response = [];
+ if (count($sites)) {
+ foreach ($sites as $site) {
+ $response = array_merge($response, $this->getSites()[$site]->$data);
+ }
+ } else {
+ foreach ($this->getSites() as $siteEntity) {
+ $response = array_merge($response, $siteEntity->$data);
+ }
+ }
+ $response = SiteFactory::normalizeArray($response, true);
+
+ return implode(
+ "\n",
+ array_map(function (string $item) {
+ $parts = explode('/', $item);
+ $mask = $this->formatShortIpMask($parts[1] ?? '');
+ return 'route add ' . $parts[0] . ' mask ' . $mask . ' 0.0.0.0';
+ }, $response)
+ );
+ }
+
+ /**
+ * @param string $mask
+ * @return string
+ */
+ private function formatShortIpMask(string $mask): string {
+ if ($mask == '') {
+ $mask = '32';
+ }
+ $binaryMask = str_repeat('1', $mask) . str_repeat('0', 32 - $mask);
+ $octets = [];
+
+ for ($i = 0; $i < 4; $i++) {
+ $octets[] = bindec(substr($binaryMask, $i * 8, 8));
+ }
+
+ return implode('.', $octets);
+ }
+}
diff --git a/src/App/Template/IndexTemplate.php b/src/App/Template/IndexTemplate.php
index 6712f57..c09f64a 100644
--- a/src/App/Template/IndexTemplate.php
+++ b/src/App/Template/IndexTemplate.php
@@ -630,6 +630,7 @@ use OpenCCK\App\Controller\MainController;
+