📄 sctp_t.c
字号:
if ( ops->init ) { len += olen; } if ( ops->hbitvl ) { len += olen; } if ( ops->rtoinit ) { len += olen; } if ( ops->rtomin ) { len += olen; } if ( ops->rtomax ) { len += olen; } if ( ops->ostr ) { len += olen; } if ( ops->istr ) { len += olen; } if ( ops->ckinc ) { len += olen; } if ( ops->titvl ) { len += olen; } if ( ops->hmac ) { len += olen; } if ( ops->mseg ) { len += olen; } if ( ops->debug ) { len += olen; } if ( ops->hb ) { len += ops->hb->len; } if ( ops->rto ) { len += ops->rto->len; } if ( ops->status ) { len += ops->status->len; } return(len);}static void sctp_build_set_opts(sctp_t *sp, sctp_opts_t *ops, unsigned char **p){ struct t_opthdr *oh; const size_t hlen = sizeof(*oh); const size_t olen = hlen + sizeof(t_scalar_t); if ( ops->bcast ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_IP; oh->name = T_IP_BROADCAST; oh->status = ops->flags & TF_IP_BROADCAST ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->bcast+1)); } if ( ops->norte ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_IP; oh->name = T_IP_DONTROUTE; oh->status = ops->flags & TF_IP_DONTROUTE ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->norte+1)); } if ( ops->opts ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_IP; oh->name = T_IP_OPTIONS; oh->status = ops->flags & TF_IP_OPTIONS ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->opts+1)); } if ( ops->reuse ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_IP; oh->name = T_IP_REUSEADDR; oh->status = ops->flags & TF_IP_REUSEADDR ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->reuse+1)); } if ( ops->tos ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_IP; oh->name = T_IP_TOS; oh->status = ops->flags & TF_IP_TOS ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->tos+1)); } if ( ops->ttl ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_IP; oh->name = T_IP_TTL; oh->status = ops->flags & TF_IP_TTL ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->ttl+1)); } if ( ops->nd ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_NODELAY; oh->status = ops->flags & TF_SCTP_NODELAY ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->nd+1)); } if ( ops->cork ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_CORK; oh->status = ops->flags & TF_SCTP_CORK ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->cork+1)); } if ( ops->ppi ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_PPI; oh->status = ops->flags & TF_SCTP_PPI ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->ppi+1)); } if ( ops->sid ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_SID; oh->status = ops->flags & TF_SCTP_SID ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->sid+1)); } if ( ops->ssn ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_SSN; oh->status = ops->flags & TF_SCTP_SSN ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->ssn+1)); } if ( ops->tsn ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_TSN; oh->status = ops->flags & TF_SCTP_TSN ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->tsn+1)); } if ( ops->ropt ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_RECVOPT; oh->status = ops->flags & TF_SCTP_RECVOPT ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->ropt+1)); } if ( ops->cklife ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_COOKIE_LIFE; oh->status = ops->flags & TF_SCTP_COOKIE_LIFE ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->cklife+1)); } if ( ops->sack ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_SACK_DELAY; oh->status = ops->flags & TF_SCTP_SACK_DELAY ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->sack+1)); } if ( ops->path ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_PATH_MAX_RETRANS; oh->status = ops->flags & TF_SCTP_PATH_MAX_RETRANS ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->path+1)); } if ( ops->assoc ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_ASSOC_MAX_RETRANS; oh->status = ops->flags & TF_SCTP_ASSOC_MAX_RETRANS ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->assoc+1)); } if ( ops->init ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_MAX_INIT_RETRIES; oh->status = ops->flags & TF_SCTP_MAX_INIT_RETRIES ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->init+1)); } if ( ops->hbitvl ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_HEARTBEAT_ITVL; oh->status = ops->flags & TF_SCTP_HEARTBEAT_ITVL ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->hbitvl+1)); } if ( ops->rtoinit ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_RTO_INITIAL; oh->status = ops->flags & TF_SCTP_RTO_INITIAL ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->rtoinit+1)); } if ( ops->rtomin ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_RTO_MIN; oh->status = ops->flags & TF_SCTP_RTO_MIN ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->rtomin+1)); } if ( ops->rtomax ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_RTO_MAX; oh->status = ops->flags & TF_SCTP_RTO_MAX ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->rtomax+1)); } if ( ops->ostr ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_OSTREAMS; oh->status = ops->flags & TF_SCTP_OSTREAMS ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->ostr+1)); } if ( ops->istr ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_ISTREAMS; oh->status = ops->flags & TF_SCTP_ISTREAMS ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->istr+1)); } if ( ops->ckinc ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_COOKIE_INC; oh->status = ops->flags & TF_SCTP_COOKIE_INC ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->ckinc+1)); } if ( ops->titvl ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_THROTTLE_ITVL; oh->status = ops->flags & TF_SCTP_THROTTLE_ITVL ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->titvl+1)); } if ( ops->hmac ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_MAC_TYPE; oh->status = ops->flags & TF_SCTP_MAC_TYPE ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->hmac+1)); } if ( ops->mseg ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_MAXSEG; oh->status = ops->flags & TF_SCTP_MAXSEG ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->mseg+1)); } if ( ops->debug ) { oh = ((struct t_opthdr *)*p)++; oh->len = olen; oh->level = T_INET_SCTP; oh->name = T_SCTP_DEBUG; oh->status = ops->flags & TF_SCTP_DEBUG ? T_SUCCESS : T_FAILURE; *((t_scalar_t *)*p)++ = *((t_scalar_t *)(ops->debug+1)); } if ( ops->hb ) { oh = ((struct t_opthdr *)*p)++; oh->len = ops->hb->len; oh->level = T_INET_SCTP; oh->name = T_SCTP_HB; oh->status = ops->flags & TF_SCTP_HB ? T_SUCCESS : T_FAILURE; bcopy(ops->hb+1, *p, ops->hb->len - sizeof(*oh)); *p += ops->hb->len - sizeof(*oh); } if ( ops->rto ) { oh = ((struct t_opthdr *)*p)++; oh->len = ops->rto->len; oh->level = T_INET_SCTP; oh->name = T_SCTP_RTO; oh->status = ops->flags & TF_SCTP_RTO ? T_SUCCESS : T_FAILURE; bcopy(ops->rto+1, *p, ops->rto->len - sizeof(*oh)); *p += ops->rto->len - sizeof(*oh); } if ( ops->status ) { oh = ((struct t_opthdr *)*p)++; oh->len = ops->status->len; oh->level = T_INET_SCTP; oh->name = T_SCTP_STATUS; oh->status = ops->flags & TF_SCTP_STATUS ? T_SUCCESS : T_FAILURE; bcopy(ops->status+1, *p, ops->status->len - sizeof(*oh)); *p += ops->status->len - sizeof(*oh); }}/* * Size and Build options. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static size_t sctp_opts_size(ulong flags, sctp_t *sp, sctp_opts_t *ops){ switch ( flags ) { case T_CHECK: case T_NEGOTIATE: if ( ops ) return sctp_set_opts_size(sp, ops); case T_DEFAULT: return sctp_default_opts_size(sp, ops); case T_CURRENT: return sctp_current_opts_size(sp, ops); } return(0);}static void sctp_build_opts(ulong flags, sctp_t *sp, sctp_opts_t *ops, unsigned char **p){ switch ( flags ) { case T_CHECK: case T_NEGOTIATE: if ( ops ) return sctp_build_set_opts(sp, ops, p); case T_DEFAULT: return sctp_build_default_opts(sp, ops, p); case T_CURRENT: return sctp_build_current_opts(sp, ops, p); } return;}/* * Parse options * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static int sctp_parse_opts(sctp_opts_t *ops, unsigned char *opt_ptr, size_t opt_len){ struct t_opthdr *oh = (struct t_opthdr *)opt_ptr; unsigned char *opt_end = opt_ptr + opt_len; for ( ; opt_ptr + sizeof(*oh) <= opt_end && oh->len >= sizeof(*oh) && opt_ptr + oh->len <= opt_end; opt_ptr += oh->len, oh = (struct t_opthdr *)opt_ptr ) { switch ( oh->level ) { case T_INET_IP: switch ( oh->name ) { case T_IP_BROADCAST: ops->bcast = oh; continue; case T_IP_DONTROUTE: ops->norte = oh; continue; case T_IP_OPTIONS: ops->opts = oh; continue; case T_IP_REUSEADDR: ops->reuse = oh; continue; case T_IP_TOS: ops->tos = oh; continue; case T_IP_TTL: ops->ttl = oh; continue; } break; case T_INET_SCTP: switch ( oh->name ) { case T_SCTP_NODELAY: ops->nd = oh; continue; case T_SCTP_CORK: ops->cork = oh; continue; case T_SCTP_PPI: ops->ppi = oh; continue; case T_SCTP_SID: ops->sid = oh; continue; case T_SCTP_SSN: ops->ssn = oh; continue; case T_SCTP_TSN: ops->tsn = oh; continue; case T_SCTP_RECVOPT: ops->ropt = oh; continue; case T_SCTP_COOKIE_LIFE: ops->cklife = oh; continue; case T_SCTP_SACK_DELAY: ops->sack = oh; continue; case T_SCTP_PATH_MAX_RETRANS: ops->path = oh; continue; case T_SCTP_ASSOC_MAX_RETRANS: ops->assoc = oh; continue; case T_SCTP_MAX_INIT_RETRIES: ops->init = oh; continue; case T_SCTP_HEARTBEAT_ITVL: ops->hbitvl = oh; continue; case T_SCTP_RTO_INITIAL: ops->rtoinit = oh; continue; case T_SCTP_RTO_MIN: ops->rtomin = oh; continue; case T_SCTP_RTO_MAX: ops->rtomax = oh; continue; case T_SCTP_OSTREAMS: ops->ostr = oh; continue; case T_SCTP_ISTREAMS: ops->istr = oh; continue; case T_SCTP_COOKIE_INC: ops->ckinc = oh; continue; case T_SCTP_THROTTLE_ITVL: ops->titvl = oh; continue; case T_SCTP_MAC_TYPE: ops->hmac = oh; continue; case T_SCTP_MAXSEG: ops->mseg = oh; continue; case T_SCTP_DEBUG: ops->debug = oh; continue; case T_SCTP_HB: ops->hb = oh; continue; case T_SCTP_RTO: ops->rto = oh; continue; case T_SCTP_STATUS: ops->status = oh; continue; } break; } return(TBADOPT); } if ( opt_ptr != opt_end ) return(TBADOPT); return(0);}/* * Negotiate options * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static void sctp_negotiate_opts(sctp_t *sp, sctp_opts_t *ops){ const size_t hlen = sizeof(struct t_opthdr); const size_t olen = hlen + sizeof(t_scalar_t); if ( !ops ) return; if ( ops->bcast ) { if ( ops->bcast->len >= olen ) { t_scalar_t *val = (t_scalar_t *)(ops->bcast+1); switch ( *val ) { case T_YES: sp->ip_broadcast = 1; break; case T_NO: sp->ip_broadcast = 0; break; } *val = sp->ip_broadcast; ops->flags |= TF_IP_BROADCAST; } } if ( ops->norte ) { if ( ops->norte->len >= olen ) { t_scalar_t *val = (t_scalar_t *)(ops->norte+1); switch ( *val ) { case T_YES: sp->ip_dontroute = 1; break; case T_NO: sp->ip_dontroute = 0; break; } *val = sp->ip_dontroute; ops->flags |= TF_IP_DONTROUTE; } } if ( ops->opts ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -