- char *avpair, *value, *key, *newp;
- avpair = key = calloc(attrib_length + 1, 1);
- memcpy(avpair, p + 8, attrib_length);
- LOG(3, 0, s, session[s].tunnel, " Cisco-Avpair value: %s\n", avpair);
- do {
- value = strchr(key, '=');
- if (!value) break;
- *value++ = 0;
-
- // Trim quotes off reply string
- if (*value == '\'' || *value == '\"')
- {
- char *x;
- value++;
- x = value + strlen(value) - 1;
- if (*x == '\'' || *x == '\"')
- *x = 0;
- }
-
- // Run hooks
- newp = strchr(value, ',');
- if (newp) *newp++ = 0;
- {
- struct param_radius_response p = { &tunnel[session[s].tunnel], &session[s], key, value };
- run_plugins(PLUGIN_RADIUS_RESPONSE, &p);
- }
- key = newp;
- } while (newp);
- free(avpair);
+ LOG(3, s, session[s].tunnel, " Unknown vendor-specific\n");
+ continue;
+ }
+
+ if (attrib_length < 0) continue;
+
+ avpair = key = calloc(attrib_length + 1, 1);
+ memcpy(avpair, p + 8, attrib_length);
+ LOG(3, s, session[s].tunnel, " Cisco-Avpair value: %s\n", avpair);
+ do {
+ value = strchr(key, '=');
+ if (!value) break;
+ *value++ = 0;
+
+ // Trim quotes off reply string
+ if (*value == '\'' || *value == '\"')
+ {
+ char *x;
+ value++;
+ x = value + strlen(value) - 1;
+ if (*x == '\'' || *x == '\"')
+ *x = 0;
+ }
+
+ // Run hooks
+ newp = strchr(value, ',');
+ if (newp) *newp++ = 0;
+ {
+ struct param_radius_response p = { &tunnel[session[s].tunnel], &session[s], key, value };
+ run_plugins(PLUGIN_RADIUS_RESPONSE, &p);
+ }
+ key = newp;
+ } while (newp);
+ free(avpair);
+ }
+ else if (*p == 99)
+ {
+ // Framed-IPv6-Route
+ struct in6_addr r6;
+ int prefixlen;
+ uint8_t *n = p + 2;
+ uint8_t *e = p + p[1];
+ uint8_t *m = strchr(n, '/');
+
+ *m++ = 0;
+ inet_pton(AF_INET6, n, &r6);
+
+ prefixlen = 0;
+ while (m < e && isdigit(*m)) {
+ prefixlen = prefixlen * 10 + *m++ - '0';
+ }
+
+ if (prefixlen)
+ {
+ LOG(3, s, session[s].tunnel,
+ " Radius reply contains route for %s/%d\n",
+ n, prefixlen);
+ session[s].ipv6route = r6;
+ session[s].ipv6prefixlen = prefixlen;