📄 rapi_lib.c
字号:
fltr = (API_FilterSpec *) resp->resp_flows; for (i = 0; i < resp->resp_nflwd; i++) { copy_filterspec_d2i(fltr, tapi_filt, eapi_filt); tapi_filt = (rapi_filter_t *) After_RAPIObj(tapi_filt); n_filter++; flow = (API_Flowspec *) After_APIObj(fltr); if (API_IsPath(resp)) {#ifdef USE_NET_BO NTOH_RAPIhdr(flow); if (ntoh_rapi_flowspec( &((API_TSpec *)flow)->tspecbody_IS) < 0) { rapi_errno = RAPI_ERR_INVAL; goto err_exit; }#endif /* USE_NET_BO */ copy_tspec_d2i((API_TSpec*)flow, (rapi_tspec_t *)tapi_spec, eapi_spec, sidp->flags&RAPI_USE_INTSERV); tapi_spec= (rapi_flowspec_t *) After_RAPIObj(tapi_spec); n_flowspec++; } else if (n_flowspec < 1) {#ifdef USE_NET_BO NTOH_RAPIhdr(flow); if (ntoh_rapi_flowspec(&flow->specbody_IS) < 0) { rapi_errno = RAPI_ERR_INVAL; goto err_exit; }#endif /* USE_NET_BO */ copy_flowspec_d2i(flow, tapi_spec, eapi_spec, sidp->flags&RAPI_USE_INTSERV); tapi_spec = (rapi_flowspec_t *) After_RAPIObj(tapi_spec); n_flowspec++; } fltr = (API_FilterSpec *) After_APIObj(flow); } if (API_IsPath(resp) && (char *)fltr - resp_buf < len){ /* * For path event, list of adspecs follows sender * descriptor list. (We make sure there really is * an adspec list, for backwards compatibility). */ size = (MAX_ADSPEC_LEN+sizeof(rapi_hdr_t)) * resp->resp_nflwd; api_adspec = malloc(size); if (api_adspec == NULL) { rapi_errno = RAPI_ERR_MEMFULL; goto err_exit; } eapi_adspp = (char *)api_adspec + size; tapi_adspp = api_adspec; adspp = (rapi_adspec_t *) fltr; for (i = 0; i < resp->resp_nflwd; i++) {#ifdef USE_NET_BO NTOH_RAPIhdr(adspp); if (ntoh_rapi_adspec(&adspp->adspecbody_IS) < 0) { rapi_errno = RAPI_ERR_INVAL; goto err_exit; }#endif /* USE_NET_BO */ copy_adspec_d2i(adspp, tapi_adspp, eapi_adspp, sidp->flags&RAPI_USE_INTSERV); if (adspp->form != RAPI_EMPTY_OTYPE) n_adspec++; /* Count non-empties */ adspp = (API_Adspec *)After_APIObj(adspp); tapi_adspp = (rapi_adspec_t *) After_RAPIObj(tapi_adspp); } /* If list contained only empty objects, pass 0 for n_adspec; * otherwise, pass resp_nflwd. */ if (n_adspec) n_adspec = resp->resp_nflwd; } if (n_filter == 0) { free(api_filter); api_filter = NULL; } if (n_flowspec == 0) { free(api_flowspec); api_flowspec = NULL; } if (n_adspec == 0) { if (api_adspec) free(api_adspec); api_adspec = NULL; } /* Invoke the client's upcall routine */ sockaddr_assign((struct sockaddr *) &enode,&resp->resp_errnode); if (sidp->event_rtn) (*(sidp->event_rtn)) ( (rapi_sid_t) resp->resp_a_sid, (rapi_eventinfo_t) resp->resp_type, resp->resp_style, resp->resp_errcode, resp->resp_errval, (struct sockaddr *)&enode, resp->resp_errflags, n_filter, api_filter, n_flowspec, api_flowspec, n_adspec, api_adspec, sidp->event_rtn_arg ); /* * Upon return, free malloc'd areas */err_exit: if (api_filter) free(api_filter); if (api_flowspec) free(api_flowspec); if (api_adspec) free(api_adspec); if (resp_buf) free(resp_buf); return (rapi_errno);}/* Scan a given list of N RAPI objects, and compute upper bound on * length after translation to API objects, for buffer allocation. */intList_Length(char *lcp, int N) { int i; int len = 0; for (i= 0; i < N; i++) { switch (((rapi_hdr_t *)lcp)->form) { case RAPI_EMPTY_OTYPE: break; case RAPI_FILTERFORM_BASE: len += sizeof(rapi_filter_base_t); break; case RAPI_FILTERFORM_GPI: len += sizeof(rapi_filter_gpi_t); break;#ifdef USE_IPV6 case RAPI_FILTERFORM_BASE6: len += sizeof(rapi_filter_base6_t); break; case RAPI_FILTERFORM_GPI6: len += sizeof(rapi_filter_gpi6_t); break;#endif /* USE_IPV6 */ case RAPI_FLOWSTYPE_Simplified: case RAPI_FLOWSTYPE_Intserv: /* IS: The Real Thing */ /* Use max Intserv flowspec size */ len += sizeof(IS_specbody_t); break; default: /* SHOULD NOT HAPPEN */ return -1; } len += sizeof(rapi_hdr_t); /* Common part */ lcp = After_RAPIObj(lcp); } return len;}char *copy_sender_desc( rapi_filter_t * i_filter, rapi_tspec_t * i_tspec, rapi_adspec_t * i_adspec, API_FlowDesc * flwdp, char * endp) { char *cp; if (!i_tspec) i_tspec = (rapi_tspec_t *) &Empty_APIObj; cp = copy_filterspec_i2d(i_filter, (API_FilterSpec *) flwdp, endp); if (!cp) return NULL; cp = copy_tspec_i2d(i_tspec, (API_TSpec *)cp, endp); if (i_adspec) cp = copy_adspec_i2d(i_adspec, (API_Adspec *)cp, endp); return cp;}voidsockaddr2filterbase(struct sockaddr *sockp, rapi_filter_t *filtp) { switch(sockp->sa_family) { case AF_INET: filtp->form = RAPI_FILTERFORM_BASE; filtp->len = sizeof(rapi_hdr_t) + sizeof(rapi_filter_base_t); filtp->rapi_filt4 = *(struct sockaddr_in *)sockp; break;#ifdef USE_IPV6 case AF_INET6: filtp->form = RAPI_FILTERFORM_BASE6; filtp->len = sizeof(rapi_hdr_t) + sizeof(rapi_filter_base6_t); filtp->rapi_filt6 = *(struct sockaddr_in6 *)sockp; break;#endif /* USE_IPV6 */ }}intvDstPort_OK(api_addr *addr, int flags) { if (!flags&RAPI_GPI_SESSION) /* We don't do any checking of dest port unless is IPSEC; * the spec says we MAY, but we don't have to. */ return(1); return(addr->port != 0);}/********************************************************************** * COPY-AND-TRANSLATE ROUTINES * * For flowspecs and adspecs, these routines may do serious translation, * since the API protocol assumes Intserv data structure bodies. * For filterspecs, these routines (currently) simply pass through the * RAPI/API object, except they convert byte order if needed. * **********************************************************************//* Translate flowspec from user interface format to daemon format, * checking type, length, and for overflow of req message. * Return ptr to next d_spec locn, or NULL if error. */static char *copy_flowspec_i2d(rapi_flowspec_t * i_spec, API_Flowspec * d_spec, char *endp) { int newL; char *next; switch (i_spec->form) { case RAPI_FLOWSTYPE_Simplified: /* * Simplifed: translate into proper Int-Serv format. */ newL = sizeof(IS_specbody_t)+sizeof(rapi_hdr_t); if ((char *)d_spec+ newL > endp) { rapi_errno = RAPI_ERR_OVERFLOW; return NULL; } if (RAPIObj_Size(i_spec) < sizeof(qos_flowspecx_t)+sizeof(rapi_hdr_t)) { rapi_errno = RAPI_ERR_OBJLEN; return NULL; } switch (i_spec->specbody_qosx.spec_type) { case QOS_GUARANTEEDX: CSZXtoG_spec(&i_spec->specbody_qosx, &d_spec->specbody_IS); break; case QOS_CNTR_LOAD: CSZXtoCL_spec(&i_spec->specbody_qosx, &d_spec->specbody_IS); break; default: rapi_errno = RAPI_ERR_INVAL; return NULL; } d_spec->form = RAPI_FLOWSTYPE_Intserv; d_spec->len = IS2RAPI_len(d_spec->specbody_IS.ISmh_len32b);#ifdef USE_NET_BO if (hton_rapi_flowspec(&d_spec->specbody_IS) < 0) { rapi_errno = RAPI_ERR_INVAL; return NULL; }#endif /* USE_NET_BO */ break; case RAPI_FLOWSTYPE_Intserv: newL = RAPIObj_Size(i_spec); if ((char *)d_spec + newL > endp) { rapi_errno = RAPI_ERR_OVERFLOW; return NULL; } /* Check length inside Intserv main header */ if (i_spec->specbody_IS.ISmh_len32b != RAPI2IS_len(newL)) { rapi_errno = RAPI_ERR_OBJLEN; return NULL; } memcpy((char *) d_spec, (char *) i_spec, newL);#ifdef USE_NET_BO if (hton_rapi_flowspec(&d_spec->specbody_IS) < 0) { rapi_errno = RAPI_ERR_INVAL; return NULL; }#endif /* USE_NET_BO */ break; case RAPI_EMPTY_OTYPE: if ((char *)d_spec + sizeof(Empty_RObj) > endp) { rapi_errno = RAPI_ERR_OVERFLOW; return NULL; } memcpy((char *)d_spec, (char *)&Empty_RObj, sizeof(Empty_RObj)); break; default: rapi_errno = RAPI_ERR_OBJTYPE; return NULL; } next = After_RAPIObj(d_spec);#ifdef USE_NET_BO HTON_RAPIhdr(d_spec);#endif /* USE_NET_BO */ return (next);}/* Translate Tspec from user interface format to daemon format, * checking type, length, and for overflow of req message. * Return ptr to next d_spec locn, or NULL if error. */static char *copy_tspec_i2d(rapi_tspec_t * i_spec, API_TSpec * d_spec, char *endp) { int printf(); char *next; if ((char *)d_spec + sizeof(rapi_tspec_t) > endp) { rapi_errno = RAPI_ERR_OVERFLOW; return NULL; } switch (i_spec->form) { case RAPI_FLOWSTYPE_Simplified: printf("Obsolete Tspec form: should be RAPI_TSPECTYPE_Simplified\n"); case RAPI_TSPECTYPE_Simplified: /* * Simplified format: translate into proper Intserv * format. In this case, don't have to supply any values. */ if (RAPIObj_Size(i_spec) < sizeof(qos_tspecx_t)+sizeof(rapi_hdr_t)) { rapi_errno = RAPI_ERR_OBJLEN; return NULL; } switch (i_spec->tspecbody_qosx.spec_type) { case QOS_GUARANTEEDX: case QOS_CNTR_LOAD: case QOS_TSPECX: /* -> Generic Tspec */ CSZXtoGen_tspec(&i_spec->tspecbody_qosx, &d_spec->tspecbody_IS); break; default: rapi_errno = RAPI_ERR_INVAL; return NULL; } d_spec->form = RAPI_TSPECTYPE_Intserv; d_spec->len =IS2RAPI_len(d_spec->tspecbody_IS.IStmh_len32b);#ifdef USE_NET_BO if (hton_rapi_flowspec(&d_spec->tspecbody_IS) < 0) { rapi_errno = RAPI_ERR_INVAL; return NULL; }#endif /* USE_NET_BO */ break; case RAPI_TSPECTYPE_Intserv: /* Set length in Intserv flowspec header */ if (RAPIObj_Size(i_spec) < sizeof(rapi_tspec_t)) { rapi_errno = RAPI_ERR_OBJLEN; return NULL; } i_spec->tspecbody_IS.IStmh_len32b = RAPI2IS_len(RAPIObj_Size(i_spec)); memcpy((char *) d_spec, (char *) i_spec, RAPIObj_Size(i_spec));#ifdef USE_NET_BO if (hton_rapi_flowspec(&d_spec->tspecbody_IS) < 0) { rapi_errno = RAPI_ERR_INVAL; return NULL; }#endif /* USE_NET_BO */ break; case RAPI_EMPTY_OTYPE: memcpy((char *)d_spec, (char *)&Empty_RObj, sizeof(Empty_RObj)); break; default: rapi_errno = RAPI_ERR_OBJTYPE; return NULL; } next = After_RAPIObj(d_spec);#ifdef USE_NET_BO HTON_RAPIhdr(d_spec);#endif /* USE_NET_BO */ return ( next );}/* Copy adspec and convert to Intserv format with RAPI framing. * Sets rapi_errno and returns NULL if it fails. */static char *copy_adspec_i2d(rapi_adspec_t *i_adsp, API_Adspec *d_adsp, char *endp) { char *next; switch (i_adsp->form) { case RAPI_ADSTYPE_Simplified: if ((char *)d_adsp + MAX_ADSPEC_LEN > endp) { rapi_errno = RAPI_ERR_OVERFLOW; return NULL; } if (CSZXtoIS_adspec(&i_adsp->adspecbody_qosx, &d_adsp->adspecbody_IS)) return NULL; d_adsp->form = RAPI_ADSTYPE_Intserv; d_adsp->len = IS2RAPI_len(d_adsp->adspecbody_IS.adspec_mh.ismh_len32b);#ifdef USE_NET_BO if (hton_rapi_adspec(&d_adsp->adspecbody_IS) < 0) { rapi_errno = RAPI_ERR_INVAL; return NULL; }#endif /* USE_NET_BO */ break; case RAPI_FLOWSTYPE_Intserv: /* Set length in Intserv flowspec header */ if (RAPIObj_Size(i_adsp) > MAX_ADSPEC_LEN) { rapi_errno = RAPI_ERR_OVERFLOW; return NULL; } i_adsp->adspecbody_IS.adspec_mh.ismh_len32b = RAPI2IS_len(RAPIObj_Size(i_adsp)); memcpy((char *) d_adsp, (char *) i_adsp, RAPIObj_Size(i_adsp));#ifdef USE_NET_BO if (hton_rapi_adspec(&d_adsp->adspecbody_IS) < 0) { rapi_errno = RAPI_ERR_INVAL; return NULL; }#endif /* USE_NET_BO */ break; case RAPI_EMPTY_OTYPE: memcpy((char *)d_adsp, (char *)&Empty_RObj, sizeof(Empty_RObj)); break; default: rapi_errno = RAPI_ERR_OBJTYPE; return NULL; } next = After_RAPIObj(d_adsp);#ifdef USE_NET_BO HTON_RAPIhdr(d_adsp);#endif /* USE_NET_BO */ return next;}/* * Copy and convert RAPI-format filter spec into daemon format. */static char *copy_filterspec_i2d(rapi_filter_t * i_filter, API_FilterSpec * d_filter, char *endp) { int newL; char *next; switch (i_filter->form) { case RAPI_FILTERFORM_BASE: newL = sizeof(rapi_filter_base_t)+sizeof(rapi_hdr_t); break; case RAPI_FILTERFORM_GPI: newL = sizeof(rapi_filter_gpi_t)+sizeof(rapi_hdr_t); break;#ifdef USE_IPV6 case RAPI_FILTERFORM_BASE6: newL = sizeof(rapi_filter_base6_t)+sizeof(rapi_hdr_t); break; case RAPI_FILTERFORM_GPI6: newL = sizeof(rapi_filter_gpi6_t)+sizeof(rapi_hdr_t); break;#endif /* USE_IPV6 */ case RAPI_EMPTY_OTYPE: newL = sizeof(rapi_hdr_t); break; default: rapi_errno = RAPI_ERR_OBJTYPE; return NULL; } if (RAPIObj_Size(i_filter) != newL) { rapi_errno = RAPI_ERR_OBJLEN; return NULL; } if ((char *)d_filter + RAPIObj_Size(i_filter) > endp) { rapi_errno = RAPI_ERR_OVERFLOW; return NULL; } memcpy((char *) d_filter, (char *) i_filter, RAPIObj_Size(i_filter)); next = After_RAPIObj(d_filter);#ifdef USE_NET_BO HTON_RAPIhdr(d_filter);#endif /* USE_NET_BO */ return (next);}/* Translate from daemon format to user interface format, checking * for overflow of upcall area. Sets rapi_errno and returns -1 if * error, else returns zero. */static intcopy_flowspec_d2i(API_Flowspec * d_spec, rapi_flowspec_t * i_spec, char *endp, int Use_Intserv)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -