diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2020-03-31 21:57:53 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2020-03-31 21:57:53 +0200 |
commit | d3512f60df5d7a2ea5c4cad3cdef797f1f95a182 (patch) | |
tree | d374b50d09b51d06ac4ee57b265c31a12205cec4 | |
parent | 480ce0314ee6338644bc202aa68c13c06b1846ce (diff) |
ip/dhcp6d: work arround non-ethernet based client duid
in ndb, we use the ethernet mac to identify the client.
in dhcpv6, there is just a uniqueue device id that
might even be generated randomly. to find the ethernet
address of a client, check the duid type and only use
it when the dudid is of type 1 (link layer) or 3 (link
layer address + time) and the link layer address type
is 1 (ethernet). otherwise, assume the source ip is
a link local address and extract it from that.
this hack works for thinkpad t495, which uses random
uuid based client duid.
-rw-r--r-- | sys/src/cmd/ip/dhcp6d.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/sys/src/cmd/ip/dhcp6d.c b/sys/src/cmd/ip/dhcp6d.c index 8250518a0..c75c67ea0 100644 --- a/sys/src/cmd/ip/dhcp6d.c +++ b/sys/src/cmd/ip/dhcp6d.c @@ -31,7 +31,8 @@ struct Req Udphdr *udp; Ipifc *ifc; - uchar mac[Eaddrlen]; + int ncid; + uchar cid[256]; uchar ips[IPaddrlen*8]; int nips; @@ -236,6 +237,31 @@ lookupips(uchar *ip, int n, Ndb *db, uchar mac[Eaddrlen]) return r; } +static uchar* +clientea(Req *r) +{ + static uchar ea[Eaddrlen]; + u32int type; + uchar *ip; + + if(r->ncid >= 4+Eaddrlen){ + type = r->cid[0]<<24 | r->cid[1]<<16 | r->cid[2]<<8 | r->cid[3]; + switch(type){ + case 0x00010001: + case 0x00030001: + return r->cid + r->ncid - Eaddrlen; + } + } + ip = r->udp->raddr; + ea[0] = ip[8] ^ 2; + ea[1] = ip[9]; + ea[2] = ip[10]; + ea[3] = ip[13]; + ea[4] = ip[14]; + ea[5] = ip[15]; + return ea; +} + static void clearotab(void) { @@ -387,7 +413,7 @@ main(int argc, char *argv[]) if((r->db = opendb()) == nil) continue; - r->nips = lookupips(r->ips, sizeof(r->ips), r->db, r->mac)/IPaddrlen; + r->nips = lookupips(r->ips, sizeof(r->ips), r->db, clientea(r))/IPaddrlen; if(debug){ for(i=0; i<r->nips; i++) fprint(2, "ip=%I\n", r->ips+i*IPaddrlen); @@ -411,10 +437,11 @@ oclientid(uchar *w, int n, Otab*, Req *r) if((p = gettlv(1, &len, r->req.p, r->req.e)) == nil) return -1; - if(len < 4+4+Eaddrlen || n < len) + if(len > sizeof(r->cid) || n < len) return -1; - memmove(r->mac, p+len-Eaddrlen, Eaddrlen); memmove(w, p, len); + memmove(r->cid, p, len); + r->ncid = len; return len; } |