*sticky = 0;
pnt++;
- seq_num = (*pnt++ << 24);
- seq_num |= (*pnt++ << 16);
- seq_num |= (*pnt++ << 8);
- seq_num |= (*pnt++);
-
+ pnt = ptr_get_be32(pnt, &seq_num);
+ (void)pnt; /* consume value */
return seq_num;
}
#include "memory.h"
#include "queue.h"
#include "filter.h"
+#include "stream.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_community.h"
str = pnt = XMALLOC(MTYPE_LCOMMUNITY_STR, 48);
ptr = (u_char *)lcomval.val;
- globaladmin = (*ptr++ << 24);
- globaladmin |= (*ptr++ << 16);
- globaladmin |= (*ptr++ << 8);
- globaladmin |= (*ptr++);
-
- localdata1 = (*ptr++ << 24);
- localdata1 |= (*ptr++ << 16);
- localdata1 |= (*ptr++ << 8);
- localdata1 |= (*ptr++);
-
- localdata2 = (*ptr++ << 24);
- localdata2 |= (*ptr++ << 16);
- localdata2 |= (*ptr++ << 8);
- localdata2 |= (*ptr++);
+ ptr = ptr_get_be32(ptr, &globaladmin);
+ ptr = ptr_get_be32(ptr, &localdata1);
+ ptr = ptr_get_be32(ptr, &localdata2);
+ (void)ptr; /* consume value */
sprintf(pnt, "%u:%u:%u", globaladmin, localdata1, localdata2);
pnt += strlen(pnt);
#include "queue.h"
#include "filter.h"
#include "jhash.h"
+#include "stream.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
/* Put string into buffer. */
if (type == ECOMMUNITY_ENCODE_AS4) {
- eas.as = (*pnt++ << 24);
- eas.as |= (*pnt++ << 16);
- eas.as |= (*pnt++ << 8);
- eas.as |= (*pnt++);
+ pnt = ptr_get_be32(pnt, &eas.as);
eas.val = (*pnt++ << 8);
eas.val |= (*pnt++);
} else if (type == ECOMMUNITY_ENCODE_AS) {
eas.as = (*pnt++ << 8);
eas.as |= (*pnt++);
-
- eas.val = (*pnt++ << 24);
- eas.val |= (*pnt++ << 16);
- eas.val |= (*pnt++ << 8);
- eas.val |= (*pnt++);
+ pnt = ptr_get_be32(pnt, &eas.val);
len = sprintf(buf, "%s%u:%u", prefix, eas.as, eas.val);
} else if (type == ECOMMUNITY_ENCODE_IP) {
len = sprintf(buf, "%s%s:%u", prefix, inet_ntoa(eip.ip),
eip.val);
}
+ (void)pnt; /* consume value */
return len;
}
#include "memory.h"
#include "prefix.h"
#include "filter.h"
+#include "stream.h"
#include "bgpd.h"
#include "bgp_attr.h"
return -1;
}
- st->sessionid = (subtlv->value[0] << 24) | (subtlv->value[1] << 16)
- | (subtlv->value[2] << 8) | subtlv->value[3];
+ ptr_get_be32(subtlv->value, &st->sessionid);
st->cookie_length = subtlv->length - 4;
if (st->cookie_length > sizeof(st->cookie)) {
zlog_debug("%s, subtlv length %d is greater than %d", __func__,
subtlv->length);
return -1;
}
- st->gre_key = (subtlv->value[0] << 24) | (subtlv->value[1] << 16)
- | (subtlv->value[2] << 8) | subtlv->value[3];
+ ptr_get_be32(subtlv->value, &st->gre_key);
return 0;
}
__func__);
return -1;
}
- st->color = (subtlv->value[4] << 24) | (subtlv->value[5] << 16)
- | (subtlv->value[6] << 8) | subtlv->value[7];
+ ptr_get_be32(subtlv->value + 4, &st->color);
return 0;
}
}
if (subtlv->length == 8) {
st->family = AF_INET;
- st->ip_address.v4.s_addr =
- ((subtlv->value[0] << 24) | (subtlv->value[1] << 16)
- | (subtlv->value[2] << 8) | subtlv->value[3]);
+ memcpy(&st->ip_address.v4.s_addr, subtlv->value, 4);
} else {
st->family = AF_INET6;
memcpy(&(st->ip_address.v6.s6_addr), subtlv->value, 16);
}
i = subtlv->length - 4;
- st->as4 = ((subtlv->value[i] << 24) | (subtlv->value[i + 1] << 16)
- | (subtlv->value[i + 2] << 8) | subtlv->value[i + 3]);
+ ptr_get_be32(subtlv->value + i, &st->as4);
return 0;
}
#include "command.h"
#include "prefix.h"
#include "lib/json.h"
+#include "stream.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
case ECOMMUNITY_ENCODE_AS:
eas.as = (*pnt++ << 8);
eas.as |= (*pnt++);
-
- eas.val = (*pnt++ << 24);
- eas.val |= (*pnt++ << 16);
- eas.val |= (*pnt++ << 8);
- eas.val |= (*pnt++);
+ pnt = ptr_get_be32(pnt, &eas.val);
snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val);
break;
case ECOMMUNITY_ENCODE_AS4:
- eas.as = (*pnt++ << 24);
- eas.as |= (*pnt++ << 16);
- eas.as |= (*pnt++ << 8);
- eas.as |= (*pnt++);
-
+ pnt = ptr_get_be32(pnt, &eas.val);
eas.val = (*pnt++ << 8);
eas.val |= (*pnt++);
#include "command.h"
#include "filter.h"
#include "jhash.h"
+#include "stream.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_lcommunity.h"
pnt = lcom->val + (i * LCOMMUNITY_SIZE);
- globaladmin = (*pnt++ << 24);
- globaladmin |= (*pnt++ << 16);
- globaladmin |= (*pnt++ << 8);
- globaladmin |= (*pnt++);
-
- localdata1 = (*pnt++ << 24);
- localdata1 |= (*pnt++ << 16);
- localdata1 |= (*pnt++ << 8);
- localdata1 |= (*pnt++);
-
- localdata2 = (*pnt++ << 24);
- localdata2 |= (*pnt++ << 16);
- localdata2 |= (*pnt++ << 8);
- localdata2 |= (*pnt++);
+ pnt = ptr_get_be32(pnt, &globaladmin);
+ pnt = ptr_get_be32(pnt, &localdata1);
+ pnt = ptr_get_be32(pnt, &localdata2);
+ (void)pnt; /* consume value */
len = sprintf(str_buf + str_pnt, "%u:%u:%u", globaladmin,
localdata1, localdata2);
{
rd_as->as = (u_int16_t)*pnt++ << 8;
rd_as->as |= (u_int16_t)*pnt++;
-
- rd_as->val = ((u_int32_t)*pnt++ << 24);
- rd_as->val |= ((u_int32_t)*pnt++ << 16);
- rd_as->val |= ((u_int32_t)*pnt++ << 8);
- rd_as->val |= (u_int32_t)*pnt;
+ ptr_get_be32(pnt, &rd_as->val);
}
/* type == RD_TYPE_AS4 */
void decode_rd_as4(u_char *pnt, struct rd_as *rd_as)
{
- rd_as->as = (u_int32_t)*pnt++ << 24;
- rd_as->as |= (u_int32_t)*pnt++ << 16;
- rd_as->as |= (u_int32_t)*pnt++ << 8;
- rd_as->as |= (u_int32_t)*pnt++;
-
+ pnt = ptr_get_be32(pnt, &rd_as->as);
rd_as->val = ((u_int16_t)*pnt++ << 8);
rd_as->val |= (u_int16_t)*pnt;
}
#include "lib/log.h"
#include "lib/skiplist.h"
#include "lib/thread.h"
+#include "lib/stream.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
if (*p++ == ECOMMUNITY_ROUTE_TARGET) {
if (encode == ECOMMUNITY_ENCODE_AS4) {
- as = (*p++ << 24);
- as |= (*p++ << 16);
- as |= (*p++ << 8);
- as |= (*p++);
+ p = ptr_get_be32(p, &as);
} else if (encode == ECOMMUNITY_ENCODE_AS) {
as = (*p++ << 8);
as |= (*p++);
{
uintptr_t result;
- result = (i & 0xff) << 24;
- result |= (i >> 8);
+ result = (unsigned)(i & 0xff) << 24;
+ result |= (unsigned)i >> 8;
return (void *)result;
}
return 0;
}
- l = s->data[from++] << 24;
+ l = (unsigned)(s->data[from++]) << 24;
l |= s->data[from++] << 16;
l |= s->data[from++] << 8;
l |= s->data[from];
return 0;
}
- l = s->data[s->getp++] << 24;
+ l = (unsigned)(s->data[s->getp++]) << 24;
l |= s->data[s->getp++] << 16;
l |= s->data[s->getp++] << 8;
l |= s->data[s->getp++];
extern void stream_fifo_clean(struct stream_fifo *fifo);
extern void stream_fifo_free(struct stream_fifo *fifo);
+/* This is here because "<< 24" is particularly problematic in C.
+ * This is because the left operand of << is integer-promoted, which means
+ * an uint8_t gets converted into a *signed* int. Shifting into the sign
+ * bit of a signed int is theoretically undefined behaviour, so - the left
+ * operand needs to be cast to unsigned.
+ *
+ * This is not a problem for 16- or 8-bit values (they don't reach the sign
+ * bit), for 64-bit values (you need to cast them anyway), and neither for
+ * encoding (because it's downcasted.)
+ */
+static inline uint8_t *ptr_get_be32(uint8_t *ptr, uint32_t *out)
+{
+ uint32_t tmp;
+ memcpy(&tmp, ptr, sizeof(tmp));
+ *out = ntohl(tmp);
+ return ptr + 4;
+}
+
#endif /* _ZEBRA_STREAM_H */
#define GET_OPAQUE_ID(lsid) ((u_int32_t)(lsid)&LSID_OPAQUE_ID_MASK)
#define SET_OPAQUE_LSID(type, id) \
- ((((type) << 24) & LSID_OPAQUE_TYPE_MASK) | ((id)&LSID_OPAQUE_ID_MASK))
+ ((((unsigned)(type) << 24) & LSID_OPAQUE_TYPE_MASK) \
+ | ((id) & LSID_OPAQUE_ID_MASK))
/*
* Opaque LSA types will be assigned by IANA.