📄 avp.c
字号:
log (LOG_DEBUG, "%s: avp is wrong size. %d != 8\n", __FUNCTION__, datalen); wrong_length (c, "Assigned Call ID", 8, datalen, 0); return -EINVAL; } }#endif c->ppd = ntohs (raw[3]); if (debug_avp) { if (DEBUG) log (LOG_DEBUG, "%s: peer's delay is %d 1/10's of a second\n", __FUNCTION__, ntohs (raw[3])); } return 0;}int call_serno_avp (struct tunnel *t, struct call *c, void *data, int datalen){ /* * What is the serial number of the call? */ _u16 *raw = data;#ifdef SANITY if (t->sanity) { switch (c->msgtype) { case ICRQ: case OCRQ: break; default: if (DEBUG) log (LOG_DEBUG, "%s: call ID not appropriate for message %s. Ignoring.\n", __FUNCTION__, msgtypes[c->msgtype]); return 0; } if (datalen != 10) {#ifdef STRICT if (DEBUG) log (LOG_DEBUG, "%s: avp is wrong size. %d != 10\n", __FUNCTION__, datalen); wrong_length (c, "Serial Number", 10, datalen, 0); return -EINVAL;#else log (LOG_DEBUG, "%s: peer is using old style serial number. Will be invalid.\n", __FUNCTION__);#endif } }#endif t->call_head->serno = (((unsigned int) ntohs (raw[3])) << 16) | ((unsigned int) ntohs (raw[4])); if (debug_avp) { if (DEBUG) log (LOG_DEBUG, "%s: serial number is %d\n", __FUNCTION__, t->call_head->serno); } return 0;}int rx_speed_avp (struct tunnel *t, struct call *c, void *data, int datalen){ /* * What is the received baud rate of the call? */ _u16 *raw = data;#ifdef SANITY if (t->sanity) { switch (c->msgtype) { case ICCN: case OCCN: case OCRP: break; default: if (DEBUG) log (LOG_DEBUG, "%s: rx connect speed not appropriate for message %s. Ignoring.\n", __FUNCTION__, msgtypes[c->msgtype]); return 0; } if (datalen != 10) { if (DEBUG) log (LOG_DEBUG, "%s: avp is wrong size. %d != 10\n", __FUNCTION__, datalen); wrong_length (c, "Connect Speed (RX)", 10, datalen, 0); return -EINVAL; } }#endif c->rxspeed = (((unsigned int) ntohs (raw[3])) << 16) | ((unsigned int) ntohs (raw[4])); if (debug_avp) { if (DEBUG) log (LOG_DEBUG, "%s: receive baud rate is %d\n", __FUNCTION__, c->rxspeed); } return 0;}int tx_speed_avp (struct tunnel *t, struct call *c, void *data, int datalen){ /* * What is the tranmsit baud rate of the call? */ _u16 *raw = data;#ifdef SANITY if (t->sanity) { switch (c->msgtype) { case ICCN: case OCCN: case OCRP: break; default: if (DEBUG) log (LOG_DEBUG, "%s: tx connect speed not appropriate for message %s. Ignoring.\n", __FUNCTION__, msgtypes[c->msgtype]); return 0; } if (datalen != 10) { if (DEBUG) log (LOG_DEBUG, "%s: avp is wrong size. %d != 10\n", __FUNCTION__, datalen); wrong_length (c, "Connect Speed (tx)", 10, datalen, 0); return -EINVAL; } }#endif c->txspeed = (((unsigned int) ntohs (raw[3])) << 16) | ((unsigned int) ntohs (raw[4])); if (debug_avp) { if (DEBUG) log (LOG_DEBUG, "%s: transmit baud rate is %d\n", __FUNCTION__, c->txspeed); } return 0;}int call_physchan_avp (struct tunnel *t, struct call *c, void *data, int datalen){ /* * What is the physical channel? */ _u16 *raw = data;#ifdef SANITY if (t->sanity) { switch (c->msgtype) { case ICRQ: case OCRQ: case OCRP: case OCCN: break; default: if (DEBUG) log (LOG_DEBUG, "%s: physical channel not appropriate for message %s. Ignoring.\n", __FUNCTION__, msgtypes[c->msgtype]); return 0; } if (datalen != 10) { if (DEBUG) log (LOG_DEBUG, "%s: avp is wrong size. %d != 10\n", __FUNCTION__, datalen); wrong_length (c, "Physical Channel", 10, datalen, 0); return -EINVAL; } }#endif t->call_head->physchan = (((unsigned int) ntohs (raw[3])) << 16) | ((unsigned int) ntohs (raw[4])); if (debug_avp) { if (DEBUG) log (LOG_DEBUG, "%s: physical channel is %d\n", __FUNCTION__, t->call_head->physchan); } return 0;}int receive_window_size_avp (struct tunnel *t, struct call *c, void *data, int datalen){ /* * What is their RWS? */ _u16 *raw = data;#ifdef SANITY if (t->sanity) { switch (c->msgtype) { case SCCRP: case SCCRQ: case OCRP: /* jz */ case OCCN: /* jz */ case StopCCN:/* case ICRP: case ICCN: */ break; default: if (DEBUG) log (LOG_DEBUG, "%s: RWS not appropriate for message %s. Ignoring.\n", __FUNCTION__, msgtypes[c->msgtype]); return 0; } if (datalen != 8) { if (DEBUG) log (LOG_DEBUG, "%s: avp is wrong size. %d != 8\n", __FUNCTION__, datalen); wrong_length (c, "Receive Window Size", 8, datalen, 0); return -EINVAL; } }#endif t->rws = ntohs (raw[3]);/* if (c->rws >= 0) c->fbit = FBIT; */ if (debug_avp) { if (DEBUG) log (LOG_DEBUG, "%s: peer wants RWS of %d. Will use flow control.\n", __FUNCTION__, t->rws); } return 0;}int handle_avps (struct buffer *buf, struct tunnel *t, struct call *c){ /* * buf's start should point to the beginning of a packet. We assume it's * a valid packet and has had check_control done to it, so no error * checking is done at this point. */ struct avp_hdr *avp; int len = buf->len - sizeof (struct control_hdr); int firstavp = -1; int hidlen; char *data = buf->start + sizeof (struct control_hdr); avp = (struct avp_hdr *) data; if (debug_avp) log (LOG_DEBUG, "%s: handling avp's for tunnel %d, call %d\n", __FUNCTION__, t->ourtid, c->ourcid); while (len > 0) { /* Go ahead and byte-swap the header */ swaps (avp, sizeof (struct avp_hdr)); if (avp->attr > AVP_MAX) { if (AMBIT (avp->length)) { log (LOG_WARN, "%s: dont know how to handle mandatory attribute %d. Closing %s.\n" __FUNCTION__, avp->attr, (c != t->self) ? "call" : "tunnel"); set_error (c, VENDOR_ERROR, "mandatory attribute %d cannot be handled", avp->attr); c->needclose = -1; return -EINVAL; } else { if (DEBUG) log (LOG_WARN, "%s: dont know how to handle atribute %d.\n", __FUNCTION__, avp->attr); goto next; } } if (ALENGTH (avp->length) > len) { log (LOG_WARN, "%s: AVP received with length > remaining packet length!\n", __FUNCTION__); set_error (c, ERROR_LENGTH, "Invalid AVP length"); c->needclose = -1; return -EINVAL; } if (avp->attr && firstavp) { log (LOG_WARN, "%s: First AVP was not message type.\n", __FUNCTION__); set_error (c, VENDOR_ERROR, "First AVP must be message type"); c->needclose = -1; return -EINVAL; } if (ALENGTH (avp->length) < sizeof (struct avp_hdr)) { log (LOG_WARN, "%s: AVP with too small of size (%d).\n", __FUNCTION__, ALENGTH (avp->length)); set_error (c, ERROR_LENGTH, "AVP too small"); c->needclose = -1; return -EINVAL; } if (AZBITS (avp->length)) { log (LOG_WARN, "%s: %sAVP has reserved bits set.\n", __FUNCTION__, AMBIT (avp->length) ? "Mandatory " : ""); if (AMBIT (avp->length)) { set_error (c, ERROR_RESERVED, "reserved bits set in AVP"); c->needclose = -1; return -EINVAL; } goto next; } if (AHBIT (avp->length)) {#ifdef DEBUG_HIDDEN log (LOG_DEBUG, "%s: Hidden bit set on AVP.\n", __FUNCTION__);#endif /* We want to rewrite the AVP as an unhidden AVP and then pass it along as normal. Remeber how long the AVP was in the first place though! */ hidlen = avp->length; if (decrypt_avp (data, t)) { if (debug_avp) log (LOG_WARN, "%s: Unable to handle hidden %sAVP\n:", __FUNCTION__, (AMBIT (avp->length) ? "mandatory " : "")); if (AMBIT (avp->length)) { set_error (c, VENDOR_ERROR, "Invalid Hidden AVP"); c->needclose = -1; return -EINVAL; } goto next; }; len -= 2; hidlen -= 2; data += 2; avp = (struct avp_hdr *) data; /* Now we should look like a normal AVP */ } else hidlen = 0; if (avps[avp->attr].handler) { if (avps[avp->attr].handler (t, c, avp, ALENGTH (avp->length))) { if (AMBIT (avp->length)) { log (LOG_WARN, "%s: Bad exit status handling attribute %d (%s) on mandatory packet.\n", __FUNCTION__, avp->attr, avps[avp->attr].description); c->needclose = -1; return -EINVAL; } else { if (DEBUG) log (LOG_DEBUG, "%s: Bad exit status handling attribute %d (%s).\n", __FUNCTION__, avp->attr, avps[avp->attr].description); } } } else { if (AMBIT (avp->length)) { log (LOG_WARN, "%s: No handler for mandatory attribute %d (%s). Closing %s.\n", __FUNCTION__, avp->attr, avps[avp->attr].description, (c != t->self) ? "call" : "tunnel"); set_error (c, VENDOR_ERROR, "No handler for attr %d (%s)\n", avp->attr, avps[avp->attr].description); return -EINVAL; } else { if (DEBUG) log (LOG_WARN, "%s: no handler for atribute %d (%s).\n", __FUNCTION__, avp->attr, avps[avp->attr].description); } } next: if (hidlen) { /* Skip over the complete length of the hidden AVP */ len -= ALENGTH (hidlen); data += ALENGTH (hidlen); } else { len -= ALENGTH (avp->length); data += ALENGTH (avp->length); /* Next AVP, please */ } avp = (struct avp_hdr *) data; firstavp = 0; } if (len != 0) { log (LOG_WARN, "%s: negative overall packet length\n", __FUNCTION__); return -EINVAL; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -