/* * A lie! It always returns! */ static rlm_rcode_t sometimes_return(void *instance, RADIUS_PACKET *packet, RADIUS_PACKET *reply) { uint32_t hash; int value; rlm_sometimes_t *inst = instance; VALUE_PAIR *vp; /* * Set it to NOOP and the module will always do nothing */ if (inst->rcode == RLM_MODULE_NOOP) return inst->rcode; /* * Hash based on the given key. Usually User-Name. */ vp = pairfind(packet->vps, inst->da->attr, inst->da->vendor, TAG_ANY); if (!vp) return RLM_MODULE_NOOP; hash = fr_hash(&vp->data, vp->length); hash &= 0xff; /* ensure it's 0..255 */ value = hash; /* * Ranges are INCLUSIVE. * [start,end] returns "rcode" * Everything else returns "noop" */ if (value < inst->start) return RLM_MODULE_NOOP; if (value > inst->end) return RLM_MODULE_NOOP; /* * If we're returning "handled", then set the packet * code in the reply, so that the server responds. */ if ((inst->rcode == RLM_MODULE_HANDLED) && reply) { switch (packet->code) { case PW_AUTHENTICATION_REQUEST: reply->code = PW_AUTHENTICATION_ACK; break; case PW_ACCOUNTING_REQUEST: reply->code = PW_ACCOUNTING_RESPONSE; break; case PW_COA_REQUEST: reply->code = PW_COA_ACK; break; case PW_DISCONNECT_REQUEST: reply->code = PW_DISCONNECT_ACK; break; default: break; } } return inst->rcode; }
static uint32_t dict_value_value_hash(const void *data) { uint32_t hash; const DICT_VALUE *dval = data; hash = fr_hash(&dval->attr, sizeof(dval->attr)); return fr_hash_update(&dval->value, sizeof(dval->value), hash); }
static uint32_t dict_attr_value_hash(const void *data) { uint32_t hash; const DICT_ATTR *attr = data; hash = fr_hash(&attr->vendor, sizeof(attr->vendor)); return fr_hash_update(&attr->attr, sizeof(attr->attr), hash); }
/* * Take the key fields of a request packet, and convert it to a * hash. */ uint32_t fr_request_packet_hash(const RADIUS_PACKET *packet) { uint32_t hash; if (packet->hash) return packet->hash; hash = fr_hash(&packet->sockfd, sizeof(packet->sockfd)); hash = fr_hash_update(&packet->src_port, sizeof(packet->src_port), hash); hash = fr_hash_update(&packet->dst_port, sizeof(packet->dst_port), hash); hash = fr_hash_update(&packet->src_ipaddr.af, sizeof(packet->src_ipaddr.af), hash); /* * The caller ensures that src & dst AF are the same. */ switch (packet->src_ipaddr.af) { case AF_INET: hash = fr_hash_update(&packet->src_ipaddr.ipaddr.ip4addr, sizeof(packet->src_ipaddr.ipaddr.ip4addr), hash); hash = fr_hash_update(&packet->dst_ipaddr.ipaddr.ip4addr, sizeof(packet->dst_ipaddr.ipaddr.ip4addr), hash); break; case AF_INET6: hash = fr_hash_update(&packet->src_ipaddr.ipaddr.ip6addr, sizeof(packet->src_ipaddr.ipaddr.ip6addr), hash); hash = fr_hash_update(&packet->dst_ipaddr.ipaddr.ip6addr, sizeof(packet->dst_ipaddr.ipaddr.ip6addr), hash); break; default: break; } return fr_hash_update(&packet->id, sizeof(packet->id), hash); }
static uint32_t packet_dst2id_hash(const void *data) { uint32_t hash; const fr_packet_dst2id_t *pd = data; hash = fr_hash(&pd->dst_port, sizeof(pd->dst_port)); switch (pd->dst_ipaddr.af) { case AF_INET: hash = fr_hash_update(&pd->dst_ipaddr.ipaddr.ip4addr, sizeof(pd->dst_ipaddr.ipaddr.ip4addr), hash); break; case AF_INET6: hash = fr_hash_update(&pd->dst_ipaddr.ipaddr.ip6addr, sizeof(pd->dst_ipaddr.ipaddr.ip6addr), hash); break; default: break; } return hash; }
static uint32_t pid_hash(const void *data) { const thread_fork_t *tf = data; return fr_hash(&tf->pid, sizeof(tf->pid)); }
static uint32_t dict_vendor_value_hash(const void *data) { return fr_hash(&(((const DICT_VENDOR *)data)->vendorpec), sizeof(((const DICT_VENDOR *)data)->vendorpec)); }
static uint32_t detail_hash(void const *data) { DICT_ATTR const *da = data; return fr_hash(&da, sizeof(da)); }
uint32_t hash_state(const void *data) { const struct radius_state_node *p = data; return fr_hash(p->data, p->datalen); }
/* * A lie! It always returns! */ static rlm_rcode_t sometimes_return(void const *instance, REQUEST *request, RADIUS_PACKET *packet, RADIUS_PACKET *reply) { uint32_t hash; uint32_t value; rlm_sometimes_t const *inst = instance; VALUE_PAIR *vp; /* * Set it to NOOP and the module will always do nothing */ if (inst->rcode == RLM_MODULE_NOOP) return inst->rcode; /* * Hash based on the given key. Usually User-Name. */ tmpl_find_vp(&vp, request, inst->key); if (!vp) return RLM_MODULE_NOOP; switch (vp->vp_type) { case FR_TYPE_OCTETS: case FR_TYPE_STRING: hash = fr_hash(vp->data.datum.ptr, vp->vp_length); break; case FR_TYPE_ABINARY: hash = fr_hash(vp->vp_filter, vp->vp_length); break; case FR_TYPE_STRUCTURAL: return RLM_MODULE_FAIL; default: hash = fr_hash(&vp->data.datum, fr_value_box_field_sizes[vp->vp_type]); break; } hash &= 0xff; /* ensure it's 0..255 */ value = hash; /* * Ranges are INCLUSIVE. * [start,end] returns "rcode" * Everything else returns "noop" */ if (value < inst->start) return RLM_MODULE_NOOP; if (value > inst->end) return RLM_MODULE_NOOP; /* * If we're returning "handled", then set the packet * code in the reply, so that the server responds. */ if ((inst->rcode == RLM_MODULE_HANDLED) && reply) { switch (packet->code) { case FR_CODE_ACCESS_REQUEST: reply->code = FR_CODE_ACCESS_ACCEPT; break; case FR_CODE_ACCOUNTING_REQUEST: reply->code = FR_CODE_ACCOUNTING_RESPONSE; break; case FR_CODE_COA_REQUEST: reply->code = FR_CODE_COA_ACK; break; case FR_CODE_DISCONNECT_REQUEST: reply->code = FR_CODE_DISCONNECT_ACK; break; default: break; } } return inst->rcode; }