mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 17:42:41 +00:00
240 lines
6.9 KiB
Diff
240 lines
6.9 KiB
Diff
From 42e7cc0388b258ae0f391e7b0dbab9b53b067124 Mon Sep 17 00:00:00 2001
|
|
From: John Crispin <john@phrozen.org>
|
|
Date: Tue, 8 Jun 2021 09:12:38 +0200
|
|
Subject: [PATCH 12/43] dnsmasq: add relay / option82 support
|
|
|
|
Signed-off-by: John Crispin <john@phrozen.org>
|
|
---
|
|
.../services/dnsmasq/files/dnsmasq.init | 10 +-
|
|
.../dnsmasq/patches/200-option82.patch | 195 ++++++++++++++++++
|
|
2 files changed, 201 insertions(+), 4 deletions(-)
|
|
create mode 100644 package/network/services/dnsmasq/patches/200-option82.patch
|
|
|
|
diff --git a/package/network/services/dnsmasq/files/dnsmasq.init b/package/network/services/dnsmasq/files/dnsmasq.init
|
|
index 205bfb4cf6..dacd476cd4 100644
|
|
--- a/package/network/services/dnsmasq/files/dnsmasq.init
|
|
+++ b/package/network/services/dnsmasq/files/dnsmasq.init
|
|
@@ -777,12 +777,14 @@ dhcp_relay_add() {
|
|
[ -n "$server_addr" ] || return 0
|
|
|
|
config_get interface "$cfg" interface
|
|
- if [ -z "$interface" ]; then
|
|
- xappend "--dhcp-relay=$local_addr,$server_addr"
|
|
- else
|
|
+ config_get suboption1 "$cfg" suboption1
|
|
+ config_get suboption2 "$cfg" suboption2
|
|
+ config_get suboption151 "$cfg" suboption151
|
|
+ config_get suboption152 "$cfg" suboption152
|
|
+ if [ -n "$interface" ]; then
|
|
network_get_device ifname "$interface" || return
|
|
- xappend "--dhcp-relay=$local_addr,$server_addr,$ifname"
|
|
fi
|
|
+ xappend "--dhcp-relay=$local_addr,$server_addr,$ifname,$suboption1,$suboption2,$suboption151,$suboption152"
|
|
}
|
|
|
|
dnsmasq_ipset_add() {
|
|
diff --git a/package/network/services/dnsmasq/patches/200-option82.patch b/package/network/services/dnsmasq/patches/200-option82.patch
|
|
new file mode 100644
|
|
index 0000000000..7883b12922
|
|
--- /dev/null
|
|
+++ b/package/network/services/dnsmasq/patches/200-option82.patch
|
|
@@ -0,0 +1,195 @@
|
|
+diff --git a/src/dhcp.c b/src/dhcp.c
|
|
+index 97324f2..48e08b1 100644
|
|
+--- a/src/dhcp.c
|
|
++++ b/src/dhcp.c
|
|
+@@ -1057,14 +1057,83 @@ char *host_from_dns(struct in_addr addr)
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
++extern void insert_option82(struct dhcp_packet *mess, size_t *sz, char *opt, int len);
|
|
++
|
|
++static char *insert_suboption(char *opt, char id, char *string, struct ifreq *ifr, u8 *client)
|
|
++{
|
|
++ char *len, *o = opt;
|
|
++
|
|
++ if (!string || !*string)
|
|
++ return opt;
|
|
++
|
|
++ *o++ = id;
|
|
++ len = o++;
|
|
++
|
|
++ while (*string) {
|
|
++ if (*string == '%') {
|
|
++ string++;
|
|
++ switch(*string) {
|
|
++ case 'i':
|
|
++ memcpy(o, ifr->ifr_name, strlen(ifr->ifr_name));
|
|
++ o += strlen(ifr->ifr_name);
|
|
++ break;
|
|
++ case 'a':
|
|
++ memcpy(o, ifr->ifr_hwaddr.sa_data, 6);
|
|
++ o += 6;
|
|
++ break;
|
|
++ case 'A':
|
|
++ sprintf(o, "%02X:%02X:%02X:%02X:%02X:%02X",
|
|
++ ifr->ifr_hwaddr.sa_data[0],
|
|
++ ifr->ifr_hwaddr.sa_data[1],
|
|
++ ifr->ifr_hwaddr.sa_data[2],
|
|
++ ifr->ifr_hwaddr.sa_data[3],
|
|
++ ifr->ifr_hwaddr.sa_data[4],
|
|
++ ifr->ifr_hwaddr.sa_data[5]);
|
|
++ o += 17;
|
|
++ break;
|
|
++ case 'c':
|
|
++ memcpy(o, client, 6);
|
|
++ o += 6;
|
|
++ break;
|
|
++ case 'C':
|
|
++ sprintf(o, "%02X:%02X:%02X:%02X:%02X:%02X",
|
|
++ client[0],
|
|
++ client[1],
|
|
++ client[2],
|
|
++ client[3],
|
|
++ client[4],
|
|
++ client[5]);
|
|
++ o += 17;
|
|
++ break;
|
|
++ }
|
|
++ } else {
|
|
++ *o++ = *string;
|
|
++ }
|
|
++ string++;
|
|
++ }
|
|
++
|
|
++ *len = o - opt - 2;
|
|
++
|
|
++ return o;
|
|
++}
|
|
++
|
|
+ static int relay_upstream4(struct dhcp_relay *relay, struct dhcp_packet *mess, size_t sz, int iface_index)
|
|
+ {
|
|
+ /* ->local is same value for all relays on ->current chain */
|
|
++ struct ifreq ifr;
|
|
+ union all_addr from;
|
|
+-
|
|
++ char opt82[512] = { 82, 12 };
|
|
++ char *o = &opt82[2];
|
|
++ int len;
|
|
++
|
|
+ if (mess->op != BOOTREQUEST)
|
|
+ return 0;
|
|
+
|
|
++ if (!if_indextoname(iface_index, ifr.ifr_name))
|
|
++ return -1;
|
|
++ if (ioctl(daemon->dhcpfd, SIOCGIFHWADDR, &ifr))
|
|
++ return -1;
|
|
++
|
|
+ /* source address == relay address */
|
|
+ from.addr4 = relay->local.addr4;
|
|
+
|
|
+@@ -1080,10 +1149,22 @@ static int relay_upstream4(struct dhcp_relay *relay, struct dhcp_packet *mess,
|
|
+ /* plug in our address */
|
|
+ mess->giaddr.s_addr = relay->local.addr4.s_addr;
|
|
+ }
|
|
++
|
|
++ o = insert_suboption(o, 1, relay->sub_opt1, &ifr, mess->chaddr);
|
|
++ o = insert_suboption(o, 2, relay->sub_opt2, &ifr, mess->chaddr);
|
|
++ o = insert_suboption(o, 151, relay->sub_opt151, &ifr, mess->chaddr);
|
|
++ o = insert_suboption(o, 152, relay->sub_opt152, &ifr, mess->chaddr);
|
|
++
|
|
++ len = o - opt82;
|
|
++ opt82[1] = len - 2;
|
|
++
|
|
++ insert_option82(mess, &sz, opt82, len);
|
|
+
|
|
+ if ((mess->hops++) > 20)
|
|
+ return 1;
|
|
+
|
|
++
|
|
++
|
|
+ for (; relay; relay = relay->current)
|
|
+ {
|
|
+ union mysockaddr to;
|
|
+diff --git a/src/dnsmasq.h b/src/dnsmasq.h
|
|
+index e770454..abc79f8 100644
|
|
+--- a/src/dnsmasq.h
|
|
++++ b/src/dnsmasq.h
|
|
+@@ -1005,6 +1005,10 @@ struct dhcp_relay {
|
|
+ char *interface; /* Allowable interface for replies from server, and dest for IPv6 multicast */
|
|
+ int iface_index; /* working - interface in which requests arrived, for return */
|
|
+ struct dhcp_relay *current, *next;
|
|
++ char sub_opt1[64];
|
|
++ char sub_opt2[64];
|
|
++ char sub_opt151[16];
|
|
++ char sub_opt152[16];
|
|
+ };
|
|
+
|
|
+ extern struct daemon {
|
|
+diff --git a/src/option.c b/src/option.c
|
|
+index 0a72406..b06d1c8 100644
|
|
+--- a/src/option.c
|
|
++++ b/src/option.c
|
|
+@@ -3957,10 +3957,25 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|
+ case LOPT_RELAY: /* --dhcp-relay */
|
|
+ {
|
|
+ struct dhcp_relay *new = opt_malloc(sizeof(struct dhcp_relay));
|
|
+- comma = split(arg);
|
|
+- new->interface = opt_string_alloc(split(comma));
|
|
++ char *args[7] = {}, **arg_p = args;
|
|
++
|
|
++ while (arg) {
|
|
++ comma = split(arg);
|
|
++ *arg_p++ = arg;
|
|
++ arg = comma;
|
|
++ }
|
|
++
|
|
++ if (args[3] && *args[3])
|
|
++ memcpy(new->sub_opt1, args[3], strlen(args[3]) + 1);
|
|
++ if (args[4] && *args[4])
|
|
++ memcpy(new->sub_opt2, args[4], strlen(args[4]) + 1);
|
|
++ if (args[5] && *args[5])
|
|
++ memcpy(new->sub_opt151, args[5], strlen(args[5]) + 1);
|
|
++ if (args[6] && *args[6])
|
|
++ memcpy(new->sub_opt152, args[6], strlen(args[6]) + 1);
|
|
++ new->interface = opt_string_alloc(args[2]);
|
|
+ new->iface_index = 0;
|
|
+- if (inet_pton(AF_INET, arg, &new->local) && inet_pton(AF_INET, comma, &new->server))
|
|
++ if (inet_pton(AF_INET, args[0], &new->local) && inet_pton(AF_INET, args[1], &new->server))
|
|
+ {
|
|
+ new->next = daemon->relay4;
|
|
+ daemon->relay4 = new;
|
|
+@@ -3977,7 +3992,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|
+ free(new->interface);
|
|
+ ret_err_free(_("Bad dhcp-relay"), new);
|
|
+ }
|
|
+-
|
|
++
|
|
+ break;
|
|
+ }
|
|
+
|
|
+diff --git a/src/rfc2131.c b/src/rfc2131.c
|
|
+index 3f50755..792a274 100644
|
|
+--- a/src/rfc2131.c
|
|
++++ b/src/rfc2131.c
|
|
+@@ -2785,6 +2785,21 @@ static void apply_delay(u32 xid, time_t recvtime, struct dhcp_netid *netid)
|
|
+ }
|
|
+ }
|
|
+
|
|
++void insert_option82(struct dhcp_packet *mess, size_t *sz, char *opt82, int len)
|
|
++{
|
|
++ if (!option_find(mess, *sz, OPTION_AGENT_ID, 2)) {
|
|
++ unsigned char *end = option_find(mess, *sz, OPTION_END, 1);
|
|
++ int space = 312 - (end - mess->options) - 1;
|
|
++
|
|
++ if (space < len)
|
|
++ return;
|
|
++ memcpy(end, opt82, len);
|
|
++ end[len] = OPTION_END;
|
|
++ *sz += len;
|
|
++ }
|
|
++}
|
|
++
|
|
++
|
|
+ #endif
|
|
+
|
|
+
|
|
--
|
|
2.25.1
|
|
|