static char *xlat_getvp(TALLOC_CTX *ctx, REQUEST *request, pair_lists_t list, DICT_ATTR const *da, int8_t tag, int num, bool return_null) { VALUE_PAIR *vp, *vps = NULL; RADIUS_PACKET *packet = NULL; DICT_VALUE *dv; VALUE_PAIR myvp; /* * Arg. Too much abstraction is annoying. */ switch (list) { default: if (return_null) return NULL; return vp_aprinttype(ctx, da->type); case PAIR_LIST_CONTROL: vps = request->config_items; break; case PAIR_LIST_REQUEST: packet = request->packet; if (packet) vps = packet->vps; break; case PAIR_LIST_REPLY: packet = request->reply; if (packet) vps = packet->vps; break; #ifdef WITH_PROXY case PAIR_LIST_PROXY_REQUEST: packet = request->proxy; if (packet) vps = packet->vps; break; case PAIR_LIST_PROXY_REPLY: packet = request->proxy_reply; if (packet) vps = packet->vps; break; #endif #ifdef WITH_COA case PAIR_LIST_COA: case PAIR_LIST_DM: if (request->coa) packet = request->coa->packet; if (packet) vps = packet->vps; break; case PAIR_LIST_COA_REPLY: case PAIR_LIST_DM_REPLY: if (request->coa) packet = request->coa->reply; if (packet) vps = packet->vps; break; #endif } /* * Now that we have the list, etc. handled, * find the VP and print it. */ if ((da->vendor != 0) || (da->attr < 256) || (list == PAIR_LIST_CONTROL)) { print_vp: vp = pairfind(vps, da->attr, da->vendor, tag); if (!vp) { return NULL; } goto do_print; } /* * Some non-packet expansions */ switch (da->attr) { default: break; /* ignore them */ case PW_CLIENT_SHORTNAME: if (request->client && request->client->shortname) { return talloc_strdup(ctx, request->client->shortname); } return talloc_strdup(ctx, "<UNKNOWN-CLIENT>"); case PW_REQUEST_PROCESSING_STAGE: if (request->component) { return talloc_strdup(ctx, request->component); } return talloc_strdup(ctx, "server_core"); case PW_VIRTUAL_SERVER: if (!request->server) return NULL; return talloc_strdup(ctx, request->server); case PW_MODULE_RETURN_CODE: return talloc_asprintf(ctx, "%d", request->simul_max); /* hack */ } /* * All of the attributes must now refer to a packet. If * there's no packet, we can't print any attribute * referencing it. */ if (!packet) { if (return_null) return NULL; return vp_aprinttype(ctx, da->type); } memset(&myvp, 0, sizeof(myvp)); myvp.da = da; vp = NULL; switch (da->attr) { default: goto print_vp; case PW_PACKET_TYPE: dv = dict_valbyattr(PW_PACKET_TYPE, 0, packet->code); if (dv) return talloc_strdup(ctx, dv->name); return talloc_asprintf(ctx, "%d", packet->code); case PW_RESPONSE_PACKET_TYPE: { int code = 0; #ifdef WITH_PROXY if (request->proxy_reply && (!request->reply || !request->reply->code)) { code = request->proxy_reply->code; } else #endif if (request->reply) { code = request->reply->code; } return talloc_strdup(ctx, fr_packet_codes[code]); } case PW_PACKET_AUTHENTICATION_VECTOR: myvp.length = sizeof(packet->vector); memcpy(&myvp.vp_octets, packet->vector, sizeof(packet->vector)); vp = &myvp; break; case PW_CLIENT_IP_ADDRESS: case PW_PACKET_SRC_IP_ADDRESS: if (packet->src_ipaddr.af == AF_INET) { myvp.vp_ipaddr = packet->src_ipaddr.ipaddr.ip4addr.s_addr; vp = &myvp; } break; case PW_PACKET_DST_IP_ADDRESS: if (packet->dst_ipaddr.af == AF_INET) { myvp.vp_ipaddr = packet->dst_ipaddr.ipaddr.ip4addr.s_addr; vp = &myvp; } break; case PW_PACKET_SRC_IPV6_ADDRESS: if (packet->src_ipaddr.af == AF_INET6) { memcpy(&myvp.vp_ipv6addr, &packet->src_ipaddr.ipaddr.ip6addr, sizeof(packet->src_ipaddr.ipaddr.ip6addr)); vp = &myvp; } break; case PW_PACKET_DST_IPV6_ADDRESS: if (packet->dst_ipaddr.af == AF_INET6) { memcpy(&myvp.vp_ipv6addr, &packet->dst_ipaddr.ipaddr.ip6addr, sizeof(packet->dst_ipaddr.ipaddr.ip6addr)); vp = &myvp; } break; case PW_PACKET_SRC_PORT: myvp.vp_integer = packet->src_port; vp = &myvp; break; case PW_PACKET_DST_PORT: myvp.vp_integer = packet->dst_port; vp = &myvp; break; } do_print: /* * Hack up the virtual attributes. */ if (num && (vp == &myvp)) { char *p, *q; /* * [*] means only one. */ if (num == 65537) num = 0; /* * [n] means NULL, as there's only one. */ if ((num > 0) && (num < 65536)) { return NULL; } p = vp_aprint(ctx, vp); rad_assert(p != NULL); /* * Get the length of it. */ if (num == 65536) { q = talloc_asprintf(ctx, "%d", (int) strlen(p)); talloc_free(p); return q; } return p; } /* * We want the N'th VP. */ if (num) { int count = 0; vp_cursor_t cursor; /* * Return a count of the VPs. */ if (num == 65536) { fr_cursor_init(&cursor, &vp); while (fr_cursor_next_by_num(&cursor, da->attr, da->vendor, tag) != NULL) { count++; } return talloc_asprintf(ctx, "%d", count); } /* * Ugly, but working. */ if (num == 65537) { char *p, *q; (void) fr_cursor_init(&cursor, &vp); vp = fr_cursor_next_by_num(&cursor, da->attr, da->vendor, tag); if (!vp) return NULL; p = vp_aprint(ctx, vp); while ((vp = fr_cursor_next_by_num(&cursor, da->attr, da->vendor, tag)) != NULL) { q = vp_aprint(ctx, vp); p = talloc_strdup_append(p, ","); p = talloc_strdup_append(p, q); } return p; } (void) fr_cursor_init(&cursor, &vp); while ((vp = fr_cursor_next_by_num(&cursor, da->attr, da->vendor, tag)) != NULL) { if (count == num) { break; } count++; } } if (!vp) { if (return_null) return NULL; return vp_aprinttype(ctx, da->type); } return vp_aprint(ctx, vp); }
static char *xlat_getvp(TALLOC_CTX *ctx, REQUEST *request, pair_lists_t list, DICT_ATTR const *da, int8_t tag, bool return_null) { VALUE_PAIR *vp, *vps = NULL; RADIUS_PACKET *packet = NULL; DICT_VALUE *dv; VALUE_PAIR myvp; /* * Arg. Too much abstraction is annoying. */ switch (list) { default: if (return_null) return NULL; return vp_aprinttype(ctx, da->type); case PAIR_LIST_CONTROL: vps = request->config_items; break; case PAIR_LIST_REQUEST: packet = request->packet; if (packet) vps = packet->vps; break; case PAIR_LIST_REPLY: packet = request->reply; if (packet) vps = packet->vps; break; #if WITH_PROXY case PAIR_LIST_PROXY_REQUEST: packet = request->proxy; if (packet) vps = packet->vps; break; case PAIR_LIST_PROXY_REPLY: packet = request->proxy_reply; if (packet) vps = packet->vps; break; #endif #ifdef WITH_COA case PAIR_LIST_COA: case PAIR_LIST_DM: if (request->coa) packet = request->coa->packet; if (packet) vps = packet->vps; break; case PAIR_LIST_COA_REPLY: case PAIR_LIST_DM_REPLY: if (request->coa) packet = request->coa->reply; if (packet) vps = packet->vps; break; #endif } /* * Now that we have the list, etc. handled, * find the VP and print it. */ if ((da->vendor != 0) || (da->attr < 256) || (list == PAIR_LIST_CONTROL)) { print_vp: vp = pairfind(vps, da->attr, da->vendor, tag); goto do_print; } /* * Some non-packet expansions */ switch (da->attr) { default: break; /* ignore them */ case PW_CLIENT_SHORTNAME: if (request->client && request->client->shortname) { return talloc_strdup(ctx, request->client->shortname); } return talloc_strdup(ctx, "<UNKNOWN-CLIENT>"); case PW_REQUEST_PROCESSING_STAGE: if (request->component) { return talloc_strdup(ctx, request->component); } return talloc_strdup(ctx, "server_core"); case PW_VIRTUAL_SERVER: if (!request->server) return NULL; return talloc_strdup(ctx, request->server); case PW_MODULE_RETURN_CODE: return talloc_asprintf(ctx, "%d", request->simul_max); /* hack */ } /* * All of the attributes must now refer to a packet. If * there's no packet, we can't print any attribute * referencing it. */ if (!packet) { if (return_null) return NULL; return vp_aprinttype(ctx, da->type); } memset(&myvp, 0, sizeof(myvp)); myvp.da = da; vp = NULL; switch (da->attr) { default: goto print_vp; case PW_PACKET_TYPE: dv = dict_valbyattr(PW_PACKET_TYPE, 0, packet->code); if (dv) return talloc_strdup(ctx, dv->name); return talloc_asprintf(ctx, "%d", packet->code); case PW_PACKET_AUTHENTICATION_VECTOR: myvp.length = sizeof(packet->vector); memcpy(&myvp.vp_octets, packet->vector, sizeof(packet->vector)); vp = &myvp; break; case PW_CLIENT_IP_ADDRESS: case PW_PACKET_SRC_IP_ADDRESS: if (packet->src_ipaddr.af == AF_INET) { myvp.vp_ipaddr = packet->src_ipaddr.ipaddr.ip4addr.s_addr; vp = &myvp; } break; case PW_PACKET_DST_IP_ADDRESS: if (packet->dst_ipaddr.af == AF_INET) { myvp.vp_ipaddr = packet->dst_ipaddr.ipaddr.ip4addr.s_addr; vp = &myvp; } break; case PW_PACKET_SRC_IPV6_ADDRESS: if (packet->src_ipaddr.af == AF_INET6) { memcpy(&myvp.vp_ipv6addr, &packet->src_ipaddr.ipaddr.ip6addr, sizeof(packet->src_ipaddr.ipaddr.ip6addr)); vp = &myvp; } break; case PW_PACKET_DST_IPV6_ADDRESS: if (packet->dst_ipaddr.af == AF_INET6) { memcpy(&myvp.vp_ipv6addr, &packet->dst_ipaddr.ipaddr.ip6addr, sizeof(packet->dst_ipaddr.ipaddr.ip6addr)); vp = &myvp; } break; case PW_PACKET_SRC_PORT: myvp.vp_integer = packet->src_port; vp = &myvp; break; case PW_PACKET_DST_PORT: myvp.vp_integer = packet->dst_port; vp = &myvp; break; } do_print: if (!vp) { if (return_null) return NULL; return vp_aprinttype(ctx, da->type); } return vp_aprint(ctx, vp); }