/* * "xdr_encode"-like interface that allows daemon (client) to send * a message to zebra server for a route that needs to be * added/deleted to the kernel. Info about the route is specified * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes * the info down the zclient socket using the stream_* functions. * * The corresponding read ("xdr_decode") function on the server * side is zread_ipv4_add()/zread_ipv4_delete(). * * 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Length (2) | Command | Route Type | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | ZEBRA Flags | Message Flags | Prefix length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Destination IPv4 Prefix for route | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Nexthop count | * +-+-+-+-+-+-+-+-+ * * * A number of IPv4 nexthop(s) or nexthop interface index(es) are then * described, as per the Nexthop count. Each nexthop described as: * * +-+-+-+-+-+-+-+-+ * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv4 Nexthop address or Interface Index number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_ * nexthop information is provided, and the message describes a prefix * to blackhole or reject route. * * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1 * byte value. * * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8 * byte value. * * XXX: No attention paid to alignment. */ int #undef zclient zapi_ipv4_route (u_char cmd, struct_zclient *zclient, struct prefix_ipv4 *p, struct zapi_ipv4 *api) { int i; int psize; struct stream *s; /* Reset stream. */ s = zclient->obuf; stream_reset (s); /* Length place holder. */ stream_putw (s, 0); /* Put command, type and nexthop. */ stream_putc (s, cmd); stream_putc (s, api->type); stream_putc (s, api->flags); stream_putc (s, api->message); /* Put prefix information. */ psize = PSIZE (p->prefixlen); stream_putc (s, p->prefixlen); stream_write (s, (u_char *) & p->prefix, psize); /* Nexthop, ifindex, distance and metric information. */ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) { if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE)) { stream_putc (s, 1); stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE); /* XXX assert(api->nexthop_num == 0); */ /* XXX assert(api->ifindex_num == 0); */ } else stream_putc (s, api->nexthop_num + api->ifindex_num); for (i = 0; i < api->nexthop_num; i++) { stream_putc (s, ZEBRA_NEXTHOP_IPV4); stream_put_in_addr (s, api->nexthop[i]); } for (i = 0; i < api->ifindex_num; i++) { stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); stream_putl (s, api->ifindex[i]); } } if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) stream_putc (s, api->distance); if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) stream_putl (s, api->metric); /* Put length at the first point of the stream. */ stream_putw_at (s, 0, stream_get_endp (s)); return writen (zclient->sock, s->data, stream_get_endp (s)); }
static struct bgp_nexthop_cache * zlookup_read_ipv6 (void) { struct stream *s; uint16_t length; u_char version, marker; uint16_t command; int nbytes; struct in6_addr raddr; uint32_t metric; int i; u_char nexthop_num; struct nexthop *nexthop; struct bgp_nexthop_cache *bnc; s = zlookup->ibuf; stream_reset (s); nbytes = stream_read (s, zlookup->sock, 2); length = stream_getw (s); nbytes = stream_read (s, zlookup->sock, length - 2); marker = stream_getc (s); version = stream_getc (s); if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER) { zlog_err("%s: socket %d version mismatch, marker %d, version %d", __func__, zlookup->sock, marker, version); return NULL; } command = stream_getw (s); stream_get (&raddr, s, 16); metric = stream_getl (s); nexthop_num = stream_getc (s); if (nexthop_num) { bnc = bnc_new (); bnc->valid = 1; bnc->metric = metric; bnc->nexthop_num = nexthop_num; for (i = 0; i < nexthop_num; i++) { nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop)); nexthop->type = stream_getc (s); switch (nexthop->type) { case ZEBRA_NEXTHOP_IPV6: stream_get (&nexthop->gate.ipv6, s, 16); break; case ZEBRA_NEXTHOP_IPV6_IFINDEX: case ZEBRA_NEXTHOP_IPV6_IFNAME: stream_get (&nexthop->gate.ipv6, s, 16); nexthop->ifindex = stream_getl (s); break; case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: nexthop->ifindex = stream_getl (s); break; default: /* do nothing */ break; } bnc_nexthop_add (bnc, nexthop); } } else return NULL; return bnc; }
/* May be called multiple times for the same peer */ int bgp_stop (struct peer *peer) { afi_t afi; safi_t safi; char orf_name[BUFSIZ]; /* Can't do this in Clearing; events are used for state transitions */ if (peer->status != Clearing) { /* Delete all existing events of the peer */ BGP_EVENT_FLUSH (peer); } /* Increment Dropped count. */ if (peer->status == Established) { peer->dropped++; /* bgp log-neighbor-changes of neighbor Down */ if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) zlog_info ("%%ADJCHANGE: neighbor %s Down %s", peer->host, peer_down_str [(int) peer->last_reset]); /* graceful restart */ if (peer->t_gr_stale) { BGP_TIMER_OFF (peer->t_gr_stale); if (BGP_DEBUG (events, EVENTS)) zlog_debug ("%s graceful restart stalepath timer stopped", peer->host); } if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT)) { if (BGP_DEBUG (events, EVENTS)) { zlog_debug ("%s graceful restart timer started for %d sec", peer->host, peer->v_gr_restart); zlog_debug ("%s graceful restart stalepath timer started for %d sec", peer->host, peer->bgp->stalepath_time); } BGP_TIMER_ON (peer->t_gr_restart, bgp_graceful_restart_timer_expire, peer->v_gr_restart); BGP_TIMER_ON (peer->t_gr_stale, bgp_graceful_stale_timer_expire, peer->bgp->stalepath_time); } else { UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE); for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) peer->nsf[afi][safi] = 0; } /* set last reset time */ peer->resettime = peer->uptime = bgp_clock (); #ifdef HAVE_SNMP bgpTrapBackwardTransition (peer); #endif /* HAVE_SNMP */ /* Reset peer synctime */ peer->synctime = 0; } /* Stop read and write threads when exists. */ BGP_READ_OFF (peer->t_read); BGP_WRITE_OFF (peer->t_write); /* Stop all timers. */ BGP_TIMER_OFF (peer->t_start); BGP_TIMER_OFF (peer->t_connect); BGP_TIMER_OFF (peer->t_holdtime); BGP_TIMER_OFF (peer->t_keepalive); BGP_TIMER_OFF (peer->t_routeadv); /* Stream reset. */ peer->packet_size = 0; /* Clear input and output buffer. */ if (peer->ibuf) stream_reset (peer->ibuf); if (peer->work) stream_reset (peer->work); if (peer->obuf) stream_fifo_clean (peer->obuf); /* Close of file descriptor. */ if (peer->fd >= 0) { close (peer->fd); peer->fd = -1; } for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) { /* Reset all negotiated variables */ peer->afc_nego[afi][safi] = 0; peer->afc_adv[afi][safi] = 0; peer->afc_recv[afi][safi] = 0; /* peer address family capability flags*/ peer->af_cap[afi][safi] = 0; /* peer address family status flags*/ peer->af_sflags[afi][safi] = 0; /* Received ORF prefix-filter */ peer->orf_plist[afi][safi] = NULL; /* ORF received prefix-filter pnt */ sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi); prefix_bgp_orf_remove_all (afi, orf_name); } /* Reset keepalive and holdtime */ if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER)) { peer->v_keepalive = peer->keepalive; peer->v_holdtime = peer->holdtime; } else { peer->v_keepalive = peer->bgp->default_keepalive; peer->v_holdtime = peer->bgp->default_holdtime; } peer->update_time = 0; /* Until we are sure that there is no problem about prefix count this should be commented out.*/ #if 0 /* Reset prefix count */ peer->pcount[AFI_IP][SAFI_UNICAST] = 0; peer->pcount[AFI_IP][SAFI_MULTICAST] = 0; peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0; peer->pcount[AFI_IP6][SAFI_UNICAST] = 0; peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0; #endif /* 0 */ return 0; }
/******************************************************************************* 函数名称 : web_zebra_ipv6_parse_packet 功能描述 : 读取报文,解析报文并填充结果集 输入参数 : ws_env ---- web service执行环境 count ---- 请求路由的条数 ret ---- 返回结果集 输出参数 : 返 回 值 : WS_OK ---- 执行成功 soapFault ---- 执行失败 -------------------------------------------------------------------------------- 最近一次修改记录 : 修改作者 : wangbin 修改目的 : 创建函数 修改日期 : 2010-2-26 *******************************************************************************/ static s32 web_zebra_ipv6_parse_packet(WS_ENV* ws_env, s8 *vrfidstr, s32 count, struct ws__getIpv6RouteInfoResponse *ret) { web_route_packethead_s packethead; struct stream *packetbody = NULL; struct in6_addr ip; struct in6_addr gateway; struct Ipv6RouteInfo *route_info = NULL; s8 cmp_zero[WEB_IPV6_ADDR_LEN] = {0}; s8 buf[BUFSIZ] = {0}; s8 name[INTERFACE_NAME_MAX_LENGTH+1] = {0}; s8 ifname[INTERFACE_NAME_MAX_LENGTH]={0}; s8 proto[16] = {0}; u32 ifindex = 0; u8 type = 0; u8 *pnt = NULL; u32 number = 0; s32 err = -1; u8 tlv_type = 0; u8 tlv_length = 0; s8 mask[10] = {0}; s8 litevrf_buf[5] = {0}; /*根据约定情况count分配数组大小*/ route_info = (struct Ipv6RouteInfo *)ws_malloc(ws_env, (u32)count * sizeof(struct Ipv6RouteInfo)); if (NULL == route_info) { return ws_new_soap_fault(ws_env, ERROR_SYSTEM); } /*调用memset函数,将刚申请的空间清零*/ memset(route_info, 0, (u32)count * sizeof(struct Ipv6RouteInfo)); ret->ret.__ptrres = route_info; /*packet中存放收到的报文的报文体,即报文的TLV结构*/ packetbody = stream_new (WEB_ROUTE_PACKET_MAX_SIZE); while (1) { /*读取报文头,确定报文体的长度*/ err = readn(zebra_sockfd, (u8 *)&packethead, WEB_ROUTE_PACKET_HEADER_SIZE); if (err < 0) { close(zebra_sockfd); zebra_sockfd = -1; return ERROR_FAIL; } stream_reset(packetbody); err = stream_read (packetbody, zebra_sockfd, packethead.packetlen); if (err < 0) { close(zebra_sockfd); zebra_sockfd = -1; return ERROR_FAIL; } /*因为TLV的是块数据的填充,不能使用stream操作取出路由信息的每个字段, *所以使用指针偏移的方法来取数据*/ /*将pnt定位在packet的数据段首*/ pnt = (packetbody->data + packetbody->getp); /*解析TLV,填充route_info,当剩余数据不够一个TLV的头部数据 *则停止解析数据*/ while (((packetbody->data + packetbody->endp) - pnt) > 2) { /*取出TLV的类型和长度字段,通过类型进行分类处理,通过 *长度判断TLV的value字段是否处理完毕*/ tlv_type = *pnt; tlv_length = *(pnt + 1); pnt += 2; /*根据类型进行解析,并填充结果集*/ switch (tlv_type) { case WEB_ZEBRA_ROUTE_IPV6_STATIC: while ((tlv_length - WEB_ZEBRA_STATIC_ROUTE_IPV6_LENGTH) >= 0) { if (number >= WEB_ZEBRA_WRITE_ROUTE_MAX) { pnt += tlv_length; tlv_length = 0; break; } /*取出路由的类型,填充结果集*/ type = *pnt++; if(type == 0xff) { route_info[number].type = ws_strdup(ws_env, "llb"); } else { if(CHECK_FLAG(type, ZEBRA_FLAG_BLACKHOLE)) { route_info[number].type = ws_strdup(ws_env, "blackhole"); } else if(CHECK_FLAG(type, ZEBRA_FLAG_REJECT)) { route_info[number].type = ws_strdup(ws_env, "reject"); } else { route_info[number].type = ws_strdup(ws_env, "normal"); } } /*取出路由的优先级,填充结果集*/ route_info[number].distance = *pnt++; /*取出目的网段,填充结果集*/ memcpy(ip.s6_addr, pnt, WEB_IPV6_ADDR_LEN); pnt += WEB_IPV6_ADDR_LEN; route_info[number].ip = ws_strdup(ws_env, inet_ntop (AF_INET6, &ip, buf, BUFSIZ)); /*取出子网掩码,填充结果集*/ sprintf(mask, "%d", *((u32 *)pnt)); pnt += sizeof(u32); route_info[number].netmask = ws_strdup(ws_env, mask); /*取出下一跳,填充结果集*/ memcpy(gateway.s6_addr, pnt, WEB_IPV6_ADDR_LEN); pnt += WEB_IPV6_ADDR_LEN; if (!memcmp(gateway.s6_addr, cmp_zero, WEB_IPV6_ADDR_LEN)) { route_info[number].gateway = ws_strdup(ws_env, "::"); } else { route_info[number].gateway = ws_strdup(ws_env, inet_ntop (AF_INET6, &gateway, buf, BUFSIZ)); } /*取出指定出接口,填充结果集*/ ifindex = *((u32 *)pnt); pnt += sizeof(ifindex); memcpy(ifname,pnt,INTERFACE_NAME_MAX_LENGTH); pnt += sizeof(ifname); if (WEB_ZEBRA_INTERFACE_AUTO == ifindex) { route_info[number].ifname = ws_strdup(ws_env, "auto"); } else if (WEB_ZEBRA_INTERFACE_NULL0 == ifindex) { route_info[number].ifname = ws_strdup(ws_env, "Null0"); } else { if ((err = if_get_name_by_index(name, INTERFACE_NAME_MAX_LENGTH, (s32)ifindex)) != ERROR_SUCCESS) { if(ifname[0] != 0) { route_info[number].ifname = ws_strdup(ws_env, ifname); } else { route_info[number].ifname = ws_strdup(ws_env, "unknown"); } } else { route_info[number].ifname = ws_strdup(ws_env, name); } } sprintf(litevrf_buf, "%d", litevrf_id); route_info[number].litevrfid = ws_strdup(ws_env, litevrf_buf); tlv_length -= WEB_ZEBRA_STATIC_ROUTE_IPV6_LENGTH; number++; } break; case WEB_ZEBRA_ROUTE_IPV6_ALL_NUM: ret->ret.sum = *((s32 *)pnt); pnt += sizeof(ret->ret.sum); break; case WEB_ZEBRA_ROUTE_IPV6_ALL: while ((tlv_length - WEB_ZEBRA_ROUTE_IPV6_INFO_LENGTH) >= 0) { if (number >= WEB_ZEBRA_WRITE_ROUTE_MAX) { pnt += tlv_length; tlv_length = 0; break; } /*取出协议字段*/ switch (*pnt++) { case ZEBRA_ROUTE_BGP: strcpy (proto, "BGP"); break; case ZEBRA_ROUTE_CONNECT: strcpy (proto, "connect"); break; case ZEBRA_ROUTE_KERNEL: strcpy (proto, "kernel"); break; case ZEBRA_ROUTE_OSPF6: strcpy (proto, "OSPFv3"); break; case ZEBRA_ROUTE_ISIS: strcpy (proto, "ISIS"); break; case ZEBRA_ROUTE_RIP: strcpy (proto, "RIP"); break; case ZEBRA_ROUTE_RIPNG: strcpy (proto, "RIPNG"); break; case ZEBRA_ROUTE_STATIC: strcpy (proto, "static"); break; default: strcpy (proto, "unknown"); break; } route_info[number].proto = ws_strdup(ws_env, proto); /*取出状态字段,填充结果集*/ if (WEB_ZEBRA_ROUTE_SELECT == *pnt++ ) { route_info[number].status = ws_strdup(ws_env, "active"); } else { route_info[number].status = ws_strdup(ws_env, "inactive"); } /*取出目的网段,填充结果集*/ memcpy(ip.s6_addr, pnt, WEB_IPV6_ADDR_LEN); pnt += WEB_IPV6_ADDR_LEN; route_info[number].ip = ws_strdup(ws_env, inet_ntop (AF_INET6, &ip, buf, BUFSIZ)); /*取出掩码字段,填充结果集*/ sprintf(mask, "%d", *((u32 *)pnt)); pnt += sizeof(u32); route_info[number].netmask = ws_strdup(ws_env, mask); /*取出下一跳字段,填充结果集*/ memcpy(gateway.s6_addr, pnt, WEB_IPV6_ADDR_LEN); pnt += WEB_IPV6_ADDR_LEN; if (!memcmp(gateway.s6_addr, cmp_zero, WEB_IPV6_ADDR_LEN)) { route_info[number].gateway = ws_strdup(ws_env, "::"); } else { route_info[number].gateway = ws_strdup(ws_env, inet_ntop (AF_INET6, &gateway, buf, BUFSIZ)); } /*取出指定出接口,填充结果集*/ ifindex = *((u32 *)pnt); pnt += sizeof(ifindex); memcpy(ifname,pnt,INTERFACE_NAME_MAX_LENGTH); pnt += sizeof(ifname); if (WEB_ZEBRA_INTERFACE_NULL0 == ifindex) { route_info[number].ifname = ws_strdup(ws_env, "Null0"); } else { if ((err = if_get_name_by_index(name, INTERFACE_NAME_MAX_LENGTH, (s32)ifindex)) != ERROR_SUCCESS) { if(ifname[0] != 0) { route_info[number].ifname = ws_strdup(ws_env, ifname); } else { route_info[number].ifname = ws_strdup(ws_env, "unknown"); } } route_info[number].ifname = ws_strdup(ws_env, name); } /*取出该路由的花费,填充结果集*/ route_info[number].metric = *((s32 *)pnt); pnt += sizeof(u32); /*取出路由的优先级,填充结果集*/ route_info[number].distance = *pnt++; /*取出路由的类型,填充结果集*/ type = *pnt++; if(type == 0xff) { route_info[number].type = ws_strdup(ws_env, "llb"); } else { if(CHECK_FLAG(type, ZEBRA_FLAG_BLACKHOLE)) { route_info[number].type = ws_strdup(ws_env, "blackhole"); } else if(CHECK_FLAG(type, ZEBRA_FLAG_REJECT)) { route_info[number].type = ws_strdup(ws_env, "reject"); } else { route_info[number].type = ws_strdup(ws_env, "normal"); } } sprintf(litevrf_buf, "%d", litevrf_id); route_info[number].litevrfid = ws_strdup(ws_env, litevrf_buf); number++; tlv_length -= WEB_ZEBRA_ROUTE_IPV6_INFO_LENGTH; } break; default: /*tlv_type不识别时则把该整个tlv偏移过去*/ pnt += tlv_length; break; } } stream_reset (packetbody); /*报文的lastpacketflag字段被置位,则接受新的报文*/ if (WEB_ROUTE_PACKET_LAST == packethead.lastpacketflag) { break; } } stream_free(packetbody); ret->ret.res_USCOREcount = ret->ret.__size = (s32)number; if(ret->ret.sum == 0) { ret->ret.sum = (s32)number; } return WS_OK; }
static int cache_fill(cache_vars_t *s) { int back,back2,newb,space,len,pos; off_t read=s->read_filepos; int read_chunk; int wraparound_copy = 0; if(read<s->min_filepos || read>s->max_filepos){ // seek... mp_msg(MSGT_CACHE,MSGL_DBG2,"Out of boundaries... seeking to 0x%"PRIX64" \n",(int64_t)read); // drop cache contents only if seeking backward or too much fwd. // This is also done for on-disk files, since it loses the backseek cache. // That in turn can cause major bandwidth increase and performance // issues with e.g. mov or badly interleaved files if(read<s->min_filepos || read>=s->max_filepos+s->seek_limit) { s->offset= // FIXME!? s->min_filepos=s->max_filepos=read; // drop cache content :( if(s->stream->eof) stream_reset(s->stream); stream_seek_internal(s->stream,read); mp_msg(MSGT_CACHE,MSGL_DBG2,"Seek done. new pos: 0x%"PRIX64" \n",(int64_t)stream_tell(s->stream)); } } // calc number of back-bytes: back=read - s->min_filepos; if(back<0) back=0; // strange... if(back>s->back_size) back=s->back_size; // calc number of new bytes: newb=s->max_filepos - read; if(newb<0) newb=0; // strange... // calc free buffer space: space=s->buffer_size - (newb+back); // calc bufferpos: pos=s->max_filepos - s->offset; if(pos>=s->buffer_size) pos-=s->buffer_size; // wrap-around if(space<s->fill_limit){ // printf("Buffer is full (%d bytes free, limit: %d)\n",space,s->fill_limit); return 0; // no fill... } // printf("### read=0x%X back=%d newb=%d space=%d pos=%d\n",read,back,newb,space,pos); // try to avoid wrap-around. If not possible due to sector size // do an extra copy. if(space>s->buffer_size-pos) { if (s->buffer_size-pos >= s->sector_size) { space=s->buffer_size-pos; } else { space = s->sector_size; wraparound_copy = 1; } } // limit one-time block size read_chunk = s->stream->read_chunk; if (!read_chunk) read_chunk = 4*s->sector_size; space = FFMIN(space, read_chunk); #if 1 // back+newb+space <= buffer_size back2=s->buffer_size-(space+newb); // max back size if(s->min_filepos<(read-back2)) s->min_filepos=read-back2; #else s->min_filepos=read-back; // avoid seeking-back to temp area... #endif if (wraparound_copy) { int to_copy; len = stream_read_internal(s->stream, s->stream->buffer, space); to_copy = FFMIN(len, s->buffer_size-pos); memcpy(s->buffer + pos, s->stream->buffer, to_copy); memcpy(s->buffer, s->stream->buffer + to_copy, len - to_copy); } else len = stream_read_internal(s->stream, &s->buffer[pos], space); s->eof= !len; s->max_filepos+=len; if(pos+len>=s->buffer_size){ // wrap... s->offset+=s->buffer_size; } return len; }
int dvb_set_channel(dvb_priv_t *priv, int card, int n) { dvb_channels_list *new_list; dvb_channel_t *channel; stream_t *stream = (stream_t*) priv->stream; char buf[4096]; dvb_config_t *conf = (dvb_config_t *) priv->config; int devno; int i; if((card < 0) || (card > conf->count)) { mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_set_channel: INVALID CARD NUMBER: %d vs %d, abort\n", card, conf->count); return 0; } devno = conf->cards[card].devno; new_list = conf->cards[card].list; if((n > new_list->NUM_CHANNELS) || (n < 0)) { mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_set_channel: INVALID CHANNEL NUMBER: %d, for card %d, abort\n", n, card); return 0; } channel = &(new_list->channels[n]); if(priv->is_on) //the fds are already open and we have to stop the demuxers { for(i = 0; i < priv->demux_fds_cnt; i++) dvb_demux_stop(priv->demux_fds[i]); priv->retry = 0; while(dvb_streaming_read(stream, buf, 4096) > 0); //empty both the stream's and driver's buffer if(priv->card != card) { dvbin_close(stream); if(! dvb_open_devices(priv, devno, channel->pids_cnt, channel->pids)) { mp_msg(MSGT_DEMUX, MSGL_ERR, "DVB_SET_CHANNEL, COULDN'T OPEN DEVICES OF CARD: %d, EXIT\n", card); return 0; } } else //close all demux_fds with pos > pids required for the new channel or open other demux_fds if we have too few { if(! dvb_fix_demuxes(priv, channel->pids_cnt, channel->pids)) return 0; } } else { if(! dvb_open_devices(priv, devno, channel->pids_cnt, channel->pids)) { mp_msg(MSGT_DEMUX, MSGL_ERR, "DVB_SET_CHANNEL2, COULDN'T OPEN DEVICES OF CARD: %d, EXIT\n", card); return 0; } } dvb_config->priv = priv; priv->card = card; priv->list = new_list; priv->retry = 5; new_list->current = n; stream->fd = priv->dvr_fd; mp_msg(MSGT_DEMUX, MSGL_V, "DVB_SET_CHANNEL: new channel name=%s, card: %d, channel %d\n", channel->name, card, n); stream->eof=1; stream_reset(stream); if(channel->freq != priv->last_freq) if (! dvb_tune(priv, channel->freq, channel->pol, channel->srate, channel->diseqc, channel->tone, channel->inv, channel->mod, channel->gi, channel->trans, channel->bw, channel->cr, channel->cr_lp, channel->hier, priv->timeout)) return 0; priv->last_freq = channel->freq; priv->is_on = 1; //sets demux filters and restart the stream for(i = 0; i < channel->pids_cnt; i++) { if(! dvb_set_ts_filt(priv->demux_fds[i], channel->pids[i], DMX_PES_OTHER)) return 0; } return 1; }
/* Zebra client message read function. */ static int zclient_read (struct thread *thread) { int ret; size_t already; uint16_t length, command; uint8_t marker, version; struct zclient *zclient; /* Get socket to zebra. */ zclient = THREAD_ARG (thread); zclient->t_read = NULL; /* Read zebra header (if we don't have it already). */ if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) { ssize_t nbyte; if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock, ZEBRA_HEADER_SIZE-already)) == 0) || (nbyte == -1)) { #ifdef ZCLIENT_DEBUG zlog_debug ("zclient connection closed socket [%d].", zclient->sock); #endif return zclient_failed(zclient); } if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already)) { /* Try again later. */ zclient_event (ZCLIENT_READ, zclient); return 0; } already = ZEBRA_HEADER_SIZE; } /* Reset to read from the beginning of the incoming packet. */ stream_set_getp(zclient->ibuf, 0); /* Fetch header values. */ length = stream_getw (zclient->ibuf); marker = stream_getc (zclient->ibuf); version = stream_getc (zclient->ibuf); command = stream_getw (zclient->ibuf); if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) { zlog_err("%s: socket %d version mismatch, marker %d, version %d", __func__, zclient->sock, marker, version); return zclient_failed(zclient); } if (length < ZEBRA_HEADER_SIZE) { zlog_err("%s: socket %d message length %u is less than %d ", __func__, zclient->sock, length, ZEBRA_HEADER_SIZE); return zclient_failed(zclient); } /* Length check. */ if (length > STREAM_SIZE(zclient->ibuf)) { struct stream *ns; zlog_warn("%s: message size %u exceeds buffer size %lu, expanding...", __func__, length, (u_long)STREAM_SIZE(zclient->ibuf)); ns = stream_new(length); stream_copy(ns, zclient->ibuf); stream_free (zclient->ibuf); zclient->ibuf = ns; } /* Read rest of zebra packet. */ if (already < length) { ssize_t nbyte; if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock, length-already)) == 0) || (nbyte == -1)) { #ifdef ZCLIENT_DEBUG zlog_debug("zclient connection closed socket [%d].", zclient->sock); #endif return zclient_failed(zclient); } if (nbyte != (ssize_t)(length-already)) { /* Try again later. */ zclient_event (ZCLIENT_READ, zclient); return 0; } } length -= ZEBRA_HEADER_SIZE; #ifdef ZCLIENT_DEBUG zlog_debug("zclient 0x%p command 0x%x \n", zclient, command); #endif switch (command) { case ZEBRA_ROUTER_ID_UPDATE: if (zclient->router_id_update) ret = (*zclient->router_id_update) (command, zclient, length); break; case ZEBRA_INTERFACE_ADD: if (zclient->interface_add) ret = (*zclient->interface_add) (command, zclient, length); break; case ZEBRA_INTERFACE_DELETE: if (zclient->interface_delete) ret = (*zclient->interface_delete) (command, zclient, length); break; case ZEBRA_INTERFACE_ADDRESS_ADD: if (zclient->interface_address_add) ret = (*zclient->interface_address_add) (command, zclient, length); break; case ZEBRA_INTERFACE_ADDRESS_DELETE: if (zclient->interface_address_delete) ret = (*zclient->interface_address_delete) (command, zclient, length); break; case ZEBRA_INTERFACE_UP: if (zclient->interface_up) ret = (*zclient->interface_up) (command, zclient, length); break; case ZEBRA_INTERFACE_DOWN: if (zclient->interface_down) ret = (*zclient->interface_down) (command, zclient, length); break; case ZEBRA_IPV4_ROUTE_ADD: if (zclient->ipv4_route_add) ret = (*zclient->ipv4_route_add) (command, zclient, length); break; case ZEBRA_IPV4_ROUTE_DELETE: if (zclient->ipv4_route_delete) ret = (*zclient->ipv4_route_delete) (command, zclient, length); break; case ZEBRA_IPV6_ROUTE_ADD: if (zclient->ipv6_route_add) ret = (*zclient->ipv6_route_add) (command, zclient, length); break; case ZEBRA_IPV6_ROUTE_DELETE: if (zclient->ipv6_route_delete) ret = (*zclient->ipv6_route_delete) (command, zclient, length); break; default: break; } if (zclient->sock < 0) /* Connection was closed during packet processing. */ return -1; /* Register read thread. */ stream_reset(zclient->ibuf); zclient_event (ZCLIENT_READ, zclient); return 0; }
void bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi) { int flags; u_char distance; struct peer *peer; struct bgp_info *mpinfo; size_t oldsize, newsize; if (zclient->sock < 0) return; if (! zclient->redist[ZEBRA_ROUTE_BGP]) return; flags = 0; peer = info->peer; if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) { SET_FLAG (flags, ZEBRA_FLAG_IBGP); SET_FLAG (flags, ZEBRA_FLAG_INTERNAL); } if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1) || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)) SET_FLAG (flags, ZEBRA_FLAG_INTERNAL); /* resize nexthop buffer size if necessary */ if ((oldsize = stream_get_size (bgp_nexthop_buf)) < (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1))) { newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)); newsize = stream_resize (bgp_nexthop_buf, newsize); if (newsize == oldsize) { zlog_err ("can't resize nexthop buffer"); return; } } stream_reset (bgp_nexthop_buf); if (p->family == AF_INET) { struct zapi_ipv4 api; struct in_addr *nexthop; api.flags = flags; nexthop = &info->attr->nexthop; stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); for (mpinfo = bgp_info_mpath_first (info); mpinfo; mpinfo = bgp_info_mpath_next (mpinfo)) { nexthop = &mpinfo->attr->nexthop; stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); } api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1 + bgp_info_mpath_count (info); api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf); api.ifindex_num = 0; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; distance = bgp_distance_apply (p, info, bgp); if (distance) { SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); api.distance = distance; } if (BGP_DEBUG(zebra, ZEBRA)) { int i; char buf[2][INET_ADDRSTRLEN]; zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u" " count %d", inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), p->prefixlen, inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])), api.metric, api.nexthop_num); for (i = 1; i < api.nexthop_num; i++) zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s", i, inet_ntop(AF_INET, api.nexthop[i], buf[1], sizeof(buf[1]))); } zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, (struct prefix_ipv4 *) p, &api); } #ifdef HAVE_IPV6 /* We have to think about a IPv6 link-local address curse. */ if (p->family == AF_INET6) { unsigned int ifindex; struct in6_addr *nexthop; struct zapi_ipv6 api; ifindex = 0; nexthop = NULL; assert (info->attr->extra); /* Only global address nexthop exists. */ if (info->attr->extra->mp_nexthop_len == 16) nexthop = &info->attr->extra->mp_nexthop_global; /* If both global and link-local address present. */ if (info->attr->extra->mp_nexthop_len == 32) { /* Workaround for Cisco's nexthop bug. */ if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global) && peer->su_remote->sa.sa_family == AF_INET6) nexthop = &peer->su_remote->sin6.sin6_addr; else nexthop = &info->attr->extra->mp_nexthop_local; if (info->peer->nexthop.ifp) ifindex = info->peer->nexthop.ifp->ifindex; } if (nexthop == NULL) return; if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex) { if (info->peer->ifname) ifindex = if_nametoindex (info->peer->ifname); else if (info->peer->nexthop.ifp) ifindex = info->peer->nexthop.ifp->ifindex; } /* Make Zebra API structure. */ api.flags = flags; api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop; SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); api.ifindex_num = 1; api.ifindex = &ifindex; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET6_ADDRSTRLEN]; zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u", inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), p->prefixlen, inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])), api.metric); } zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, (struct prefix_ipv6 *) p, &api); } #endif /* HAVE_IPV6 */ }
static demuxer_t* demux_open_rawdv(demuxer_t* demuxer) { unsigned char dv_frame[DV_PAL_FRAME_SIZE]; sh_video_t *sh_video = NULL; rawdv_frames_t *frames = malloc(sizeof(rawdv_frames_t)); dv_decoder_t *dv_decoder=NULL; mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() end_pos %"PRId64"\n",(int64_t)demuxer->stream->end_pos); // go back to the beginning stream_reset(demuxer->stream); stream_seek(demuxer->stream, 0); //get the first frame stream_read(demuxer->stream, dv_frame, DV_PAL_FRAME_SIZE); //read params from this frame dv_decoder=dv_decoder_new(TRUE,TRUE,FALSE); dv_decoder->quality=DV_QUALITY_BEST; if (dv_parse_header(dv_decoder, dv_frame) == -1) return NULL; // create a new video stream header sh_video = new_sh_video(demuxer, 0); if (!sh_video) return NULL; // make sure the demuxer knows about the new video stream header // (even though new_sh_video() ought to take care of it) demuxer->seekable = 1; demuxer->video->sh = sh_video; // make sure that the video demuxer stream header knows about its // parent video demuxer stream (this is getting wacky), or else // video_read_properties() will choke sh_video->ds = demuxer->video; // custom fourcc for internal MPlayer use // sh_video->format = mmioFOURCC('R', 'A', 'D', 'V'); sh_video->format = mmioFOURCC('D', 'V', 'S', 'D'); sh_video->disp_w = dv_decoder->width; sh_video->disp_h = dv_decoder->height; mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() frame_size: %d w: %d h: %d dif_seq: %d system: %d\n",dv_decoder->frame_size,dv_decoder->width, dv_decoder->height,dv_decoder->num_dif_seqs,dv_decoder->system); sh_video->fps= (dv_decoder->system==e_dv_system_525_60?29.97:25); sh_video->frametime = 1.0/sh_video->fps; // emulate BITMAPINFOHEADER for win32 decoders: sh_video->bih=malloc(sizeof(BITMAPINFOHEADER)); memset(sh_video->bih,0,sizeof(BITMAPINFOHEADER)); sh_video->bih->biSize=40; sh_video->bih->biWidth = dv_decoder->width; sh_video->bih->biHeight = dv_decoder->height; sh_video->bih->biPlanes=1; sh_video->bih->biBitCount=24; sh_video->bih->biCompression=sh_video->format; // "DVSD" sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3; frames->current_filepos=0; frames->current_frame=0; frames->frame_size=dv_decoder->frame_size; frames->frame_number=demuxer->stream->end_pos/frames->frame_size; mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() seek to %qu, size: %d, dv_dec->frame_size: %d\n",frames->current_filepos,frames->frame_size, dv_decoder->frame_size); if (dv_decoder->audio != NULL && demuxer->audio->id>=-1){ sh_audio_t *sh_audio = new_sh_audio(demuxer, 0); demuxer->audio->sh = sh_audio; sh_audio->ds = demuxer->audio; mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() chan: %d samplerate: %d\n",dv_decoder->audio->num_channels,dv_decoder->audio->frequency ); // custom fourcc for internal MPlayer use sh_audio->format = mmioFOURCC('R', 'A', 'D', 'V'); sh_audio->wf = malloc(sizeof(WAVEFORMATEX)); memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX)); sh_audio->wf->wFormatTag = sh_audio->format; sh_audio->wf->nChannels = dv_decoder->audio->num_channels; sh_audio->wf->wBitsPerSample = 16; sh_audio->wf->nSamplesPerSec = dv_decoder->audio->frequency; // info about the input stream: sh_audio->wf->nAvgBytesPerSec = sh_video->fps*dv_decoder->frame_size; sh_audio->wf->nBlockAlign = dv_decoder->frame_size; // sh_audio->context=(void*)dv_decoder; } stream_reset(demuxer->stream); stream_seek(demuxer->stream, 0); dv_decoder_free(dv_decoder); //we keep this in the context of both stream headers demuxer->priv=frames; return demuxer; }
static void bgp_dump_routes_index_table(struct bgp *bgp) { struct peer *peer; struct listnode *node; uint16_t peerno = 0; struct stream *obuf; obuf = bgp_dump_obuf; stream_reset (obuf); /* MRT header */ bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_PEER_INDEX_TABLE); /* Collector BGP ID */ stream_put_in_addr (obuf, &bgp->router_id); /* View name */ if(bgp->name) { stream_putw (obuf, strlen(bgp->name)); stream_put(obuf, bgp->name, strlen(bgp->name)); } else { stream_putw(obuf, 0); } /* Peer count */ stream_putw (obuf, listcount(bgp->peer)); /* Walk down all peers */ for(ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer)) { /* Peer's type */ if (sockunion_family(&peer->su) == AF_INET) { stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP); } #ifdef HAVE_IPV6 else if (sockunion_family(&peer->su) == AF_INET6) { stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP6); } #endif /* HAVE_IPV6 */ /* Peer's BGP ID */ stream_put_in_addr (obuf, &peer->remote_id); /* Peer's IP address */ if (sockunion_family(&peer->su) == AF_INET) { stream_put_in_addr (obuf, &peer->su.sin.sin_addr); } #ifdef HAVE_IPV6 else if (sockunion_family(&peer->su) == AF_INET6) { stream_write (obuf, (u_char *)&peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN); } #endif /* HAVE_IPV6 */ /* Peer's AS number. */ /* Note that, as this is an AS4 compliant quagga, the RIB is always AS4 */ stream_putl (obuf, peer->as); /* Store the peer number for this peer */ peer->table_dump_index = peerno; peerno++; } bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2); fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp); fflush (bgp_dump_routes.fp); }
/* Runs under child process. */ static unsigned int bgp_dump_routes_func (int afi, int first_run, unsigned int seq) { struct stream *obuf; struct bgp_info *info; struct bgp_node *rn; struct bgp *bgp; struct bgp_table *table; bgp = bgp_get_default (); if (!bgp) return seq; if (bgp_dump_routes.fp == NULL) return seq; /* Note that bgp_dump_routes_index_table will do ipv4 and ipv6 peers, so this should only be done on the first call to bgp_dump_routes_func. ( this function will be called once for ipv4 and once for ipv6 ) */ if(first_run) bgp_dump_routes_index_table(bgp); obuf = bgp_dump_obuf; stream_reset(obuf); /* Walk down each BGP route. */ table = bgp->rib[afi][SAFI_UNICAST]; for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) { if(!rn->info) continue; stream_reset(obuf); /* MRT header */ if (afi == AFI_IP) { bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV4_UNICAST); } #ifdef HAVE_IPV6 else if (afi == AFI_IP6) { bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV6_UNICAST); } #endif /* HAVE_IPV6 */ /* Sequence number */ stream_putl(obuf, seq); /* Prefix length */ stream_putc (obuf, rn->p.prefixlen); /* Prefix */ if (afi == AFI_IP) { /* We'll dump only the useful bits (those not 0), but have to align on 8 bits */ stream_write(obuf, (u_char *)&rn->p.u.prefix4, (rn->p.prefixlen+7)/8); } #ifdef HAVE_IPV6 else if (afi == AFI_IP6) { /* We'll dump only the useful bits (those not 0), but have to align on 8 bits */ stream_write (obuf, (u_char *)&rn->p.u.prefix6, (rn->p.prefixlen+7)/8); } #endif /* HAVE_IPV6 */ /* Save where we are now, so we can overwride the entry count later */ int sizep = stream_get_endp(obuf); /* Entry count */ uint16_t entry_count = 0; /* Entry count, note that this is overwritten later */ stream_putw(obuf, 0); for (info = rn->info; info; info = info->next) { entry_count++; /* Peer index */ stream_putw(obuf, info->peer->table_dump_index); /* Originated */ stream_putl (obuf, info->uptime); /* Dump attribute. */ /* Skip prefix & AFI/SAFI for MP_NLRI */ bgp_dump_routes_attr (obuf, info->attr, &rn->p); } /* Overwrite the entry count, now that we know the right number */ stream_putw_at (obuf, sizep, entry_count); seq++; bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2); fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp); } fflush (bgp_dump_routes.fp); return seq; }
/* * "xdr_encode"-like interface that allows daemon (client) to send * a message to zebra server for a route that needs to be * added/deleted to the kernel. Info about the route is specified * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes * the info down the zclient socket using the stream_* functions. * * The corresponding read ("xdr_decode") function on the server * side is zread_ipv4_add()/zread_ipv4_delete(). * * 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Length (2) | Command | Route Type | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | ZEBRA Flags | Message Flags | Prefix length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Destination IPv4 Prefix for route | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Nexthop count | * +-+-+-+-+-+-+-+-+ * * * A number of IPv4 nexthop(s) or nexthop interface index(es) are then * described, as per the Nexthop count. Each nexthop described as: * * +-+-+-+-+-+-+-+-+ * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv4 Nexthop address or Interface Index number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_ * nexthop information is provided, and the message describes a prefix * to blackhole or reject route. * * The original struct zapi_ipv4, zapi_ipv4_route() and zread_ipv4_*() * infrastructure was built around the traditional (32-bit "gate OR * ifindex") nexthop data unit. A special encoding can be used to feed * onlink (64-bit "gate AND ifindex") nexthops into zapi_ipv4_route() * using the same zapi_ipv4 structure. This is done by setting zapi_ipv4 * fields as follows: * - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK * - .nexthop_num == .ifindex_num * - .nexthop and .ifindex are filled with gate and ifindex parts of * each compound nexthop, both in the same order * * zapi_ipv4_route() will produce two nexthop data units for each such * interleaved 64-bit nexthop. On the zserv side of the socket it will be * mapped to a singlle NEXTHOP_TYPE_IPV4_IFINDEX_OL RIB nexthop structure. * * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1 * byte value. * * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8 * byte value. * * XXX: No attention paid to alignment. */ int zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p, struct zapi_ipv4 *api) { int i; int psize; struct stream *s; /* Reset stream. */ s = zclient->obuf; stream_reset (s); zclient_create_header (s, cmd); /* Put type and nexthop. */ stream_putc (s, api->type); stream_putc (s, api->flags); stream_putc (s, api->message); stream_putw (s, api->safi); /* Put prefix information. */ psize = PSIZE (p->prefixlen); stream_putc (s, p->prefixlen); stream_write (s, (u_char *) & p->prefix, psize); /* Nexthop, ifindex, distance and metric information. */ /* ZAPI_MESSAGE_ONLINK implies interleaving */ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_ONLINK)) { /* ZAPI_MESSAGE_NEXTHOP is required for proper receiving */ assert (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)); /* 64-bit data units, interleaved between nexthop[] and ifindex[] */ assert (api->nexthop_num == api->ifindex_num); stream_putc (s, api->nexthop_num * 2); for (i = 0; i < api->nexthop_num; i++) { stream_putc (s, ZEBRA_NEXTHOP_IPV4_ONLINK); stream_put_in_addr (s, api->nexthop[i]); stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); stream_putl (s, api->ifindex[i]); } } else if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) { /* traditional 32-bit data units */ if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE | ZEBRA_FLAG_REJECT)) { stream_putc (s, 1); stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE); /* XXX assert(api->nexthop_num == 0); */ /* XXX assert(api->ifindex_num == 0); */ } else stream_putc (s, api->nexthop_num + api->ifindex_num); for (i = 0; i < api->nexthop_num; i++) { stream_putc (s, ZEBRA_NEXTHOP_IPV4); stream_put_in_addr (s, api->nexthop[i]); } for (i = 0; i < api->ifindex_num; i++) { stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); stream_putl (s, api->ifindex[i]); } } if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) stream_putc (s, api->distance); if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) stream_putl (s, api->metric); /* Put length at the first point of the stream. */ stream_putw_at (s, 0, stream_get_endp (s)); return zclient_send_message(zclient); }
void unabto_stream_release(unabto_stream* stream) { nabto_stream_tcb_release(stream); stream_reset(stream); }
/* Zebra client message read function. */ int zclient_read (struct thread *thread) { int ret; int nbytes; int sock; zebra_size_t length; zebra_command_t command; #undef zclient struct_zclient *zclient; /* Get socket to zebra. */ sock = THREAD_FD (thread); zclient = THREAD_ARG (thread); zclient->t_read = NULL; /* Clear input buffer. */ stream_reset (zclient->ibuf); /* Read zebra header. */ nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE); /* zebra socket is closed. */ if (nbytes == 0) { if (zclient_debug) zlog_debug ("zclient connection closed socket [%d].", sock); zclient->fail++; zclient_stop (zclient); zclient_event (ZCLIENT_CONNECT, zclient); return -1; } /* zebra read error. */ if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE) { if (zclient_debug) zlog_debug ("Can't read all packet (length %d).", nbytes); zclient->fail++; zclient_stop (zclient); zclient_event (ZCLIENT_CONNECT, zclient); return -1; } /* Fetch length and command. */ length = stream_getw (zclient->ibuf); command = stream_getc (zclient->ibuf); /* Length check. */ if (length >= zclient->ibuf->size) { stream_free (zclient->ibuf); zclient->ibuf = stream_new (length + 1); } length -= ZEBRA_HEADER_SIZE; /* Read rest of zebra packet. */ nbytes = stream_read (zclient->ibuf, sock, length); if (nbytes != length) { if (zclient_debug) zlog_debug ("zclient connection closed socket [%d].", sock); zclient->fail++; zclient_stop (zclient); zclient_event (ZCLIENT_CONNECT, zclient); return -1; } if (zclient_debug) zlog_debug("zclient 0x%p command 0x%x \n", zclient, command); switch (command) { case ZEBRA_ROUTER_ID_UPDATE: if (zclient->router_id_update) ret = (*zclient->router_id_update) (command, zclient, length); break; case ZEBRA_INTERFACE_ADD: if (zclient->interface_add) ret = (*zclient->interface_add) (command, zclient, length); break; case ZEBRA_INTERFACE_DELETE: if (zclient->interface_delete) ret = (*zclient->interface_delete) (command, zclient, length); break; case ZEBRA_INTERFACE_ADDRESS_ADD: if (zclient->interface_address_add) ret = (*zclient->interface_address_add) (command, zclient, length); break; case ZEBRA_INTERFACE_ADDRESS_DELETE: if (zclient->interface_address_delete) ret = (*zclient->interface_address_delete) (command, zclient, length); break; case ZEBRA_INTERFACE_UP: if (zclient->interface_up) ret = (*zclient->interface_up) (command, zclient, length); break; case ZEBRA_INTERFACE_DOWN: if (zclient->interface_down) ret = (*zclient->interface_down) (command, zclient, length); break; case ZEBRA_IPV4_ROUTE_ADD: if (zclient->ipv4_route_add) ret = (*zclient->ipv4_route_add) (command, zclient, length); break; case ZEBRA_IPV4_ROUTE_DELETE: if (zclient->ipv4_route_delete) ret = (*zclient->ipv4_route_delete) (command, zclient, length); break; case ZEBRA_IPV6_ROUTE_ADD: if (zclient->ipv6_route_add) ret = (*zclient->ipv6_route_add) (command, zclient, length); break; case ZEBRA_IPV6_ROUTE_DELETE: if (zclient->ipv6_route_delete) ret = (*zclient->ipv6_route_delete) (command, zclient, length); break; default: break; } /* Register read thread. */ zclient_event (ZCLIENT_READ, zclient); return 0; }
int cache_fill(cache_vars_t* s){ int back,back2,newb,space,len,pos; off_t read=s->read_filepos; if(read<s->min_filepos || read>s->max_filepos){ // seek... mp_msg(MSGT_CACHE,MSGL_DBG2,"Out of boundaries... seeking to 0x%"PRIX64" \n",(int64_t)read); // streaming: drop cache contents only if seeking backward or too much fwd: if(s->stream->type!=STREAMTYPE_STREAM || read<s->min_filepos || read>=s->max_filepos+s->seek_limit) { s->offset= // FIXME!? s->min_filepos=s->max_filepos=read; // drop cache content :( if(s->stream->eof) stream_reset(s->stream); stream_seek(s->stream,read); mp_msg(MSGT_CACHE,MSGL_DBG2,"Seek done. new pos: 0x%"PRIX64" \n",(int64_t)stream_tell(s->stream)); } } // calc number of back-bytes: back=read - s->min_filepos; if(back<0) back=0; // strange... if(back>s->back_size) back=s->back_size; // calc number of new bytes: newb=s->max_filepos - read; if(newb<0) newb=0; // strange... // calc free buffer space: space=s->buffer_size - (newb+back); // calc bufferpos: pos=s->max_filepos - s->offset; if(pos>=s->buffer_size) pos-=s->buffer_size; // wrap-around if(space<s->fill_limit){ // printf("Buffer is full (%d bytes free, limit: %d)\n",space,s->fill_limit); return 0; // no fill... } // printf("### read=0x%X back=%d newb=%d space=%d pos=%d\n",read,back,newb,space,pos); // reduce space if needed: if(space>s->buffer_size-pos) space=s->buffer_size-pos; // if(space>32768) space=32768; // limit one-time block size if(space>4*s->sector_size) space=4*s->sector_size; // if(s->seek_lock) return 0; // FIXME #if 1 // back+newb+space <= buffer_size back2=s->buffer_size-(space+newb); // max back size if(s->min_filepos<(read-back2)) s->min_filepos=read-back2; #else s->min_filepos=read-back; // avoid seeking-back to temp area... #endif // .... //printf("Buffer fill: %d bytes of %d\n",space,s->buffer_size); //len=stream_fill_buffer(s->stream); //memcpy(&s->buffer[pos],s->stream->buffer,len); // avoid this extra copy! // .... len=stream_read(s->stream,&s->buffer[pos],space); if(!len) s->eof=1; s->max_filepos+=len; if(pos+len>=s->buffer_size){ // wrap... s->offset+=s->buffer_size; } return len; }
static demuxer_t* demux_open_roq(demuxer_t* demuxer) { sh_video_t *sh_video = NULL; sh_audio_t *sh_audio = NULL; roq_data_t *roq_data = malloc(sizeof(roq_data_t)); int chunk_id; int chunk_size; int chunk_arg; int last_chunk_id = 0; int largest_audio_chunk = 0; int fps; roq_data->total_chunks = 0; roq_data->current_chunk = 0; roq_data->total_video_chunks = 0; roq_data->chunks = NULL; // position the stream and start traversing stream_seek(demuxer->stream, 6); fps = stream_read_word_le(demuxer->stream); while (!stream_eof(demuxer->stream)) { chunk_id = stream_read_word_le(demuxer->stream); chunk_size = stream_read_dword_le(demuxer->stream); chunk_arg = stream_read_word_le(demuxer->stream); // this is the only useful header info in the file if (chunk_id == RoQ_INFO) { // there should only be one RoQ_INFO chunk per file if (sh_video) { mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Found more than one RoQ_INFO chunk\n"); stream_skip(demuxer->stream, 8); } else { // this is a good opportunity to create a video stream header sh_video = new_sh_video(demuxer, 0); // make sure the demuxer knows about the new stream header demuxer->video->sh = sh_video; // make sure that the video demuxer stream header knows about its // parent video demuxer stream sh_video->ds = demuxer->video; sh_video->disp_w = stream_read_word_le(demuxer->stream); sh_video->disp_h = stream_read_word_le(demuxer->stream); stream_skip(demuxer->stream, 4); // custom fourcc for internal MPlayer use sh_video->format = mmioFOURCC('R', 'o', 'Q', 'V'); // constant frame rate sh_video->fps = fps; sh_video->frametime = 1 / sh_video->fps; } } else if ((chunk_id == RoQ_SOUND_MONO) || (chunk_id == RoQ_SOUND_STEREO)) { // create the audio stream header if it hasn't been created it if (sh_audio == NULL) { // make the header first sh_audio = new_sh_audio(demuxer, 0); // make sure the demuxer knows about the new stream header demuxer->audio->sh = sh_audio; // make sure that the audio demuxer stream header knows about its // parent audio demuxer stream sh_audio->ds = demuxer->audio; // go through the bother of making a WAVEFORMATEX structure sh_audio->wf = malloc(sizeof(WAVEFORMATEX)); // custom fourcc for internal MPlayer use sh_audio->format = mmioFOURCC('R', 'o', 'Q', 'A'); if (chunk_id == RoQ_SOUND_STEREO) sh_audio->wf->nChannels = 2; else sh_audio->wf->nChannels = 1; // always 22KHz, 16-bit sh_audio->wf->nSamplesPerSec = 22050; sh_audio->wf->wBitsPerSample = 16; } // index the chunk roq_data->chunks = (roq_chunk_t *)realloc(roq_data->chunks, (roq_data->total_chunks + 1) * sizeof (roq_chunk_t)); roq_data->chunks[roq_data->total_chunks].chunk_type = CHUNK_TYPE_AUDIO; roq_data->chunks[roq_data->total_chunks].chunk_offset = stream_tell(demuxer->stream) - 8; roq_data->chunks[roq_data->total_chunks].chunk_size = chunk_size + 8; roq_data->chunks[roq_data->total_chunks].running_audio_sample_count = roq_data->total_audio_sample_count; // audio housekeeping if (chunk_size > largest_audio_chunk) largest_audio_chunk = chunk_size; roq_data->total_audio_sample_count += (chunk_size / sh_audio->wf->nChannels); stream_skip(demuxer->stream, chunk_size); roq_data->total_chunks++; } else if ((chunk_id == RoQ_QUAD_CODEBOOK) || ((chunk_id == RoQ_QUAD_VQ) && (last_chunk_id != RoQ_QUAD_CODEBOOK))) { // index a new chunk if it's a codebook or quad VQ not following a // codebook roq_data->chunks = (roq_chunk_t *)realloc(roq_data->chunks, (roq_data->total_chunks + 1) * sizeof (roq_chunk_t)); roq_data->chunks[roq_data->total_chunks].chunk_type = CHUNK_TYPE_VIDEO; roq_data->chunks[roq_data->total_chunks].chunk_offset = stream_tell(demuxer->stream) - 8; roq_data->chunks[roq_data->total_chunks].chunk_size = chunk_size + 8; roq_data->chunks[roq_data->total_chunks].video_chunk_number = roq_data->total_video_chunks++; stream_skip(demuxer->stream, chunk_size); roq_data->total_chunks++; } else if ((chunk_id == RoQ_QUAD_VQ) && (last_chunk_id == RoQ_QUAD_CODEBOOK)) { // if it's a quad VQ chunk following a codebook chunk, extend the last // chunk roq_data->chunks[roq_data->total_chunks - 1].chunk_size += (chunk_size + 8); stream_skip(demuxer->stream, chunk_size); } else if (!stream_eof(demuxer->stream)) { mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Unknown RoQ chunk ID: %04X\n", chunk_id); } last_chunk_id = chunk_id; } // minimum output buffer size = largest audio chunk * 2, since each byte // in the DPCM encoding effectively represents 1 16-bit sample // (store it in wf->nBlockAlign for the time being since init_audio() will // step on it anyway) if (sh_audio) sh_audio->wf->nBlockAlign = largest_audio_chunk * 2; roq_data->current_chunk = 0; demuxer->priv = roq_data; stream_reset(demuxer->stream); return demuxer; }
static struct bgp_nexthop_cache * zlookup_read (void) { struct stream *s; uint16_t length; u_char marker; u_char version; uint16_t command __attribute__((unused)); int nbytes __attribute__((unused)); struct in_addr raddr __attribute__((unused)); uint32_t metric; int i; u_char nexthop_num; struct nexthop *nexthop; struct bgp_nexthop_cache *bnc; s = zlookup->ibuf; stream_reset (s); /* nbytes not being checked */ nbytes = stream_read (s, zlookup->sock, 2); length = stream_getw (s); nbytes = stream_read (s, zlookup->sock, length - 2); marker = stream_getc (s); version = stream_getc (s); if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER) { zlog_err("%s: socket %d version mismatch, marker %d, version %d", __func__, zlookup->sock, marker, version); return NULL; } /* XXX: not checking command */ command = stream_getw (s); /* XXX: not doing anything with raddr */ raddr.s_addr = stream_get_ipv4 (s); metric = stream_getl (s); nexthop_num = stream_getc (s); if (nexthop_num) { bnc = bnc_new (); bnc->valid = 1; bnc->metric = metric; bnc->nexthop_num = nexthop_num; for (i = 0; i < nexthop_num; i++) { nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop)); nexthop->type = stream_getc (s); switch (nexthop->type) { case ZEBRA_NEXTHOP_IPV4: nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s); break; case ZEBRA_NEXTHOP_IPV4_IFINDEX: nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s); nexthop->ifindex = stream_getl (s); break; case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: nexthop->ifindex = stream_getl (s); break; default: /* do nothing */ break; } bnc_nexthop_add (bnc, nexthop); } } else return NULL; return bnc; }
static void *discovery_write_raw( struct disk *d, unsigned int tracknr, struct stream *s) { struct track_info *ti = &d->di->track[tracknr]; uint16_t sync, csum, sum, chk1, chk2, len1, len2;; uint16_t raw[2*ti->len/2], dat[(ti->len+6)/2], craw[2]; unsigned int i, k; char *block; for (k = 0; k < ARRAY_SIZE(syncs); k++) { sync = syncs[k]; while (stream_next_bit(s) != -1) { if ((uint16_t)s->word != sync) continue; ti->data_bitoff = s->index_offset_bc - 15; if (stream_next_bytes(s, craw, 4) == -1) break; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &sum); if (ti->type != TRKTYP_hybris && be16toh(sum) != sync) continue; if (stream_next_bytes(s, craw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &chk1); if (stream_next_bytes(s, craw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &len1); if (be16toh(len1) != (uint16_t)ti->len) continue; if (stream_next_bytes(s, craw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &len2); if (stream_next_bytes(s, raw, 2*ti->len) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, ti->len, raw, dat); if (stream_next_bytes(s, craw, 4) == -1) goto fail; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &chk2); sum = discovery_sum(sum,0); sum = discovery_sum(chk1,sum); sum = discovery_sum(len1,sum); sum = discovery_sum(len2,sum); for (i = 0 ; i < ti->len/2; i++) sum = discovery_sum(dat[i], sum); sum = discovery_sum(chk2,sum); if (stream_next_bytes(s, craw, 4) == -1) break; mfm_decode_bytes(bc_mfm_even_odd, 2, craw, &csum); if (sum != be16toh(csum)) continue; /* No calculation for the data length and chk1 depends * on length in cases when the length is less than 0x1880. * dat is extended by 6 bytes. */ dat[ti->len/2] = be16toh(chk1); dat[ti->len/2+1] = be16toh(len2); dat[ti->len/2+2] = sync; stream_next_index(s); ti->total_bits = (s->track_len_bc > 102500) ? (s->track_len_bc > 104400) ? 108000 : 104300 : 102300; block = memalloc(ti->len+6); memcpy(block, dat, ti->len+6); set_all_sectors_valid(ti); return block; } stream_reset(s); } fail: return NULL; }
/* basic parsing test */ static void parse_test (struct peer *peer, struct test_segment *t, int type) { int ret; int capability = 0; as_t as4 = 0; int oldfailed = failed; int len = t->len; #define RANDOM_FUZZ 35 stream_reset (peer->ibuf); stream_put (peer->ibuf, NULL, RANDOM_FUZZ); stream_set_getp (peer->ibuf, RANDOM_FUZZ); switch (type) { case CAPABILITY: stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP); stream_putc (peer->ibuf, t->len); break; case DYNCAP: /* for (i = 0; i < BGP_MARKER_SIZE; i++) stream_putc (peer->, 0xff); stream_putw (s, 0); stream_putc (s, BGP_MSG_CAPABILITY);*/ break; } stream_write (peer->ibuf, t->data, t->len); printf ("%s: %s\n", t->name, t->desc); switch (type) { case CAPABILITY: len += 2; /* to cover the OPT-Param header */ case OPT_PARAM: printf ("len: %u\n", len); /* peek_for_as4 wants getp at capibility*/ as4 = peek_for_as4_capability (peer, len); printf ("peek_for_as4: as4 is %u\n", as4); /* and it should leave getp as it found it */ assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ); ret = bgp_open_option_parse (peer, len, &capability); break; case DYNCAP: ret = bgp_capability_receive (peer, t->len); break; default: printf ("unknown type %u\n", type); exit(1); } if (!ret && t->validate_afi) { safi_t safi = t->safi; if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid) failed++; printf ("MP: %u/%u (%u): recv %u, nego %u\n", t->afi, t->safi, safi, peer->afc_recv[t->afi][safi], peer->afc_nego[t->afi][safi]); if (t->afi_valid == VALID_AFI) { if (!peer->afc_recv[t->afi][safi]) failed++; if (!peer->afc_nego[t->afi][safi]) failed++; } } if (as4 != t->peek_for) { printf ("as4 %u != %u\n", as4, t->peek_for); failed++; } printf ("parsed?: %s\n", ret ? "no" : "yes"); if (ret != t->parses) failed++; if (tty) printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET : VT100_GREEN "OK" VT100_RESET); else printf ("%s", (failed > oldfailed) ? "failed!" : "OK" ); if (failed) printf (" (%u)", failed); printf ("\n\n"); }
/* Handler of zebra service request. */ static int zebra_client_read (struct thread *thread) { int sock; struct zserv *client; size_t already; uint16_t length, command; uint8_t marker, version; /* Get thread data. Reset reading thread because I'm running. */ sock = THREAD_FD (thread); client = THREAD_ARG (thread); client->t_read = NULL; if (client->t_suicide) { zebra_client_close(client); return -1; } /* Read length and command (if we don't have it already). */ if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE) { ssize_t nbyte; if (((nbyte = stream_read_try (client->ibuf, sock, ZEBRA_HEADER_SIZE-already)) == 0) || (nbyte == -1)) { if (IS_ZEBRA_DEBUG_EVENT) zlog_debug ("connection closed socket [%d]", sock); zebra_client_close (client); return -1; } if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already)) { /* Try again later. */ zebra_event (ZEBRA_READ, sock, client); return 0; } already = ZEBRA_HEADER_SIZE; } /* Reset to read from the beginning of the incoming packet. */ stream_set_getp(client->ibuf, 0); /* Fetch header values */ length = stream_getw (client->ibuf); marker = stream_getc (client->ibuf); version = stream_getc (client->ibuf); command = stream_getw (client->ibuf); if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) { zlog_err("%s: socket %d version mismatch, marker %d, version %d", __func__, sock, marker, version); zebra_client_close (client); return -1; } if (length < ZEBRA_HEADER_SIZE) { zlog_warn("%s: socket %d message length %u is less than header size %d", __func__, sock, length, ZEBRA_HEADER_SIZE); zebra_client_close (client); return -1; } if (length > STREAM_SIZE(client->ibuf)) { zlog_warn("%s: socket %d message length %u exceeds buffer size %lu", __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf)); zebra_client_close (client); return -1; } /* Read rest of data. */ if (already < length) { ssize_t nbyte; if (((nbyte = stream_read_try (client->ibuf, sock, length-already)) == 0) || (nbyte == -1)) { if (IS_ZEBRA_DEBUG_EVENT) zlog_debug ("connection closed [%d] when reading zebra data", sock); zebra_client_close (client); return -1; } if (nbyte != (ssize_t)(length-already)) { /* Try again later. */ zebra_event (ZEBRA_READ, sock, client); return 0; } } length -= ZEBRA_HEADER_SIZE; /* Debug packet information. */ if (IS_ZEBRA_DEBUG_EVENT) zlog_debug ("zebra message comes from socket [%d]", sock); if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) zlog_debug ("zebra message received [%s] %d", zserv_command_string (command), length); switch (command) { case ZEBRA_ROUTER_ID_ADD: zread_router_id_add (client, length); break; case ZEBRA_ROUTER_ID_DELETE: zread_router_id_delete (client, length); break; case ZEBRA_INTERFACE_ADD: zread_interface_add (client, length); break; case ZEBRA_INTERFACE_DELETE: zread_interface_delete (client, length); break; case ZEBRA_IPV4_ROUTE_ADD: zread_ipv4_add (client, length); break; case ZEBRA_IPV4_ROUTE_DELETE: zread_ipv4_delete (client, length); break; #ifdef HAVE_IPV6 case ZEBRA_IPV6_ROUTE_ADD: zread_ipv6_add (client, length); break; case ZEBRA_IPV6_ROUTE_DELETE: zread_ipv6_delete (client, length); break; #endif /* HAVE_IPV6 */ case ZEBRA_REDISTRIBUTE_ADD: zebra_redistribute_add (command, client, length); break; case ZEBRA_REDISTRIBUTE_DELETE: zebra_redistribute_delete (command, client, length); break; case ZEBRA_REDISTRIBUTE_DEFAULT_ADD: zebra_redistribute_default_add (command, client, length); break; case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE: zebra_redistribute_default_delete (command, client, length); break; case ZEBRA_IPV4_NEXTHOP_LOOKUP: zread_ipv4_nexthop_lookup (client, length); break; #ifdef HAVE_IPV6 case ZEBRA_IPV6_NEXTHOP_LOOKUP: zread_ipv6_nexthop_lookup (client, length); break; #endif /* HAVE_IPV6 */ case ZEBRA_IPV4_IMPORT_LOOKUP: zread_ipv4_import_lookup (client, length); break; case ZEBRA_HELLO: zread_hello (client); break; default: zlog_info ("Zebra received unknown command %d", command); break; } if (client->t_suicide) { /* No need to wait for thread callback, just kill immediately. */ zebra_client_close(client); return -1; } stream_reset (client->ibuf); zebra_event (ZEBRA_READ, sock, client); return 0; }
static demuxer_t * demux_open_pva (demuxer_t * demuxer) { sh_video_t *sh_video = new_sh_video(demuxer,0); sh_audio_t *sh_audio = new_sh_audio(demuxer,0, NULL); pva_priv_t * priv; stream_reset(demuxer->stream); stream_seek(demuxer->stream,0); priv=malloc(sizeof(pva_priv_t)); if(demuxer->stream->type!=STREAMTYPE_FILE) demuxer->seekable=0; else demuxer->seekable=1; demuxer->priv=priv; memset(demuxer->priv,0,sizeof(pva_priv_t)); if(!pva_sync(demuxer)) { mp_msg(MSGT_DEMUX,MSGL_ERR,"Not a PVA file.\n"); return NULL; } //printf("priv->just_synced %s after initial sync!\n",priv->just_synced?"set":"UNSET"); demuxer->video->sh=sh_video; //printf("demuxer->stream->end_pos= %d\n",demuxer->stream->end_pos); mp_msg(MSGT_DEMUXER,MSGL_INFO,"Opened PVA demuxer...\n"); /* * Audio and Video codecs: * the PVA spec only allows MPEG2 video and MPEG layer II audio. No need to check the formats then. * Moreover, there would be no way to do that since the PVA stream format has no fields to describe * the used codecs. */ sh_video->format=0x10000002; sh_video->ds=demuxer->video; /* printf("demuxer->video->id==%d\n",demuxer->video->id); printf("demuxer->audio->id==%d\n",demuxer->audio->id); */ demuxer->audio->id = 0; demuxer->audio->sh=sh_audio; sh_audio->format=0x50; sh_audio->ds=demuxer->audio; demuxer->movi_start=0; demuxer->movi_end=demuxer->stream->end_pos; priv->last_video_pts=-1; priv->last_audio_pts=-1; return demuxer; }
/* * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following * situations: * - when the client starts up, and requests default information * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the * - case of rip, ripngd, ospfd and ospf6d, when the client sends a * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd, * - when the zebra server redistributes routes after it updates its rib * * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when: * - a "ip route" or "ipv6 route" vty command is issued, a prefix is * - deleted from zebra's rib, and this info * has to be redistributed to the clients * * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the * zebra server when the client wants to tell the zebra server to add a * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the * same message being sent back and forth, this function and * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code * duplication. */ int zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p, struct rib *rib) { int psize; struct stream *s; struct nexthop *nexthop; unsigned long nhnummark = 0, messmark = 0; int nhnum = 0; u_char zapi_flags = 0; s = client->obuf; stream_reset (s); zserv_create_header (s, cmd); /* Put type and nexthop. */ stream_putc (s, rib->type); stream_putc (s, rib->flags); /* marker for message flags field */ messmark = stream_get_endp (s); stream_putc (s, 0); /* Prefix. */ psize = PSIZE (p->prefixlen); stream_putc (s, p->prefixlen); stream_write (s, (u_char *) & p->u.prefix, psize); /* * XXX The message format sent by zebra below does not match the format * of the corresponding message expected by the zebra server * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly, * (is there a bug on the client side if more than one segment is sent?) * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX * is hard-coded. */ /* Nexthop */ for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) { if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP); SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX); if (nhnummark == 0) { nhnummark = stream_get_endp (s); stream_putc (s, 1); /* placeholder */ } nhnum++; switch(nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: stream_put_in_addr (s, &nexthop->gate.ipv4); break; #ifdef HAVE_IPV6 case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: case NEXTHOP_TYPE_IPV6_IFNAME: stream_write (s, (u_char *) &nexthop->gate.ipv6, 16); break; #endif default: if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV4_ROUTE_DELETE) { struct in_addr empty; memset (&empty, 0, sizeof (struct in_addr)); stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN); } else { struct in6_addr empty; memset (&empty, 0, sizeof (struct in6_addr)); stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN); } } /* Interface index. */ stream_putc (s, 1); stream_putl (s, nexthop->ifindex); break; } } /* Metric */ if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD) { SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE); stream_putc (s, rib->distance); SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC); stream_putl (s, rib->metric); } /* write real message flags value */ stream_putc_at (s, messmark, zapi_flags); /* Write next-hop number */ if (nhnummark) stream_putc_at (s, nhnummark, nhnum); /* Write packet size. */ stream_putw_at (s, 0, stream_get_endp (s)); return zebra_server_send_message(client); }
/* validate the given aspath */ static int validate (struct aspath *as, const struct test_spec *sp) { size_t bytes, bytes4; int fails = 0; const u_char *out; static struct stream *s; struct aspath *asinout, *asconfeddel, *asstr, *as4; out = aspath_snmp_pathseg (as, &bytes); asinout = make_aspath (out, bytes, 0); /* Excercise AS4 parsing a bit, with a dogfood test */ if (!s) s = stream_new (4096); bytes4 = aspath_put (s, as, 1); as4 = make_aspath (STREAM_DATA(s), bytes4, 1); asstr = aspath_str2aspath (sp->shouldbe); asconfeddel = aspath_delete_confed_seq (aspath_dup (asinout)); printf ("got: %s\n", aspath_print(as)); /* the parsed path should match the specified 'shouldbe' string. * We should pass the "eat our own dog food" test, be able to output * this path and then input it again. Ie the path resulting from: * * aspath_parse(aspath_put(as)) * * should: * * - also match the specified 'shouldbe' value * - hash to same value as original path * - have same hops and confed counts as original, and as the * the specified counts * * aspath_str2aspath() and shouldbe should match * * We do the same for: * * aspath_parse(aspath_put(as,USE32BIT)) * * Confederation related tests: * - aspath_delete_confed_seq(aspath) should match shouldbe_confed * - aspath_delete_confed_seq should be idempotent. */ if (strcmp(aspath_print (as), sp->shouldbe) /* hash validation */ || (aspath_key_make (as) != aspath_key_make (asinout)) /* by string */ || strcmp(aspath_print (asinout), sp->shouldbe) /* By 4-byte parsing */ || strcmp(aspath_print (as4), sp->shouldbe) /* by various path counts */ || (aspath_count_hops (as) != sp->hops) || (aspath_count_confeds (as) != sp->confeds) || (aspath_count_hops (asinout) != sp->hops) || (aspath_count_confeds (asinout) != sp->confeds)) { failed++; fails++; printf ("shouldbe:\n%s\n", sp->shouldbe); printf ("as4:\n%s\n", aspath_print (as4)); printf ("hash keys: in: %d out->in: %d\n", aspath_key_make (as), aspath_key_make (asinout)); printf ("hops: %d, counted %d %d\n", sp->hops, aspath_count_hops (as), aspath_count_hops (asinout) ); printf ("confeds: %d, counted %d %d\n", sp->confeds, aspath_count_confeds (as), aspath_count_confeds (asinout)); printf ("out->in:\n%s\nbytes: ", aspath_print(asinout)); printbytes (out, bytes); } /* basic confed related tests */ if ((aspath_print (asconfeddel) == NULL && sp->shouldbe_delete_confed != NULL) || (aspath_print (asconfeddel) != NULL && sp->shouldbe_delete_confed == NULL) || strcmp(aspath_print (asconfeddel), sp->shouldbe_delete_confed) /* delete_confed_seq should be idempotent */ || (aspath_key_make (asconfeddel) != aspath_key_make (aspath_delete_confed_seq (asconfeddel)))) { failed++; fails++; printf ("confed_del: %s\n", aspath_print (asconfeddel)); printf ("should be: %s\n", sp->shouldbe_delete_confed); } /* aspath_str2aspath test */ if ((aspath_print (asstr) == NULL && sp->shouldbe != NULL) || (aspath_print (asstr) != NULL && sp->shouldbe == NULL) || strcmp(aspath_print (asstr), sp->shouldbe)) { failed++; fails++; printf ("asstr: %s\n", aspath_print (asstr)); } /* loop, private and first as checks */ if ((sp->does_loop && aspath_loop_check (as, sp->does_loop) == 0) || (sp->doesnt_loop && aspath_loop_check (as, sp->doesnt_loop) != 0) || (aspath_private_as_check (as) != sp->private_as) || (aspath_firstas_check (as,sp->first) && sp->first == 0)) { failed++; fails++; printf ("firstas: %d, got %d\n", sp->first, aspath_firstas_check (as,sp->first)); printf ("loop does: %d %d, doesnt: %d %d\n", sp->does_loop, aspath_loop_check (as, sp->does_loop), sp->doesnt_loop, aspath_loop_check (as, sp->doesnt_loop)); printf ("private check: %d %d\n", sp->private_as, aspath_private_as_check (as)); } aspath_unintern (asinout); aspath_unintern (as4); aspath_free (asconfeddel); aspath_free (asstr); stream_reset (s); return fails; }
static int zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr) { struct stream *s; struct rib *rib; unsigned long nump; u_char num; struct nexthop *nexthop; /* Lookup nexthop. */ rib = rib_match_ipv4 (addr); /* Get output stream. */ s = client->obuf; stream_reset (s); /* Fill in result. */ zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP); stream_put_in_addr (s, &addr); if (rib) { if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) zlog_debug("%s: Matching rib entry found.", __func__); stream_putl (s, rib->metric); num = 0; nump = stream_get_endp(s); stream_putc (s, 0); for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { stream_putc (s, nexthop->type); switch (nexthop->type) { case ZEBRA_NEXTHOP_IPV4: stream_put_in_addr (s, &nexthop->gate.ipv4); break; case ZEBRA_NEXTHOP_IPV4_IFINDEX: stream_put_in_addr (s, &nexthop->gate.ipv4); stream_putl (s, nexthop->ifindex); break; case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: stream_putl (s, nexthop->ifindex); break; default: /* do nothing */ break; } num++; } stream_putc_at (s, nump, num); } else { if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) zlog_debug("%s: No matching rib entry found.", __func__); stream_putl (s, 0); stream_putc (s, 0); } stream_putw_at (s, 0, stream_get_endp (s)); return zebra_server_send_message(client); }
static demuxer_t* demux_open_avi(demuxer_t* demuxer){ demux_stream_t *d_audio=demuxer->audio; demux_stream_t *d_video=demuxer->video; sh_audio_t *sh_audio=NULL; sh_video_t *sh_video=NULL; avi_priv_t* priv=calloc(1, sizeof(avi_priv_t)); demuxer->priv=(void*)priv; priv->index_mode = -1; priv->last_fccType = 0; priv->last_fccHandler = 0; //---- AVI header: read_avi_header(demuxer,(demuxer->stream->flags & MP_STREAM_SEEK_BW)?priv->index_mode:-2); if(priv->idx_size==0&&(demuxer->stream->flags & MP_STREAM_SEEK_BW)){ priv->index_mode=1; stream_seek(demuxer->stream,0); read_avi_header(demuxer,1); } if(demuxer->audio->id>=0 && !demuxer->a_streams[demuxer->audio->id]){ mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_InvalidAudioStreamNosound,demuxer->audio->id); demuxer->audio->id=-2; // disabled } if(demuxer->video->id>=0 && !demuxer->v_streams[demuxer->video->id]){ mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_InvalidAudioStreamUsingDefault,demuxer->video->id); demuxer->video->id=-1; // autodetect } stream_reset(demuxer->stream); stream_seek(demuxer->stream,demuxer->movi_start); if(priv->idx_size>1){ // decide index format: #if 1 if((AVI_IDX_OFFSET(&((AVIINDEXENTRY *)priv->idx)[0])<demuxer->movi_start || AVI_IDX_OFFSET(&((AVIINDEXENTRY *)priv->idx)[1])<demuxer->movi_start )&& !priv->isodml) priv->idx_offset=demuxer->movi_start-4; #else if(AVI_IDX_OFFSET(&((AVIINDEXENTRY *)priv->idx)[0])<demuxer->movi_start) priv->idx_offset=demuxer->movi_start-4; #endif mp_msg(MSGT_DEMUX,MSGL_V,"AVI index offset: 0x%X (movi=0x%X idx0=0x%X idx1=0x%X)\n", (int)priv->idx_offset,(int)demuxer->movi_start, (int)((AVIINDEXENTRY *)priv->idx)[0].dwChunkOffset, (int)((AVIINDEXENTRY *)priv->idx)[1].dwChunkOffset); } if(priv->idx_size>0){ // check that file is non-interleaved: int i; loff_t a_pos=-1; loff_t v_pos=-1; for(i=0;i<priv->idx_size;i++){ AVIINDEXENTRY* idx=&((AVIINDEXENTRY *)priv->idx)[i]; demux_stream_t* ds=demux_avi_select_stream(demuxer,idx->ckid); loff_t pos = priv->idx_offset + AVI_IDX_OFFSET(idx); if(a_pos==-1 && ds==demuxer->audio){ a_pos=pos; if(v_pos!=-1) break; } if(v_pos==-1 && ds==demuxer->video){ v_pos=pos; if(a_pos!=-1) break; } } if(v_pos==-1){ mp_msg(MSGT_DEMUX,MSGL_ERR,"AVI_NI: " MSGTR_MissingVideoStream); return NULL; } if(a_pos==-1){ d_audio->sh=sh_audio=NULL; } else { if(force_ni || abs(a_pos-v_pos)>0x100000){ // distance > 1MB mp_msg(MSGT_DEMUX,MSGL_INFO,MSGTR_NI_Message,force_ni?MSGTR_NI_Forced:MSGTR_NI_Detected); demuxer->type=DEMUXER_TYPE_AVI_NI; // HACK!!!! demuxer->desc=&demuxer_desc_avi_ni; // HACK!!!! pts_from_bps=1; // force BPS sync! } } } else { // no index if(force_ni){ mp_msg(MSGT_DEMUX,MSGL_INFO,MSGTR_UsingNINI); demuxer->type=DEMUXER_TYPE_AVI_NINI; // HACK!!!! demuxer->desc=&demuxer_desc_avi_nini; // HACK!!!! priv->idx_pos_a= priv->idx_pos_v=demuxer->movi_start; pts_from_bps=1; // force BPS sync! } demuxer->seekable=0; } if(!ds_fill_buffer(d_video)){ mp_msg(MSGT_DEMUX,MSGL_ERR,"AVI: " MSGTR_MissingVideoStreamBug); return NULL; } sh_video=d_video->sh;sh_video->ds=d_video; if(d_audio->id!=-2){ mp_msg(MSGT_DEMUX,MSGL_V,"AVI: Searching for audio stream (id:%d)\n",d_audio->id); if(!priv->audio_streams || !ds_fill_buffer(d_audio)){ mp_msg(MSGT_DEMUX,MSGL_INFO,"AVI: " MSGTR_MissingAudioStream); d_audio->sh=sh_audio=NULL; } else { sh_audio=d_audio->sh;sh_audio->ds=d_audio; } } // calculating audio/video bitrate: if(priv->idx_size>0){ // we have index, let's count 'em! AVIINDEXENTRY *idx = priv->idx; int64_t vsize=0; int64_t asize=0; size_t vsamples=0; size_t asamples=0; int i; for(i=0;i<priv->idx_size;i++){ int id=avi_stream_id(idx[i].ckid); unsigned len=idx[i].dwChunkLength; if(sh_video->ds->id == id) { vsize+=len; ++vsamples; } else if(sh_audio && sh_audio->ds->id == id) { asize+=len; asamples+=(len+priv->audio_block_size-1)/priv->audio_block_size; } } mp_msg(MSGT_DEMUX, MSGL_V, "AVI video size=%"PRId64" (%zu) audio size=%"PRId64" (%zu)\n", vsize, vsamples, asize, asamples); priv->numberofframes=vsamples; if(priv->numberofframes<=1) // bad video header, try to get number of frames from audio if(sh_audio && sh_audio->wf->nAvgBytesPerSec) priv->numberofframes=sh_video->fps*sh_audio->audio.dwLength/sh_audio->audio.dwRate*sh_audio->audio.dwScale; sh_video->i_bps=((float)vsize/(float)vsamples)*(float)sh_video->video.dwRate/(float)sh_video->video.dwScale; if(sh_audio) sh_audio->i_bps=((float)asize/(float)asamples)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; } else { // guessing, results may be inaccurate: int64_t vsize; int64_t asize=0; if((priv->numberofframes=sh_video->video.dwLength)<=1) // bad video header, try to get number of frames from audio if(sh_audio && sh_audio->wf->nAvgBytesPerSec) priv->numberofframes=sh_video->fps*sh_audio->audio.dwLength/sh_audio->audio.dwRate*sh_audio->audio.dwScale; if(priv->numberofframes<=1){ mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CouldntDetFNo); priv->numberofframes=0; } if(sh_audio){ if(sh_audio->wf->nAvgBytesPerSec && sh_audio->audio.dwSampleSize!=1){ asize=(float)sh_audio->wf->nAvgBytesPerSec*sh_audio->audio.dwLength*sh_audio->audio.dwScale/sh_audio->audio.dwRate; } else { asize=sh_audio->audio.dwLength; sh_audio->i_bps=(float)asize/(sh_video->frametime*priv->numberofframes); } } vsize=demuxer->movi_end-demuxer->movi_start-asize-8*priv->numberofframes; mp_msg(MSGT_DEMUX,MSGL_V,"AVI video size=%"PRId64" (%u) audio size=%"PRId64"\n",vsize,priv->numberofframes,asize); sh_video->i_bps=(float)vsize/(sh_video->frametime*priv->numberofframes); } return demuxer; }
static int zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p) { struct stream *s; struct rib *rib; unsigned long nump; u_char num; struct nexthop *nexthop; /* Lookup nexthop. */ rib = rib_lookup_ipv4 (p); /* Get output stream. */ s = client->obuf; stream_reset (s); /* Fill in result. */ zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP); stream_put_in_addr (s, &p->prefix); if (rib) { stream_putl (s, rib->metric); num = 0; nump = stream_get_endp(s); stream_putc (s, 0); for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { stream_putc (s, nexthop->type); switch (nexthop->type) { case ZEBRA_NEXTHOP_IPV4: stream_put_in_addr (s, &nexthop->gate.ipv4); break; case ZEBRA_NEXTHOP_IPV4_IFINDEX: stream_put_in_addr (s, &nexthop->gate.ipv4); stream_putl (s, nexthop->ifindex); break; case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: stream_putl (s, nexthop->ifindex); break; default: /* do nothing */ break; } num++; } stream_putc_at (s, nump, num); } else { stream_putl (s, 0); stream_putc (s, 0); } stream_putw_at (s, 0, stream_get_endp (s)); return zebra_server_send_message(client); }
static int bgp_import_check (struct prefix *p, u_int32_t *igpmetric, struct in_addr *igpnexthop) { struct stream *s; int ret; u_int16_t length, command; u_char version, marker; int nbytes; struct in_addr addr; struct in_addr nexthop; u_int32_t metric = 0; u_char nexthop_num; u_char nexthop_type; /* If lookup connection is not available return valid. */ if (zlookup->sock < 0) { if (igpmetric) *igpmetric = 0; return 1; } /* Send query to the lookup connection */ s = zlookup->obuf; stream_reset (s); zclient_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP); stream_putc (s, p->prefixlen); stream_put_in_addr (s, &p->u.prefix4); stream_putw_at (s, 0, stream_get_endp (s)); /* Write the packet. */ ret = writen (zlookup->sock, s->data, stream_get_endp (s)); if (ret < 0) { zlog_err ("can't write to zlookup->sock"); close (zlookup->sock); zlookup->sock = -1; return 1; } if (ret == 0) { zlog_err ("zlookup->sock connection closed"); close (zlookup->sock); zlookup->sock = -1; return 1; } /* Get result. */ stream_reset (s); /* Fetch length. */ nbytes = stream_read (s, zlookup->sock, 2); length = stream_getw (s); /* Fetch whole data. */ nbytes = stream_read (s, zlookup->sock, length - 2); marker = stream_getc (s); version = stream_getc (s); if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER) { zlog_err("%s: socket %d version mismatch, marker %d, version %d", __func__, zlookup->sock, marker, version); return 0; } command = stream_getw (s); addr.s_addr = stream_get_ipv4 (s); metric = stream_getl (s); nexthop_num = stream_getc (s); /* Set IGP metric value. */ if (igpmetric) *igpmetric = metric; /* If there is nexthop then this is active route. */ if (nexthop_num) { nexthop.s_addr = 0; nexthop_type = stream_getc (s); if (nexthop_type == ZEBRA_NEXTHOP_IPV4) { nexthop.s_addr = stream_get_ipv4 (s); if (igpnexthop) *igpnexthop = nexthop; } else *igpnexthop = nexthop; return 1; } else return 0; }
int shim_sisis_read(struct thread * thread) { struct sisis_listener *listener; int sisis_sock; uint16_t length, command, checksum; int already; u_int ifindex; struct shim_interface * si; struct in6_addr src; char src_buf[INET6_ADDRSTRLEN]; struct in6_addr dst; char dst_buf[INET6_ADDRSTRLEN]; zlog_notice("Reading packet from SISIS connection!\n"); /* first of all get listener pointer. */ listener = THREAD_ARG (thread); sisis_sock = THREAD_FD (thread); if ((already = stream_get_endp(listener->ibuf)) < SV_HEADER_SIZE) { ssize_t nbytes; if (((nbytes = stream_read_try (listener->ibuf, sisis_sock, SV_HEADER_SIZE-already)) == 0) || (nbytes == -1)) { return -1; } if(nbytes != (SV_HEADER_SIZE - already)) { listener->thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; } already = SV_HEADER_SIZE; } stream_set_getp(listener->ibuf, 0); /* read header packet. */ length = stream_getw (listener->ibuf); command = stream_getw (listener->ibuf); // will be 0 so may be discarded stream_get (&src, listener->ibuf, sizeof (struct in6_addr)); stream_get (&dst, listener->ibuf, sizeof (struct in6_addr)); ifindex = stream_getl(listener->ibuf); checksum = stream_getw(listener->ibuf); inet_ntop(AF_INET6, &src, src_buf, sizeof(src_buf)); inet_ntop(AF_INET6, &dst, dst_buf, sizeof(dst_buf)); zlog_debug("SISIS: length: %d, command: %d, ifindex: %d, checksum: %d sock %d, src: %s, dst: %s\n", length, command, ifindex, checksum, sisis_sock, src_buf, dst_buf); if(length > STREAM_SIZE(listener->ibuf)) { struct stream * ns; zlog_warn("message size exceeds buffer size"); ns = stream_new(length); stream_copy(ns, listener->ibuf); stream_free(listener->ibuf); listener->ibuf = ns; } if(already < length) { ssize_t nbytes; if(((nbytes = stream_read_try(listener->ibuf, sisis_sock, length-already)) == 0) || nbytes == -1) { return -1; } if(nbytes != (length-already)) { listener->thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; } } length -= SV_HEADER_SIZE; switch(command) { case SV_JOIN_ALLSPF: zlog_debug("join allspf received"); shim_join_allspfrouters (ifindex); break; case SV_LEAVE_ALLSPF: zlog_debug("leave allspf received"); shim_leave_allspfrouters (ifindex); zlog_debug("index: %d\n", ifindex); break; case SV_JOIN_ALLD: zlog_debug("join alld received"); shim_join_alldrouters (ifindex); zlog_debug("index: %d", ifindex); break; case SV_LEAVE_ALLD: zlog_debug("leave alld received"); shim_leave_alldrouters (ifindex); zlog_debug("index: %d", ifindex); break; case SV_MESSAGE: zlog_debug("SISIS message received"); unsigned int num_of_addrs = number_of_sisis_addrs_for_process_type(SISIS_PTYPE_RIBCOMP_OSPF6); unsigned int num_of_listeners = number_of_listeners(); zlog_debug("num of listeners: %d, num of addrs: %d", num_of_listeners, num_of_addrs); float received_ratio = num_of_listeners/num_of_addrs; listener->chksum = checksum; if(received_ratio > (1/2)) { if(are_checksums_same()) { si = shim_interface_lookup_by_ifindex (ifindex); reset_checksums(); shim_send(&src, &dst, si, listener->ibuf, length); // shim_send(si->linklocal_addr, &dst, si, listener->ibuf, length); } else { zlog_notice("Checksums are not all the same"); } } else { zlog_notice("Not enough processes have sent their data: buffering ..."); } break; default: break; } if (sisis_sock < 0) /* Connection was closed during packet processing. */ return -1; /* Register read thread. */ stream_reset(listener->ibuf); /* prepare for next packet. */ listener->thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; }
void ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or) { u_char message; u_char distance; u_char flags; int psize; struct stream *s; struct ospf_path *path; struct listnode *node; if (zclient->redist[ZEBRA_ROUTE_OSPF]) { message = 0; flags = 0; /* OSPF pass nexthop and metric */ SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP); SET_FLAG (message, ZAPI_MESSAGE_METRIC); /* Distance value. */ distance = ospf_distance_apply (p, or); if (distance) SET_FLAG (message, ZAPI_MESSAGE_DISTANCE); /* Make packet. */ s = zclient->obuf; stream_reset (s); /* Put command, type, flags, message. */ zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD); stream_putc (s, ZEBRA_ROUTE_OSPF); stream_putc (s, flags); stream_putc (s, message); /* Put prefix information. */ psize = PSIZE (p->prefixlen); stream_putc (s, p->prefixlen); stream_write (s, (u_char *) & p->prefix, psize); /* Nexthop count. */ stream_putc (s, or->paths->count); /* Nexthop, ifindex, distance and metric information. */ for (ALL_LIST_ELEMENTS_RO (or->paths, node, path)) { if (path->nexthop.s_addr != INADDR_ANY) { stream_putc (s, ZEBRA_NEXTHOP_IPV4); stream_put_in_addr (s, &path->nexthop); } else { stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); if (path->oi) stream_putl (s, path->oi->ifp->ifindex); else stream_putl (s, 0); } if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) { char buf[2][INET_ADDRSTRLEN]; zlog_debug("Zebra: Route add %s/%d nexthop %s", inet_ntop(AF_INET, &p->prefix, buf[0], sizeof(buf[0])), p->prefixlen, inet_ntop(AF_INET, &path->nexthop, buf[1], sizeof(buf[1]))); } } if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) stream_putc (s, distance); if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) { if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) stream_putl (s, or->cost + or->u.ext.type2_cost); else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) stream_putl (s, or->u.ext.type2_cost); else stream_putl (s, or->cost); } stream_putw_at (s, 0, stream_get_endp (s)); zclient_send_message(zclient); }
int main (int argc, char **argv) { int ret; FILE *fp; struct stream *s; time_t now; int type; int subtype; size_t len; int source_as; int dest_as; int ifindex; int family; struct in_addr sip; struct in_addr dip; u_int16_t viewno, seq_num; struct prefix_ipv4 p; s = stream_new (10000); if (argc != 2) { fprintf (stderr, "Usage: %s FILENAME\n", argv[0]); exit (1); } fp = fopen (argv[1], "r"); if (!fp) { perror ("fopen"); exit (1); } while (1) { stream_reset (s); ret = fread (s->data, 12, 1, fp); if (!ret || feof (fp)) { printf ("END OF FILE\n"); break; } if (ferror (fp)) { printf ("ERROR OF FREAD\n"); break; } /* Extract header. */ now = stream_getl (s); type = stream_getw (s); subtype = stream_getw (s); len = stream_getl (s); printf ("TIME: %s", ctime (&now)); /* printf ("TYPE: %d/%d\n", type, subtype); */ if (type == MSG_PROTOCOL_BGP4MP) printf ("TYPE: BGP4MP"); else if (type == MSG_PROTOCOL_BGP4MP_ET) printf ("TYPE: BGP4MP_ET"); else if (type == MSG_TABLE_DUMP) printf ("TYPE: MSG_TABLE_DUMP"); else printf ("TYPE: Unknown %d", type); if (type == MSG_TABLE_DUMP) switch (subtype) { case AFI_IP: printf ("/AFI_IP\n"); break; case AFI_IP6: printf ("/AFI_IP6\n"); break; default: printf ("/UNKNOWN %d", subtype); break; } else { switch (subtype) { case BGP4MP_STATE_CHANGE: printf ("/CHANGE\n"); break; case BGP4MP_MESSAGE: printf ("/MESSAGE\n"); break; case BGP4MP_ENTRY: printf ("/ENTRY\n"); break; case BGP4MP_SNAPSHOT: printf ("/SNAPSHOT\n"); break; default: printf ("/UNKNOWN %d", subtype); break; } } printf ("len: %zd\n", len); ret = fread (s->data + 12, len, 1, fp); if (feof (fp)) { printf ("ENDOF FILE 2\n"); break; } if (ferror (fp)) { printf ("ERROR OF FREAD 2\n"); break; } /* printf ("now read %d\n", len); */ if (type == MSG_TABLE_DUMP) { u_char status; time_t originated; struct in_addr peer; u_int16_t attrlen; viewno = stream_getw (s); seq_num = stream_getw (s); printf ("VIEW: %d\n", viewno); printf ("SEQUENCE: %d\n", seq_num); /* start */ while (s->getp < len - 16) { p.prefix.s_addr = stream_get_ipv4 (s); p.prefixlen = stream_getc (s); printf ("PREFIX: %s/%d\n", inet_ntoa (p.prefix), p.prefixlen); status = stream_getc (s); originated = stream_getl (s); peer.s_addr = stream_get_ipv4 (s); source_as = stream_getw(s); printf ("FROM: %s AS%d\n", inet_ntoa (peer), source_as); printf ("ORIGINATED: %s", ctime (&originated)); attrlen = stream_getw (s); printf ("ATTRLEN: %d\n", attrlen); attr_parse (s, attrlen); printf ("STATUS: 0x%x\n", status); } } else { source_as = stream_getw (s); dest_as = stream_getw (s); printf ("source_as: %d\n", source_as); printf ("dest_as: %d\n", dest_as); ifindex = stream_getw (s); family = stream_getw (s); printf ("ifindex: %d\n", ifindex); printf ("family: %d\n", family); sip.s_addr = stream_get_ipv4 (s); dip.s_addr = stream_get_ipv4 (s); printf ("saddr: %s\n", inet_ntoa (sip)); printf ("daddr: %s\n", inet_ntoa (dip)); printf ("\n"); } } fclose (fp); return 0; }