📄 aspath.c
字号:
*/struct asnum *asnumcpy(asn, len) struct asnum *asn; int len;{ struct asnum *cpy = NULL, *cpy2, *src; int i; /* by jinmei */ if ((src = asn)) cpy = bgp_new_asnum(src->asn_num); for (i = 1; i < len ; i++) { src = src->asn_next; cpy2 = bgp_new_asnum(src->asn_num); insque(cpy2, cpy); cpy = cpy2; } return cpy->asn_next;}/* * bgp_new_asseg() * DESCRIPTION: segment Type is not set. */struct asseg *bgp_new_asseg(an) u_int16_t an;{ struct asseg *asg; MALLOC(asg, struct asseg); asg->asg_next = asg->asg_prev = asg; asg->asg_len = 1; asg->asg_asn = bgp_new_asnum(an); return asg;}/* * bgp_new_asnum() */struct asnum *bgp_new_asnum(an) u_int16_t an;{ struct asnum *asn; MALLOC(asn, struct asnum); asn->asn_next = asn->asn_prev = asn; asn->asn_num = an; return asn;}/* * equal_asseg() * RETURN VALUE: 1 or 0 * NOTE: AS numbers are assumed to be already sorted by their AS number */intequal_asseg(asg1, asg2) struct asseg *asg1; struct asseg *asg2;{ struct asnum *asn1, *asn2; int i; if (asg1 == NULL && asg2 == NULL) /* both are empty AS PATH */ return 1; else if (!asg1 || !asg2) /* one is empty but the other not */ return 0; if (asg1->asg_type != asg2->asg_type || asg1->asg_len != asg2->asg_len) return 0; switch (asg1->asg_type) { case PA_PATH_SET: case PA_PATH_SEQ: asn1 = asg1->asg_asn; asn2 = asg2->asg_asn; for(i = 0; i < asg1->asg_type; i++) { if (asn1->asn_num != asn2->asn_num) return 0; asn1 = asn1->asn_next; asn2 = asn2->asn_next; } return 1; break; default: fatalx("<equal_asseg>: unknown AS Segment Type"); return 0; break; }}/* * equal_aspath() * RETURN VALUE: 1 : equal * 0 : not equal * */intequal_aspath(asp1, asp2) struct aspath *asp1; struct aspath *asp2;{ struct asseg *asg1, *asg2; int i; if (asp1 == NULL && asp2 == NULL) return 1; if (!asp1 || !asp2) return 0; if (asp1->asp_len != asp2->asp_len) return 0; asg1 = asp1->asp_segment; asg2 = asp2->asp_segment; for (i = 0; i < asp1->asp_len; i++) { if (!equal_asseg(asg1, asg2)) return 0; asg1 = asg1->asg_next; asg2 = asg2->asg_next; } if (asp1->asp_origin != asp2->asp_origin || asp1->asp_atomagg != asp2->asp_atomagg ) return 0; return 1; /* equal */}/* * aspath2cost() * RETURN VALUES: >= 0 */u_charaspath2cost(asp) struct aspath *asp;{ struct asseg *asg; u_char cost; int i; if (asp == NULL) return 0; if ((asg = asp->asp_segment) == NULL) /* empty AS path */ return 0; /* appropriate cost?? */ cost = 1; for(i = 0; i < asp->asp_len ; i++) { switch (asg->asg_type) { case PA_PATH_SET: cost++; break; case PA_PATH_SEQ: cost += asg->asg_len; break; default: fatalx("<aspath2cost>: BUG !"); break; } asg = asg->asg_next; } return cost;}/* * aspath2tag() * RETURN VALUES: */u_int16_taspath2tag(asp) struct aspath *asp;{ if (asp == NULL) return 0; if (!(asp->asp_segment && asp->asp_segment->asg_asn)) return 0; return (asp->asp_segment->asg_asn->asn_num);}/* * prepend_clstrlist() */struct clstrlist *prepend_clstrlist(id, cllist) u_int32_t id; /* host byte order */ struct clstrlist *cllist;{ struct clstrlist *cllh, *cllt; if (cllist == NULL) { cllh = bgp_new_clstrlist(id); return cllh; } cllt = clstrlistcpy(cllist); cllh = bgp_new_clstrlist(id); insque(cllh, cllt->cll_prev); return cllh;}/* * clstrlistcpy() */struct clstrlist *clstrlistcpy(cll) struct clstrlist *cll;{ struct clstrlist *cpy, *cpy2, *src; if (cll == NULL) return NULL; src = cll; cpy = bgp_new_clstrlist(src->cll_id); while (src->cll_next != cll) { src = src->cll_next; cpy2 = bgp_new_clstrlist(src->cll_id); insque(cpy2, cpy); cpy = cpy2; } return cpy->cll_next;} /* * msg2clstrlist() * DESCRIPTION: compose an CLUSTER_LIST structure, from incoming msg. * * RETURN VALUES: Pointer to clstrlist: normally. * NULL: If the msg is invalid, or, * a loop is detected. * [rfc1966] * Using this attribute an RR can identify if the routing information is * looped back to the same cluster due to mis-configuration. If the local * CLUSTER_ID is found in the cluster-list, the advertisement will be ignored. */struct clstrlist *msg2clstrlist(bnp, i, len) struct rpcb *bnp; int i; /* tracer */ int len; /* data length in octets */{ struct clstrlist *cllhead, *cll; int j, l; int bufwlen; char buf[LINE_MAX]; /* debugging */ extern u_int32_t clusterId; extern byte IamRR; if (len == 0) return NULL; l = 0; memset(buf, 0, LINE_MAX); cllhead = cll = NULL; j = i; while (1){ MALLOC(cll, struct clstrlist); memcpy((char *)&cll->cll_id, &bnp->rp_inpkt[j], PA_LEN_CLUSTER); bufwlen = sprintf(&buf[l], "%u ", cll->cll_id); l += bufwlen; if (IamRR && clusterId != 0 && /* global */ clusterId == cll->cll_id) { /* loop detection */ syslog(LOG_NOTICE, "<%s>: Cluster-list loop detected: %s from %s", __FUNCTION__, buf, bgp_peerstr(bnp)); free_clstrlist(cll); return NULL; } if (cllhead) { insque(cll, cllhead->cll_prev); } else { cll->cll_next = cll; cll->cll_prev = cll; cllhead = cll; } if ((j += PA_LEN_CLUSTER) >= len) break; } if ((logflags & LOG_ASPATH) != 0) syslog(LOG_DEBUG, "BGP+ RECV\t\t%s", buf); return cllhead; }/* * clstrlist2msg() * DESCRIPTION: compose a part of message, from an clstrlist strcuture. * * RETURN VALUES: composed length (i.e. "data length") */intclstrlist2msg(cll, i) struct clstrlist *cll; int i; /* tracer */{ struct clstrlist *icll; int j; /* tracer (local) */ int l, bufwlen; char buf[LINE_MAX]; /* debugging */ extern byte outpkt[]; l = 0; memset(buf, 0, LINE_MAX); j = i; if (cll == NULL) return 0; icll = cll; while(1) { memcpy(&outpkt[j], &icll->cll_id, PA_LEN_CLUSTER); bufwlen = sprintf(&buf[l], "%u ", icll->cll_id); l += bufwlen; j += PA_LEN_CLUSTER; if ((icll = icll->cll_next) == cll) break; } if ((logflags & LOG_ASPATH) != 0) syslog(LOG_DEBUG, "BGP+ SEND\t\t%s", buf); if (j - i > 0xff) fatalx("<clstrlist2msg>: Too long CLUSTER_LIST"); return (j - i); /* composed length */}/* * bgp_new_clstrlist() */struct clstrlist *bgp_new_clstrlist(id) u_int32_t id;{ struct clstrlist *cll; MALLOC(cll, struct clstrlist); cll->cll_next = cll; cll->cll_prev = cll; cll->cll_id = id; return cll;}/* * free_clstrlist() */voidfree_clstrlist(cll) struct clstrlist *cll;{ struct clstrlist *fcll; if (cll == NULL) return; if (cll->cll_next == NULL) { free(cll); return; } while (1) { if ((fcll = cll->cll_next) && /* changed */ fcll != cll ) { remque(fcll); free(fcll); } else { break; } } free(cll); return;}struct optatr *add_optatr(optatr, optdata, len) struct optatr *optatr; char *optdata; int len;{ struct optatr *newoptatr; /* allocate memory */ MALLOC(newoptatr, struct optatr); if ((newoptatr->data = malloc(len)) == NULL) { syslog(LOG_ERR, "<%s> malloc failed(size %d)", __FUNCTION__, len); fatalx("malloc"); } /* set values */ newoptatr->len = len; memcpy(newoptatr->data, optdata, len); /* link into the chain */ newoptatr->next = optatr; return(newoptatr);}struct optatr *copy_optatr_list(src) struct optatr *src;{ struct optatr *dst = NULL; for(; src; src = src->next) dst = add_optatr(dst, src->data, src->len); return(dst);}voidfree_optatr_list(optatr) struct optatr *optatr;{ struct optatr *next = NULL; while(optatr) { next = optatr->next; free(optatr->data); free(optatr); optatr = next; } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -