diff options
Diffstat (limited to 'accel-pptpd/radius/packet.c')
-rw-r--r-- | accel-pptpd/radius/packet.c | 644 |
1 files changed, 0 insertions, 644 deletions
diff --git a/accel-pptpd/radius/packet.c b/accel-pptpd/radius/packet.c deleted file mode 100644 index 4e24ded..0000000 --- a/accel-pptpd/radius/packet.c +++ /dev/null @@ -1,644 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> - -#include "log.h" -#include "mempool.h" - -#include "radius_p.h" - -#include "memdebug.h" - -static mempool_t packet_pool; -static mempool_t attr_pool; - -struct rad_packet_t *rad_packet_alloc(int code) -{ - struct rad_packet_t *pack; - - pack = mempool_alloc(packet_pool); - if (!pack) { - log_emerg("radius:packet: out of memory\n"); - return NULL; - } - - memset(pack, 0, sizeof(*pack)); - pack->code = code; - pack->len = 20; - pack->id = 1; - INIT_LIST_HEAD(&pack->attrs); - - return pack; -} - -void print_buf(uint8_t *buf,int size) -{ - int i; - for(i=0;i<size;i++) - printf("%x ",buf[i]); - printf("\n"); -} - -int rad_packet_build(struct rad_packet_t *pack, uint8_t *RA) -{ - struct rad_attr_t *attr; - uint8_t *ptr; - - if (pack->buf) - ptr = _realloc(pack->buf, pack->len); - else - ptr = _malloc(pack->len); - - if (!ptr) { - log_emerg("radius:packet: out of memory\n"); - return -1; - } - - pack->buf = ptr; - *ptr = pack->code; ptr++; - *ptr = pack->id; ptr++; - *(uint16_t*)ptr = htons(pack->len); ptr+= 2; - memcpy(ptr, RA, 16); ptr+=16; - - list_for_each_entry(attr, &pack->attrs, entry) { - if (attr->vendor) { - *ptr = 26; ptr++; - *ptr = attr->len + 2 + 6; ptr++; - *(uint32_t *)ptr = htonl(attr->vendor->id); ptr+=4; - } - *ptr = attr->attr->id; ptr++; - *ptr = attr->len + 2; ptr++; - switch(attr->attr->type) { - case ATTR_TYPE_INTEGER: - *(uint32_t*)ptr = htonl(attr->val.integer); - break; - case ATTR_TYPE_OCTETS: - case ATTR_TYPE_STRING: - memcpy(ptr, attr->val.string, attr->len); - break; - case ATTR_TYPE_IPADDR: - *(in_addr_t*)ptr = attr->val.ipaddr; - break; - case ATTR_TYPE_DATE: - *(uint32_t*)ptr = htonl(attr->val.date); - break; - default: - log_emerg("radius:packet:BUG: unknown attribute type\n"); - abort(); - } - ptr += attr->len; - } - - //print_buf(pack->buf, pack->len); - return 0; -} - -int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr) -{ - struct rad_packet_t *pack; - struct rad_attr_t *attr; - struct rad_dict_attr_t *da; - struct rad_dict_vendor_t *vendor; - uint8_t *ptr; - int n, id, len, vendor_id; - socklen_t addr_len = sizeof(*addr); - - *p = NULL; - - pack = rad_packet_alloc(0); - if (!pack) - return 0; - - pack->buf = _malloc(REQ_LENGTH_MAX); - if (!pack->buf) { - log_emerg("radius:packet: out of memory\n"); - goto out_err; - } - - while (1) { - if (addr) - n = recvfrom(fd, pack->buf, REQ_LENGTH_MAX, 0, addr, &addr_len); - else - n = read(fd, pack->buf, REQ_LENGTH_MAX); - if (n < 0) { - if (errno == EAGAIN) { - rad_packet_free(pack); - return -1; - } - if (errno != ECONNREFUSED) - log_ppp_error("radius:packet:read: %s\n", strerror(errno)); - goto out_err; - } - break; - } - - if (n < 20) { - log_ppp_warn("radius:packet: short packed received (%i)\n", n); - goto out_err; - } - - ptr = (uint8_t *)pack->buf; - - pack->code = *ptr; ptr++; - pack->id = *ptr; ptr++; - pack->len = ntohs(*(uint16_t*)ptr); ptr += 2; - - if (pack->len > n) { - log_ppp_warn("radius:packet: short packet received %i, expected %i\n", pack->len, n); - goto out_err; - } - - ptr += 16; - n -= 20; - - while (n>0) { - id = *ptr; ptr++; - len = *ptr - 2; ptr++; - if (len < 0) { - log_ppp_warn("radius:packet short attribute len received\n"); - goto out_err; - } - if (2 + len > n) { - log_ppp_warn("radius:packet: too long attribute received (%i, %i)\n", id, len); - goto out_err; - } - if (id == 26) { - vendor_id = ntohl(*(uint32_t *)ptr); - vendor = rad_dict_find_vendor_id(vendor_id); - if (vendor) { - ptr += 4; - id = *ptr; ptr++; - len = *ptr - 2; ptr++; - n -= 2 + 4; - } else - log_ppp_warn("radius:packet: vendor %i not found\n", id); - } else - vendor = NULL; - da = rad_dict_find_attr_id(vendor, id); - if (da) { - attr = mempool_alloc(attr_pool); - if (!attr) { - log_emerg("radius:packet: out of memory\n"); - goto out_err; - } - memset(attr, 0, sizeof(*attr)); - attr->vendor = vendor; - attr->attr = da; - attr->len = len; - switch (da->type) { - case ATTR_TYPE_STRING: - attr->val.string = _malloc(len+1); - if (!attr->val.string) { - log_emerg("radius:packet: out of memory\n"); - _free(attr); - goto out_err; - } - memcpy(attr->val.string, ptr, len); - attr->val.string[len] = 0; - break; - case ATTR_TYPE_OCTETS: - attr->val.octets = _malloc(len); - if (!attr->val.octets) { - log_emerg("radius:packet: out of memory\n"); - _free(attr); - goto out_err; - } - memcpy(attr->val.octets, ptr, len); - break; - case ATTR_TYPE_DATE: - case ATTR_TYPE_INTEGER: - attr->val.integer = ntohl(*(uint32_t*)ptr); - break; - case ATTR_TYPE_IPADDR: - attr->val.integer = *(uint32_t*)ptr; - break; - } - list_add_tail(&attr->entry, &pack->attrs); - } else - log_ppp_warn("radius:packet: unknown attribute received (%i,%i)\n", vendor ? vendor->id : 0, id); - ptr += len; - n -= 2 + len; - } - - *p = pack; - - return 0; - -out_err: - rad_packet_free(pack); - return 0; -} - -void rad_packet_free(struct rad_packet_t *pack) -{ - struct rad_attr_t *attr; - - if (pack->buf) - _free(pack->buf); - - while(!list_empty(&pack->attrs)) { - attr = list_entry(pack->attrs.next, typeof(*attr), entry); - list_del(&attr->entry); - if (attr->attr->type == ATTR_TYPE_STRING || attr->attr->type == ATTR_TYPE_OCTETS) - _free(attr->val.string); - mempool_free(attr); - } - - mempool_free(pack); -} - -void rad_packet_print(struct rad_packet_t *pack, void (*print)(const char *fmt, ...)) -{ - struct rad_attr_t *attr; - struct rad_dict_value_t *val; - - print("[RADIUS "); - switch(pack->code) { - case CODE_ACCESS_REQUEST: - print("Access-Request"); - break; - case CODE_ACCESS_CHALLENGE: - print("Access-Challenge"); - break; - case CODE_ACCESS_ACCEPT: - print("Access-Accept"); - break; - case CODE_ACCESS_REJECT: - print("Access-Reject"); - break; - case CODE_ACCOUNTING_REQUEST: - print("Accounting-Request"); - break; - case CODE_ACCOUNTING_RESPONSE: - print("Accounting-Response"); - break; - case CODE_DISCONNECT_REQUEST: - print("Disconnect-Request"); - break; - case CODE_DISCONNECT_ACK: - print("Disconnect-ACK"); - break; - case CODE_DISCONNECT_NAK: - print("Disconnect-NAK"); - break; - case CODE_COA_REQUEST: - print("CoA-Request"); - break; - case CODE_COA_ACK: - print("CoA-ACK"); - break; - case CODE_COA_NAK: - print("CoA-NAK"); - break; - default: - print("Unknown (%i)", pack->code); - } - print(" id=%x", pack->id); - - list_for_each_entry(attr, &pack->attrs, entry) { - if (attr->vendor) - print("<%s %s ", attr->vendor->name, attr->attr->name); - else - print(" <%s ", attr->attr->name); - switch (attr->attr->type) { - case ATTR_TYPE_INTEGER: - val = rad_dict_find_val(attr->attr, attr->val); - if (val) - print("%s", val->name); - else - print("%u", attr->val.integer); - break; - case ATTR_TYPE_STRING: - print("\"%s\"", attr->val.string); - break; - case ATTR_TYPE_IPADDR: - print("%i.%i.%i.%i", attr->val.ipaddr & 0xff, (attr->val.ipaddr >> 8) & 0xff, (attr->val.ipaddr >> 16) & 0xff, (attr->val.ipaddr >> 24) & 0xff); - break; - } - print(">"); - } - print("]\n"); -} - -int __export rad_packet_add_int(struct rad_packet_t *pack, const char *vendor_name, const char *name, int val) -{ - struct rad_attr_t *ra; - struct rad_dict_attr_t *attr; - struct rad_dict_vendor_t *vendor; - - if (pack->len + (vendor_name ? 8 : 2) + 4 >= REQ_LENGTH_MAX) - return -1; - - if (vendor_name) { - vendor = rad_dict_find_vendor_name(vendor_name); - if (!vendor) - return -1; - attr = rad_dict_find_vendor_attr(vendor, name); - } else { - vendor = NULL; - attr = rad_dict_find_attr(name); - } - - if (!attr) - return -1; - - ra = mempool_alloc(attr_pool); - if (!ra) - return -1; - - memset(ra, 0, sizeof(*ra)); - ra->vendor = vendor; - ra->attr = attr; - ra->len = 4; - ra->val.integer = val; - list_add_tail(&ra->entry, &pack->attrs); - pack->len += (vendor_name ? 8 : 2) + 4; - - return 0; -} - -int __export rad_packet_change_int(struct rad_packet_t *pack, const char *vendor_name, const char *name, int val) -{ - struct rad_attr_t *ra; - - ra = rad_packet_find_attr(pack, vendor_name, name); - if (!ra) - return -1; - - ra->val.integer = val; - - return 0; -} - -int __export rad_packet_add_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len) -{ - struct rad_attr_t *ra; - struct rad_dict_attr_t *attr; - struct rad_dict_vendor_t *vendor; - - if (pack->len + (vendor_name ? 8 : 2) + len >= REQ_LENGTH_MAX) - return -1; - - if (vendor_name) { - vendor = rad_dict_find_vendor_name(vendor_name); - if (!vendor) - return -1; - attr = rad_dict_find_vendor_attr(vendor, name); - } else { - vendor = NULL; - attr = rad_dict_find_attr(name); - } - - if (!attr) - return -1; - - ra = mempool_alloc(attr_pool); - if (!ra) { - log_emerg("radius: out of memory\n"); - return -1; - } - - memset(ra, 0, sizeof(*ra)); - ra->vendor = vendor; - ra->attr = attr; - ra->len = len; - ra->val.octets = _malloc(len); - if (!ra->val.octets) { - log_emerg("radius: out of memory\n"); - _free(ra); - return -1; - } - memcpy(ra->val.octets, val, len); - list_add_tail(&ra->entry, &pack->attrs); - pack->len += (vendor_name ? 8 : 2) + len; - - return 0; -} - -int __export rad_packet_change_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len) -{ - struct rad_attr_t *ra; - - ra = rad_packet_find_attr(pack, vendor_name, name); - if (!ra) - return -1; - - if (ra->len != len) { - if (pack->len - ra->len + len >= REQ_LENGTH_MAX) - return -1; - - ra->val.octets = _realloc(ra->val.octets, len); - if (!ra->val.octets) { - log_emerg("radius: out of memory\n"); - return -1; - } - - pack->len += len - ra->len; - ra->len = len; - } - - memcpy(ra->val.octets, val, len); - - return 0; -} - - -int __export rad_packet_add_str(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val) -{ - struct rad_attr_t *ra; - struct rad_dict_attr_t *attr; - struct rad_dict_vendor_t *vendor; - int len = strlen(val); - - if (pack->len + (vendor_name ? 8 : 2) + len >= REQ_LENGTH_MAX) - return -1; - - if (vendor_name) { - vendor = rad_dict_find_vendor_name(vendor_name); - if (!vendor) - return -1; - attr = rad_dict_find_vendor_attr(vendor, name); - } else { - vendor = NULL; - attr = rad_dict_find_attr(name); - } - - if (!attr) - return -1; - - ra = mempool_alloc(attr_pool); - if (!ra) { - log_emerg("radius: out of memory\n"); - return -1; - } - - memset(ra, 0, sizeof(*ra)); - ra->vendor = vendor; - ra->attr = attr; - ra->len = len; - ra->val.string = _malloc(len + 1); - if (!ra->val.string) { - log_emerg("radius: out of memory\n"); - _free(ra); - return -1; - } - memcpy(ra->val.string, val, len); - ra->val.string[len] = 0; - list_add_tail(&ra->entry, &pack->attrs); - pack->len += (vendor_name ? 8 : 2) + len; - - return 0; -} - -int __export rad_packet_change_str(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val, int len) -{ - struct rad_attr_t *ra; - - ra = rad_packet_find_attr(pack, vendor_name, name); - if (!ra) - return -1; - - if (ra->len != len) { - if (pack->len - ra->len + len >= REQ_LENGTH_MAX) - return -1; - - ra->val.string = _realloc(ra->val.string, len + 1); - if (!ra->val.string) { - log_emerg("radius: out of memory\n"); - return -1; - } - - pack->len += len - ra->len; - ra->len = len; - } - - memcpy(ra->val.string, val, len); - ra->val.string[len] = 0; - - return 0; -} - -int __export rad_packet_add_val(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val) -{ - struct rad_attr_t *ra; - struct rad_dict_attr_t *attr; - struct rad_dict_value_t *v; - struct rad_dict_vendor_t *vendor; - - if (pack->len + (vendor_name ? 8 : 2) + 4 >= REQ_LENGTH_MAX) - return -1; - - if (vendor_name) { - vendor = rad_dict_find_vendor_name(vendor_name); - if (!vendor) - return -1; - attr = rad_dict_find_vendor_attr(vendor, name); - } else { - vendor = NULL; - attr = rad_dict_find_attr(name); - } - - if (!attr) - return -1; - - v = rad_dict_find_val_name(attr, val); - if (!v) - return -1; - - ra = mempool_alloc(attr_pool); - if (!ra) - return -1; - - memset(ra, 0, sizeof(*ra)); - ra->vendor = vendor; - ra->attr = attr; - ra->len = 4; - ra->val = v->val; - list_add_tail(&ra->entry, &pack->attrs); - pack->len += (vendor_name ? 8 : 2) + 4; - - return 0; -} - -int __export rad_packet_change_val(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val) -{ - struct rad_attr_t *ra; - struct rad_dict_value_t *v; - - ra = rad_packet_find_attr(pack, vendor_name, name); - if (!ra) - return -1; - - v = rad_dict_find_val_name(ra->attr, val); - if (!v) - return -1; - - ra->val = v->val; - - return 0; -} - -int __export rad_packet_add_ipaddr(struct rad_packet_t *pack, const char *vendor_name, const char *name, in_addr_t ipaddr) -{ - return rad_packet_add_int(pack, vendor_name, name, ipaddr); -} - - -struct rad_attr_t __export *rad_packet_find_attr(struct rad_packet_t *pack, const char *vendor_name, const char *name) -{ - struct rad_attr_t *ra; - struct rad_dict_vendor_t *vendor; - - if (vendor_name) { - vendor = rad_dict_find_vendor_name(vendor_name); - if (!vendor) - return NULL; - } else - vendor = NULL; - - list_for_each_entry(ra, &pack->attrs, entry) { - if (vendor && vendor != ra->vendor) - continue; - - if (strcmp(ra->attr->name, name)) - continue; - - return ra; - } - - return NULL; -} - -int rad_packet_send(struct rad_packet_t *pack, int fd, struct sockaddr_in *addr) -{ - int n; - - while (1) { - if (addr) - n = sendto(fd, pack->buf, pack->len, 0, addr, sizeof(*addr)); - else - n = write(fd, pack->buf, pack->len); - if (n < 0) { - if (errno == EINTR) - continue; - log_ppp_error("radius:write: %s\n", strerror(errno)); - return -1; - } else if (n != pack->len) { - log_ppp_error("radius:write: short write %i, excpected %i\n", n, pack->len); - return -1; - } - break; - } - - return 0; -} - -static void __init init(void) -{ - attr_pool = mempool_create(sizeof(struct rad_attr_t)); - packet_pool = mempool_create(sizeof(struct rad_packet_t)); -} |