Annotation of embedaddon/bird2/proto/babel/packets.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  *     BIRD -- The Babel protocol
        !             3:  *
        !             4:  *     Copyright (c) 2015--2016 Toke Hoiland-Jorgensen
        !             5:  *     (c) 2016--2017 Ondrej Zajicek <santiago@crfreenet.org>
        !             6:  *     (c) 2016--2017 CZ.NIC z.s.p.o.
        !             7:  *
        !             8:  *     Can be freely distributed and used under the terms of the GNU GPL.
        !             9:  *
        !            10:  *     This file contains the packet and TLV handling code for the protocol.
        !            11:  */
        !            12: 
        !            13: #include "babel.h"
        !            14: 
        !            15: 
        !            16: struct babel_pkt_header {
        !            17:   u8 magic;
        !            18:   u8 version;
        !            19:   u16 length;
        !            20: } PACKED;
        !            21: 
        !            22: struct babel_tlv {
        !            23:   u8 type;
        !            24:   u8 length;
        !            25:   u8 value[0];
        !            26: } PACKED;
        !            27: 
        !            28: struct babel_tlv_ack_req {
        !            29:   u8 type;
        !            30:   u8 length;
        !            31:   u16 reserved;
        !            32:   u16 nonce;
        !            33:   u16 interval;
        !            34: } PACKED;
        !            35: 
        !            36: struct babel_tlv_ack {
        !            37:   u8 type;
        !            38:   u8 length;
        !            39:   u16 nonce;
        !            40: } PACKED;
        !            41: 
        !            42: struct babel_tlv_hello {
        !            43:   u8 type;
        !            44:   u8 length;
        !            45:   u16 flags;
        !            46:   u16 seqno;
        !            47:   u16 interval;
        !            48: } PACKED;
        !            49: 
        !            50: struct babel_tlv_ihu {
        !            51:   u8 type;
        !            52:   u8 length;
        !            53:   u8 ae;
        !            54:   u8 reserved;
        !            55:   u16 rxcost;
        !            56:   u16 interval;
        !            57:   u8 addr[0];
        !            58: } PACKED;
        !            59: 
        !            60: struct babel_tlv_router_id {
        !            61:   u8 type;
        !            62:   u8 length;
        !            63:   u16 reserved;
        !            64:   u64 router_id;
        !            65: } PACKED;
        !            66: 
        !            67: struct babel_tlv_next_hop {
        !            68:   u8 type;
        !            69:   u8 length;
        !            70:   u8 ae;
        !            71:   u8 reserved;
        !            72:   u8 addr[0];
        !            73: } PACKED;
        !            74: 
        !            75: struct babel_tlv_update {
        !            76:   u8 type;
        !            77:   u8 length;
        !            78:   u8 ae;
        !            79:   u8 flags;
        !            80:   u8 plen;
        !            81:   u8 omitted;
        !            82:   u16 interval;
        !            83:   u16 seqno;
        !            84:   u16 metric;
        !            85:   u8 addr[0];
        !            86: } PACKED;
        !            87: 
        !            88: struct babel_tlv_route_request {
        !            89:   u8 type;
        !            90:   u8 length;
        !            91:   u8 ae;
        !            92:   u8 plen;
        !            93:   u8 addr[0];
        !            94: } PACKED;
        !            95: 
        !            96: struct babel_tlv_seqno_request {
        !            97:   u8 type;
        !            98:   u8 length;
        !            99:   u8 ae;
        !           100:   u8 plen;
        !           101:   u16 seqno;
        !           102:   u8 hop_count;
        !           103:   u8 reserved;
        !           104:   u64 router_id;
        !           105:   u8 addr[0];
        !           106: } PACKED;
        !           107: 
        !           108: struct babel_subtlv_source_prefix {
        !           109:   u8 type;
        !           110:   u8 length;
        !           111:   u8 plen;
        !           112:   u8 addr[0];
        !           113: } PACKED;
        !           114: 
        !           115: 
        !           116: /* Hello flags */
        !           117: #define BABEL_HF_UNICAST       0x8000
        !           118: 
        !           119: /* Update flags */
        !           120: #define BABEL_UF_DEF_PREFIX    0x80
        !           121: #define BABEL_UF_ROUTER_ID     0x40
        !           122: 
        !           123: 
        !           124: struct babel_parse_state {
        !           125:   struct babel_proto *proto;
        !           126:   struct babel_iface *ifa;
        !           127:   ip_addr saddr;
        !           128:   ip_addr next_hop_ip4;
        !           129:   ip_addr next_hop_ip6;
        !           130:   u64 router_id;               /* Router ID used in subsequent updates */
        !           131:   u8 def_ip6_prefix[16];       /* Implicit IPv6 prefix in network order */
        !           132:   u8 def_ip4_prefix[4];                /* Implicit IPv4 prefix in network order */
        !           133:   u8 router_id_seen;           /* router_id field is valid */
        !           134:   u8 def_ip6_prefix_seen;      /* def_ip6_prefix is valid */
        !           135:   u8 def_ip4_prefix_seen;      /* def_ip4_prefix is valid */
        !           136:   u8 current_tlv_endpos;       /* End of self-terminating TLVs (offset from start) */
        !           137:   u8 sadr_enabled;
        !           138: };
        !           139: 
        !           140: enum parse_result {
        !           141:   PARSE_SUCCESS,
        !           142:   PARSE_ERROR,
        !           143:   PARSE_IGNORE,
        !           144: };
        !           145: 
        !           146: struct babel_write_state {
        !           147:   u64 router_id;
        !           148:   u8 router_id_seen;
        !           149:   ip_addr next_hop_ip4;
        !           150:   ip_addr next_hop_ip6;
        !           151:   u8 def_ip6_prefix[16];       /* Implicit IPv6 prefix in network order */
        !           152:   u8 def_ip6_pxlen;
        !           153: };
        !           154: 
        !           155: 
        !           156: #define DROP(DSC,VAL) do { err_dsc = DSC; err_val = VAL; goto drop; } while(0)
        !           157: #define DROP1(DSC) do { err_dsc = DSC; goto drop; } while(0)
        !           158: #define LOG_PKT(msg, args...) \
        !           159:   log_rl(&p->log_pkt_tbf, L_REMOTE "%s: " msg, p->p.name, args)
        !           160: 
        !           161: #define FIRST_TLV(p) ((struct babel_tlv *) (((struct babel_pkt_header *) p) + 1))
        !           162: #define NEXT_TLV(t) ((struct babel_tlv *) (((byte *) t) + TLV_LENGTH(t)))
        !           163: #define TLV_LENGTH(t) (t->type == BABEL_TLV_PAD1 ? 1 : t->length + sizeof(struct babel_tlv))
        !           164: #define TLV_OPT_LENGTH(t) (t->length + sizeof(struct babel_tlv) - sizeof(*t))
        !           165: #define TLV_HDR(tlv,t,l) ({ tlv->type = t; tlv->length = l - sizeof(struct babel_tlv); })
        !           166: #define TLV_HDR0(tlv,t) TLV_HDR(tlv, t, tlv_data[t].min_length)
        !           167: 
        !           168: #define NET_SIZE(n) BYTES(net_pxlen(n))
        !           169: 
        !           170: static inline uint
        !           171: bytes_equal(u8 *b1, u8 *b2, uint maxlen)
        !           172: {
        !           173:   uint i;
        !           174:   for (i = 0; (i < maxlen) && (*b1 == *b2); i++, b1++, b2++)
        !           175:     ;
        !           176:   return i;
        !           177: }
        !           178: 
        !           179: static inline uint
        !           180: get_time16(const void *p)
        !           181: {
        !           182:   uint v = get_u16(p) * BABEL_TIME_UNITS;
        !           183:   return MAX(BABEL_MIN_INTERVAL, v);
        !           184: }
        !           185: 
        !           186: static inline void
        !           187: put_time16(void *p, uint v)
        !           188: {
        !           189:   put_u16(p, v / BABEL_TIME_UNITS);
        !           190: }
        !           191: 
        !           192: static inline void
        !           193: read_ip4_px(net_addr *n, const void *p, uint plen)
        !           194: {
        !           195:   ip4_addr addr = {0};
        !           196:   memcpy(&addr, p, BYTES(plen));
        !           197:   net_fill_ip4(n, ip4_ntoh(addr), plen);
        !           198: }
        !           199: 
        !           200: static inline void
        !           201: put_ip4_px(void *p, net_addr *n)
        !           202: {
        !           203:   ip4_addr addr = ip4_hton(net4_prefix(n));
        !           204:   memcpy(p, &addr, NET_SIZE(n));
        !           205: }
        !           206: 
        !           207: static inline void
        !           208: read_ip6_px(net_addr *n, const void *p, uint plen)
        !           209: {
        !           210:   ip6_addr addr = IPA_NONE;
        !           211:   memcpy(&addr, p, BYTES(plen));
        !           212:   net_fill_ip6(n, ip6_ntoh(addr), plen);
        !           213: }
        !           214: 
        !           215: static inline void
        !           216: put_ip6_px(void *p, net_addr *n)
        !           217: {
        !           218:   ip6_addr addr = ip6_hton(net6_prefix(n));
        !           219:   memcpy(p, &addr, NET_SIZE(n));
        !           220: }
        !           221: 
        !           222: static inline ip6_addr
        !           223: get_ip6_ll(const void *p)
        !           224: {
        !           225:   return ip6_build(0xfe800000, 0, get_u32(p+0), get_u32(p+4));
        !           226: }
        !           227: 
        !           228: static inline void
        !           229: put_ip6_ll(void *p, ip6_addr addr)
        !           230: {
        !           231:   put_u32(p+0, _I2(addr));
        !           232:   put_u32(p+4, _I3(addr));
        !           233: }
        !           234: 
        !           235: 
        !           236: /*
        !           237:  *     TLV read/write functions
        !           238:  */
        !           239: 
        !           240: static int babel_read_ack_req(struct babel_tlv *hdr, union babel_msg *msg, struct babel_parse_state *state);
        !           241: static int babel_read_hello(struct babel_tlv *hdr, union babel_msg *msg, struct babel_parse_state *state);
        !           242: static int babel_read_ihu(struct babel_tlv *hdr, union babel_msg *msg, struct babel_parse_state *state);
        !           243: static int babel_read_router_id(struct babel_tlv *hdr, union babel_msg *msg, struct babel_parse_state *state);
        !           244: static int babel_read_next_hop(struct babel_tlv *hdr, union babel_msg *msg, struct babel_parse_state *state);
        !           245: static int babel_read_update(struct babel_tlv *hdr, union babel_msg *msg, struct babel_parse_state *state);
        !           246: static int babel_read_route_request(struct babel_tlv *hdr, union babel_msg *msg, struct babel_parse_state *state);
        !           247: static int babel_read_seqno_request(struct babel_tlv *hdr, union babel_msg *msg, struct babel_parse_state *state);
        !           248: static int babel_read_source_prefix(struct babel_tlv *hdr, union babel_msg *msg, struct babel_parse_state *state);
        !           249: 
        !           250: static uint babel_write_ack(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len);
        !           251: static uint babel_write_hello(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len);
        !           252: static uint babel_write_ihu(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len);
        !           253: static uint babel_write_update(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len);
        !           254: static uint babel_write_route_request(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len);
        !           255: static uint babel_write_seqno_request(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len);
        !           256: static int babel_write_source_prefix(struct babel_tlv *hdr, net_addr *net, uint max_len);
        !           257: 
        !           258: struct babel_tlv_data {
        !           259:   u8 min_length;
        !           260:   int (*read_tlv)(struct babel_tlv *hdr, union babel_msg *m, struct babel_parse_state *state);
        !           261:   uint (*write_tlv)(struct babel_tlv *hdr, union babel_msg *m, struct babel_write_state *state, uint max_len);
        !           262:   void (*handle_tlv)(union babel_msg *m, struct babel_iface *ifa);
        !           263: };
        !           264: 
        !           265: static const struct babel_tlv_data tlv_data[BABEL_TLV_MAX] = {
        !           266:   [BABEL_TLV_ACK_REQ] = {
        !           267:     sizeof(struct babel_tlv_ack_req),
        !           268:     babel_read_ack_req,
        !           269:     NULL,
        !           270:     babel_handle_ack_req
        !           271:   },
        !           272:   [BABEL_TLV_ACK] = {
        !           273:     sizeof(struct babel_tlv_ack),
        !           274:     NULL,
        !           275:     babel_write_ack,
        !           276:     NULL
        !           277:   },
        !           278:   [BABEL_TLV_HELLO] = {
        !           279:     sizeof(struct babel_tlv_hello),
        !           280:     babel_read_hello,
        !           281:     babel_write_hello,
        !           282:     babel_handle_hello
        !           283:   },
        !           284:   [BABEL_TLV_IHU] = {
        !           285:     sizeof(struct babel_tlv_ihu),
        !           286:     babel_read_ihu,
        !           287:     babel_write_ihu,
        !           288:     babel_handle_ihu
        !           289:   },
        !           290:   [BABEL_TLV_ROUTER_ID] = {
        !           291:     sizeof(struct babel_tlv_router_id),
        !           292:     babel_read_router_id,
        !           293:     NULL,
        !           294:     NULL
        !           295:   },
        !           296:   [BABEL_TLV_NEXT_HOP] = {
        !           297:     sizeof(struct babel_tlv_next_hop),
        !           298:     babel_read_next_hop,
        !           299:     NULL,
        !           300:     NULL
        !           301:   },
        !           302:   [BABEL_TLV_UPDATE] = {
        !           303:     sizeof(struct babel_tlv_update),
        !           304:     babel_read_update,
        !           305:     babel_write_update,
        !           306:     babel_handle_update
        !           307:   },
        !           308:   [BABEL_TLV_ROUTE_REQUEST] = {
        !           309:     sizeof(struct babel_tlv_route_request),
        !           310:     babel_read_route_request,
        !           311:     babel_write_route_request,
        !           312:     babel_handle_route_request
        !           313:   },
        !           314:   [BABEL_TLV_SEQNO_REQUEST] = {
        !           315:     sizeof(struct babel_tlv_seqno_request),
        !           316:     babel_read_seqno_request,
        !           317:     babel_write_seqno_request,
        !           318:     babel_handle_seqno_request
        !           319:   },
        !           320: };
        !           321: 
        !           322: static int
        !           323: babel_read_ack_req(struct babel_tlv *hdr, union babel_msg *m,
        !           324:                   struct babel_parse_state *state)
        !           325: {
        !           326:   struct babel_tlv_ack_req *tlv = (void *) hdr;
        !           327:   struct babel_msg_ack_req *msg = &m->ack_req;
        !           328: 
        !           329:   msg->type = BABEL_TLV_ACK_REQ;
        !           330:   msg->nonce = get_u16(&tlv->nonce);
        !           331:   msg->interval = get_time16(&tlv->interval);
        !           332:   msg->sender = state->saddr;
        !           333: 
        !           334:   if (!msg->interval)
        !           335:     return PARSE_ERROR;
        !           336: 
        !           337:   return PARSE_SUCCESS;
        !           338: }
        !           339: 
        !           340: static uint
        !           341: babel_write_ack(struct babel_tlv *hdr, union babel_msg *m,
        !           342:                 struct babel_write_state *state UNUSED, uint max_len UNUSED)
        !           343: {
        !           344:   struct babel_tlv_ack *tlv = (void *) hdr;
        !           345:   struct babel_msg_ack *msg = &m->ack;
        !           346: 
        !           347:   TLV_HDR0(tlv, BABEL_TLV_ACK);
        !           348:   put_u16(&tlv->nonce, msg->nonce);
        !           349: 
        !           350:   return sizeof(struct babel_tlv_ack);
        !           351: }
        !           352: 
        !           353: static int
        !           354: babel_read_hello(struct babel_tlv *hdr, union babel_msg *m,
        !           355:                  struct babel_parse_state *state)
        !           356: {
        !           357:   struct babel_tlv_hello *tlv = (void *) hdr;
        !           358:   struct babel_msg_hello *msg = &m->hello;
        !           359: 
        !           360:   /* We currently don't support unicast Hello */
        !           361:   u16 flags = get_u16(&tlv->flags);
        !           362:   if (flags & BABEL_HF_UNICAST)
        !           363:     return PARSE_IGNORE;
        !           364: 
        !           365:   msg->type = BABEL_TLV_HELLO;
        !           366:   msg->seqno = get_u16(&tlv->seqno);
        !           367:   msg->interval = get_time16(&tlv->interval);
        !           368:   msg->sender = state->saddr;
        !           369: 
        !           370:   return PARSE_SUCCESS;
        !           371: }
        !           372: 
        !           373: static uint
        !           374: babel_write_hello(struct babel_tlv *hdr, union babel_msg *m,
        !           375:                   struct babel_write_state *state UNUSED, uint max_len UNUSED)
        !           376: {
        !           377:   struct babel_tlv_hello *tlv = (void *) hdr;
        !           378:   struct babel_msg_hello *msg = &m->hello;
        !           379: 
        !           380:   TLV_HDR0(tlv, BABEL_TLV_HELLO);
        !           381:   put_u16(&tlv->seqno, msg->seqno);
        !           382:   put_time16(&tlv->interval, msg->interval);
        !           383: 
        !           384:   return sizeof(struct babel_tlv_hello);
        !           385: }
        !           386: 
        !           387: static int
        !           388: babel_read_ihu(struct babel_tlv *hdr, union babel_msg *m,
        !           389:                struct babel_parse_state *state)
        !           390: {
        !           391:   struct babel_tlv_ihu *tlv = (void *) hdr;
        !           392:   struct babel_msg_ihu *msg = &m->ihu;
        !           393: 
        !           394:   msg->type = BABEL_TLV_IHU;
        !           395:   msg->ae = tlv->ae;
        !           396:   msg->rxcost = get_u16(&tlv->rxcost);
        !           397:   msg->interval = get_time16(&tlv->interval);
        !           398:   msg->addr = IPA_NONE;
        !           399:   msg->sender = state->saddr;
        !           400: 
        !           401:   if (msg->ae >= BABEL_AE_MAX)
        !           402:     return PARSE_IGNORE;
        !           403: 
        !           404:   /*
        !           405:    * We only actually read link-local IPs. In every other case, the addr field
        !           406:    * will be 0 but validation will succeed. The handler takes care of these
        !           407:    * cases. We handle them here anyway because we need the length for parsing
        !           408:    * subtlvs.
        !           409:    */
        !           410:   switch (msg->ae)
        !           411:   {
        !           412:   case BABEL_AE_IP4:
        !           413:     if (TLV_OPT_LENGTH(tlv) < 4)
        !           414:       return PARSE_ERROR;
        !           415:     state->current_tlv_endpos += 4;
        !           416:     break;
        !           417: 
        !           418:   case BABEL_AE_IP6:
        !           419:     if (TLV_OPT_LENGTH(tlv) < 16)
        !           420:       return PARSE_ERROR;
        !           421:     state->current_tlv_endpos += 16;
        !           422:     break;
        !           423: 
        !           424:   case BABEL_AE_IP6_LL:
        !           425:     if (TLV_OPT_LENGTH(tlv) < 8)
        !           426:       return PARSE_ERROR;
        !           427: 
        !           428:     msg->addr = ipa_from_ip6(get_ip6_ll(&tlv->addr));
        !           429:     state->current_tlv_endpos += 8;
        !           430:     break;
        !           431:   }
        !           432: 
        !           433:   return PARSE_SUCCESS;
        !           434: }
        !           435: 
        !           436: static uint
        !           437: babel_write_ihu(struct babel_tlv *hdr, union babel_msg *m,
        !           438:                 struct babel_write_state *state UNUSED, uint max_len)
        !           439: {
        !           440:   struct babel_tlv_ihu *tlv = (void *) hdr;
        !           441:   struct babel_msg_ihu *msg = &m->ihu;
        !           442: 
        !           443:   if (ipa_is_link_local(msg->addr) && max_len < sizeof(struct babel_tlv_ihu) + 8)
        !           444:     return 0;
        !           445: 
        !           446:   TLV_HDR0(tlv, BABEL_TLV_IHU);
        !           447:   put_u16(&tlv->rxcost, msg->rxcost);
        !           448:   put_time16(&tlv->interval, msg->interval);
        !           449: 
        !           450:   if (!ipa_is_link_local(msg->addr))
        !           451:   {
        !           452:     tlv->ae = BABEL_AE_WILDCARD;
        !           453:     return sizeof(struct babel_tlv_ihu);
        !           454:   }
        !           455:   put_ip6_ll(&tlv->addr, msg->addr);
        !           456:   tlv->ae = BABEL_AE_IP6_LL;
        !           457:   hdr->length += 8;
        !           458:   return sizeof(struct babel_tlv_ihu) + 8;
        !           459: }
        !           460: 
        !           461: static int
        !           462: babel_read_router_id(struct babel_tlv *hdr, union babel_msg *m UNUSED,
        !           463:                      struct babel_parse_state *state)
        !           464: {
        !           465:   struct babel_tlv_router_id *tlv = (void *) hdr;
        !           466: 
        !           467:   state->router_id = get_u64(&tlv->router_id);
        !           468:   state->router_id_seen = 1;
        !           469: 
        !           470:   return PARSE_IGNORE;
        !           471: }
        !           472: 
        !           473: /* This is called directly from babel_write_update() */
        !           474: static uint
        !           475: babel_write_router_id(struct babel_tlv *hdr, u64 router_id,
        !           476:                      struct babel_write_state *state, uint max_len UNUSED)
        !           477: {
        !           478:   struct babel_tlv_router_id *tlv = (void *) hdr;
        !           479: 
        !           480:   /* We still assume that first min_length bytes are available and zeroed */
        !           481: 
        !           482:   TLV_HDR0(tlv, BABEL_TLV_ROUTER_ID);
        !           483:   put_u64(&tlv->router_id, router_id);
        !           484: 
        !           485:   state->router_id = router_id;
        !           486:   state->router_id_seen = 1;
        !           487: 
        !           488:   return sizeof(struct babel_tlv_router_id);
        !           489: }
        !           490: 
        !           491: static int
        !           492: babel_read_next_hop(struct babel_tlv *hdr, union babel_msg *m UNUSED,
        !           493:                     struct babel_parse_state *state)
        !           494: {
        !           495:   struct babel_tlv_next_hop *tlv = (void *) hdr;
        !           496: 
        !           497:   switch (tlv->ae)
        !           498:   {
        !           499:   case BABEL_AE_WILDCARD:
        !           500:     return PARSE_ERROR;
        !           501: 
        !           502:   case BABEL_AE_IP4:
        !           503:     if (TLV_OPT_LENGTH(tlv) < sizeof(ip4_addr))
        !           504:       return PARSE_ERROR;
        !           505: 
        !           506:     state->next_hop_ip4 = ipa_from_ip4(get_ip4(&tlv->addr));
        !           507:     state->current_tlv_endpos += sizeof(ip4_addr);
        !           508:     return PARSE_IGNORE;
        !           509: 
        !           510:   case BABEL_AE_IP6:
        !           511:     if (TLV_OPT_LENGTH(tlv) < sizeof(ip6_addr))
        !           512:       return PARSE_ERROR;
        !           513: 
        !           514:     state->next_hop_ip6 = ipa_from_ip6(get_ip6(&tlv->addr));
        !           515:     state->current_tlv_endpos += sizeof(ip6_addr);
        !           516:     return PARSE_IGNORE;
        !           517: 
        !           518:   case BABEL_AE_IP6_LL:
        !           519:     if (TLV_OPT_LENGTH(tlv) < 8)
        !           520:       return PARSE_ERROR;
        !           521: 
        !           522:     state->next_hop_ip6 = ipa_from_ip6(get_ip6_ll(&tlv->addr));
        !           523:     state->current_tlv_endpos += 8;
        !           524:     return PARSE_IGNORE;
        !           525: 
        !           526:   default:
        !           527:     return PARSE_IGNORE;
        !           528:   }
        !           529: 
        !           530:   return PARSE_IGNORE;
        !           531: }
        !           532: 
        !           533: /* This is called directly from babel_write_update() and returns -1 if a next
        !           534:    hop should be written but there is not enough space. */
        !           535: static int
        !           536: babel_write_next_hop(struct babel_tlv *hdr, ip_addr addr,
        !           537:                     struct babel_write_state *state, uint max_len)
        !           538: {
        !           539:   struct babel_tlv_next_hop *tlv = (void *) hdr;
        !           540: 
        !           541:   if (ipa_zero(addr))
        !           542:   {
        !           543:     /* Should not happen */
        !           544:     return 0;
        !           545:   }
        !           546:   else if (ipa_is_ip4(addr) && !ipa_equal(addr, state->next_hop_ip4))
        !           547:   {
        !           548:     uint len = sizeof(struct babel_tlv_next_hop) + sizeof(ip4_addr);
        !           549:     if (len > max_len)
        !           550:       return -1;
        !           551: 
        !           552:     TLV_HDR(tlv, BABEL_TLV_NEXT_HOP, len);
        !           553: 
        !           554:     tlv->ae = BABEL_AE_IP4;
        !           555:     put_ip4(&tlv->addr, ipa_to_ip4(addr));
        !           556:     state->next_hop_ip4 = addr;
        !           557: 
        !           558:     return len;
        !           559:   }
        !           560:   else if (ipa_is_ip6(addr) && !ipa_equal(addr, state->next_hop_ip6))
        !           561:   {
        !           562:     uint len = sizeof(struct babel_tlv_next_hop) + sizeof(ip6_addr);
        !           563:     if (len > max_len)
        !           564:       return -1;
        !           565: 
        !           566:     TLV_HDR(tlv, BABEL_TLV_NEXT_HOP, len);
        !           567: 
        !           568:     tlv->ae = BABEL_AE_IP6;
        !           569:     put_ip6(&tlv->addr, ipa_to_ip6(addr));
        !           570:     state->next_hop_ip6 = addr;
        !           571: 
        !           572:     return len;
        !           573:   }
        !           574: 
        !           575:   return 0;
        !           576: }
        !           577: 
        !           578: static int
        !           579: babel_read_update(struct babel_tlv *hdr, union babel_msg *m,
        !           580:                   struct babel_parse_state *state)
        !           581: {
        !           582:   struct babel_tlv_update *tlv = (void *) hdr;
        !           583:   struct babel_msg_update *msg = &m->update;
        !           584: 
        !           585:   msg->type = BABEL_TLV_UPDATE;
        !           586:   msg->interval = get_time16(&tlv->interval);
        !           587:   msg->seqno = get_u16(&tlv->seqno);
        !           588:   msg->metric = get_u16(&tlv->metric);
        !           589: 
        !           590:   /* Length of received prefix data without omitted part */
        !           591:   int len = BYTES(tlv->plen) - (int) tlv->omitted;
        !           592:   u8 buf[16] = {};
        !           593: 
        !           594:   if ((len < 0) || ((uint) len > TLV_OPT_LENGTH(tlv)))
        !           595:     return PARSE_ERROR;
        !           596: 
        !           597:   switch (tlv->ae)
        !           598:   {
        !           599:   case BABEL_AE_WILDCARD:
        !           600:     if (tlv->plen > 0)
        !           601:       return PARSE_ERROR;
        !           602: 
        !           603:     if (msg->metric != 65535)
        !           604:       return PARSE_ERROR;
        !           605: 
        !           606:     msg->wildcard = 1;
        !           607:     break;
        !           608: 
        !           609:   case BABEL_AE_IP4:
        !           610:     if (tlv->plen > IP4_MAX_PREFIX_LENGTH)
        !           611:       return PARSE_ERROR;
        !           612: 
        !           613:     /* Cannot omit data if there is no saved prefix */
        !           614:     if (tlv->omitted && !state->def_ip4_prefix_seen)
        !           615:       return PARSE_ERROR;
        !           616: 
        !           617:     /* Update must have next hop, unless it is retraction */
        !           618:     if (ipa_zero(state->next_hop_ip4) && (msg->metric != BABEL_INFINITY))
        !           619:       return PARSE_IGNORE;
        !           620: 
        !           621:     /* Merge saved prefix and received prefix parts */
        !           622:     memcpy(buf, state->def_ip4_prefix, tlv->omitted);
        !           623:     memcpy(buf + tlv->omitted, tlv->addr, len);
        !           624: 
        !           625:     ip4_addr prefix4 = get_ip4(buf);
        !           626:     net_fill_ip4(&msg->net, prefix4, tlv->plen);
        !           627: 
        !           628:     if (tlv->flags & BABEL_UF_DEF_PREFIX)
        !           629:     {
        !           630:       put_ip4(state->def_ip4_prefix, prefix4);
        !           631:       state->def_ip4_prefix_seen = 1;
        !           632:     }
        !           633: 
        !           634:     msg->next_hop = state->next_hop_ip4;
        !           635: 
        !           636:     break;
        !           637: 
        !           638:   case BABEL_AE_IP6:
        !           639:     if (tlv->plen > IP6_MAX_PREFIX_LENGTH)
        !           640:       return PARSE_ERROR;
        !           641: 
        !           642:     /* Cannot omit data if there is no saved prefix */
        !           643:     if (tlv->omitted && !state->def_ip6_prefix_seen)
        !           644:       return PARSE_ERROR;
        !           645: 
        !           646:     /* Merge saved prefix and received prefix parts */
        !           647:     memcpy(buf, state->def_ip6_prefix, tlv->omitted);
        !           648:     memcpy(buf + tlv->omitted, tlv->addr, len);
        !           649: 
        !           650:     ip6_addr prefix6 = get_ip6(buf);
        !           651:     net_fill_ip6(&msg->net, prefix6, tlv->plen);
        !           652: 
        !           653:     if (state->sadr_enabled)
        !           654:       net_make_ip6_sadr(&msg->net);
        !           655: 
        !           656:     if (tlv->flags & BABEL_UF_DEF_PREFIX)
        !           657:     {
        !           658:       put_ip6(state->def_ip6_prefix, prefix6);
        !           659:       state->def_ip6_prefix_seen = 1;
        !           660:     }
        !           661: 
        !           662:     if (tlv->flags & BABEL_UF_ROUTER_ID)
        !           663:     {
        !           664:       state->router_id = ((u64) _I2(prefix6)) << 32 | _I3(prefix6);
        !           665:       state->router_id_seen = 1;
        !           666:     }
        !           667: 
        !           668:     msg->next_hop = state->next_hop_ip6;
        !           669: 
        !           670:     break;
        !           671: 
        !           672:   case BABEL_AE_IP6_LL:
        !           673:     /* ??? */
        !           674:     return PARSE_IGNORE;
        !           675: 
        !           676:   default:
        !           677:     return PARSE_IGNORE;
        !           678:   }
        !           679: 
        !           680:   /* Update must have Router ID, unless it is retraction */
        !           681:   if (!state->router_id_seen && (msg->metric != BABEL_INFINITY))
        !           682:   {
        !           683:     DBG("Babel: No router ID seen before update\n");
        !           684:     return PARSE_ERROR;
        !           685:   }
        !           686: 
        !           687:   msg->router_id = state->router_id;
        !           688:   msg->sender = state->saddr;
        !           689:   state->current_tlv_endpos += len;
        !           690: 
        !           691:   return PARSE_SUCCESS;
        !           692: }
        !           693: 
        !           694: static uint
        !           695: babel_write_update(struct babel_tlv *hdr, union babel_msg *m,
        !           696:                    struct babel_write_state *state, uint max_len)
        !           697: {
        !           698:   struct babel_msg_update *msg = &m->update;
        !           699:   uint len0 = 0;
        !           700: 
        !           701:   /*
        !           702:    * When needed, we write Router-ID TLV before Update TLV and return size of
        !           703:    * both of them. There is enough space for the Router-ID TLV, because
        !           704:    * sizeof(struct babel_tlv_router_id) == sizeof(struct babel_tlv_update).
        !           705:    *
        !           706:    * Router ID is not used for retractions, so do not use it in such case.
        !           707:    */
        !           708:   if ((msg->metric < BABEL_INFINITY) &&
        !           709:       (!state->router_id_seen || (msg->router_id != state->router_id)))
        !           710:   {
        !           711:     len0 = babel_write_router_id(hdr, msg->router_id, state, max_len);
        !           712:     hdr = NEXT_TLV(hdr);
        !           713:   }
        !           714: 
        !           715:   /*
        !           716:    * We also may add Next Hop TLV for regular updates. It may fail for not
        !           717:    * enough space or it may be unnecessary as the next hop is the same as the
        !           718:    * last one already announced. So we handle all three cases.
        !           719:    */
        !           720:   if (msg->metric < BABEL_INFINITY)
        !           721:   {
        !           722:     int l = babel_write_next_hop(hdr, msg->next_hop, state, max_len - len0);
        !           723:     if (l < 0)
        !           724:       return 0;
        !           725: 
        !           726:     if (l)
        !           727:     {
        !           728:       len0 += l;
        !           729:       hdr = NEXT_TLV(hdr);
        !           730:     }
        !           731:   }
        !           732: 
        !           733:   struct babel_tlv_update *tlv = (void *) hdr;
        !           734:   uint len = sizeof(struct babel_tlv_update) + NET_SIZE(&msg->net);
        !           735: 
        !           736:   if (len0 + len > max_len)
        !           737:     return 0;
        !           738: 
        !           739:   memset(tlv, 0, sizeof(struct babel_tlv_update));
        !           740:   TLV_HDR(tlv, BABEL_TLV_UPDATE, len);
        !           741: 
        !           742:   if (msg->wildcard)
        !           743:   {
        !           744:     tlv->ae = BABEL_AE_WILDCARD;
        !           745:     tlv->plen = 0;
        !           746:   }
        !           747:   else if (msg->net.type == NET_IP4)
        !           748:   {
        !           749:     tlv->ae = BABEL_AE_IP4;
        !           750:     tlv->plen = net4_pxlen(&msg->net);
        !           751:     put_ip4_px(tlv->addr, &msg->net);
        !           752:   }
        !           753:   else
        !           754:   {
        !           755:     tlv->ae = BABEL_AE_IP6;
        !           756:     tlv->plen = net6_pxlen(&msg->net);
        !           757: 
        !           758:     /* Address compression - omit initial matching bytes */
        !           759:     u8 buf[16], omit;
        !           760:     put_ip6(buf, net6_prefix(&msg->net));
        !           761:     omit = bytes_equal(buf, state->def_ip6_prefix,
        !           762:                       MIN(tlv->plen, state->def_ip6_pxlen) / 8);
        !           763: 
        !           764:     if (omit > 0)
        !           765:     {
        !           766:       memcpy(tlv->addr, buf + omit, NET_SIZE(&msg->net) - omit);
        !           767: 
        !           768:       tlv->omitted = omit;
        !           769:       tlv->length -= omit;
        !           770:       len -= omit;
        !           771:     }
        !           772:     else
        !           773:     {
        !           774:       put_ip6_px(tlv->addr, &msg->net);
        !           775:       tlv->flags |= BABEL_UF_DEF_PREFIX;
        !           776: 
        !           777:       put_ip6(state->def_ip6_prefix, net6_prefix(&msg->net));
        !           778:       state->def_ip6_pxlen = tlv->plen;
        !           779:     }
        !           780:   }
        !           781: 
        !           782:   put_time16(&tlv->interval, msg->interval);
        !           783:   put_u16(&tlv->seqno, msg->seqno);
        !           784:   put_u16(&tlv->metric, msg->metric);
        !           785: 
        !           786:   if (msg->net.type == NET_IP6_SADR)
        !           787:   {
        !           788:     int l = babel_write_source_prefix(hdr, &msg->net, max_len - (len0 + len));
        !           789:     if (l < 0)
        !           790:       return 0;
        !           791: 
        !           792:     len += l;
        !           793:   }
        !           794: 
        !           795:   return len0 + len;
        !           796: }
        !           797: 
        !           798: static int
        !           799: babel_read_route_request(struct babel_tlv *hdr, union babel_msg *m,
        !           800:                          struct babel_parse_state *state)
        !           801: {
        !           802:   struct babel_tlv_route_request *tlv = (void *) hdr;
        !           803:   struct babel_msg_route_request *msg = &m->route_request;
        !           804: 
        !           805:   msg->type = BABEL_TLV_ROUTE_REQUEST;
        !           806: 
        !           807:   switch (tlv->ae)
        !           808:   {
        !           809:   case BABEL_AE_WILDCARD:
        !           810:     /* Wildcard requests must have plen 0 */
        !           811:     if (tlv->plen > 0)
        !           812:       return PARSE_ERROR;
        !           813: 
        !           814:     msg->full = 1;
        !           815:     return PARSE_SUCCESS;
        !           816: 
        !           817:   case BABEL_AE_IP4:
        !           818:     if (tlv->plen > IP4_MAX_PREFIX_LENGTH)
        !           819:       return PARSE_ERROR;
        !           820: 
        !           821:     if (TLV_OPT_LENGTH(tlv) < BYTES(tlv->plen))
        !           822:       return PARSE_ERROR;
        !           823: 
        !           824:     read_ip4_px(&msg->net, tlv->addr, tlv->plen);
        !           825:     state->current_tlv_endpos += BYTES(tlv->plen);
        !           826:     return PARSE_SUCCESS;
        !           827: 
        !           828:   case BABEL_AE_IP6:
        !           829:     if (tlv->plen > IP6_MAX_PREFIX_LENGTH)
        !           830:       return PARSE_ERROR;
        !           831: 
        !           832:     if (TLV_OPT_LENGTH(tlv) < BYTES(tlv->plen))
        !           833:       return PARSE_ERROR;
        !           834: 
        !           835:     read_ip6_px(&msg->net, tlv->addr, tlv->plen);
        !           836:     state->current_tlv_endpos += BYTES(tlv->plen);
        !           837: 
        !           838:     if (state->sadr_enabled)
        !           839:       net_make_ip6_sadr(&msg->net);
        !           840: 
        !           841:     return PARSE_SUCCESS;
        !           842: 
        !           843:   case BABEL_AE_IP6_LL:
        !           844:     return PARSE_ERROR;
        !           845: 
        !           846:   default:
        !           847:     return PARSE_IGNORE;
        !           848:   }
        !           849: 
        !           850:   return PARSE_IGNORE;
        !           851: }
        !           852: 
        !           853: static uint
        !           854: babel_write_route_request(struct babel_tlv *hdr, union babel_msg *m,
        !           855:                          struct babel_write_state *state UNUSED, uint max_len)
        !           856: {
        !           857:   struct babel_tlv_route_request *tlv = (void *) hdr;
        !           858:   struct babel_msg_route_request *msg = &m->route_request;
        !           859: 
        !           860:   uint len = sizeof(struct babel_tlv_route_request) + NET_SIZE(&msg->net);
        !           861: 
        !           862:   if (len > max_len)
        !           863:     return 0;
        !           864: 
        !           865:   TLV_HDR(tlv, BABEL_TLV_ROUTE_REQUEST, len);
        !           866: 
        !           867:   if (msg->full)
        !           868:   {
        !           869:     tlv->ae = BABEL_AE_WILDCARD;
        !           870:     tlv->plen = 0;
        !           871:   }
        !           872:   else if (msg->net.type == NET_IP4)
        !           873:   {
        !           874:     tlv->ae = BABEL_AE_IP4;
        !           875:     tlv->plen = net4_pxlen(&msg->net);
        !           876:     put_ip4_px(tlv->addr, &msg->net);
        !           877:   }
        !           878:   else
        !           879:   {
        !           880:     tlv->ae = BABEL_AE_IP6;
        !           881:     tlv->plen = net6_pxlen(&msg->net);
        !           882:     put_ip6_px(tlv->addr, &msg->net);
        !           883:   }
        !           884: 
        !           885:   if (msg->net.type == NET_IP6_SADR)
        !           886:   {
        !           887:     int l = babel_write_source_prefix(hdr, &msg->net, max_len - len);
        !           888:     if (l < 0)
        !           889:       return 0;
        !           890: 
        !           891:     len += l;
        !           892:   }
        !           893: 
        !           894:   return len;
        !           895: }
        !           896: 
        !           897: static int
        !           898: babel_read_seqno_request(struct babel_tlv *hdr, union babel_msg *m,
        !           899:                          struct babel_parse_state *state)
        !           900: {
        !           901:   struct babel_tlv_seqno_request *tlv = (void *) hdr;
        !           902:   struct babel_msg_seqno_request *msg = &m->seqno_request;
        !           903: 
        !           904:   msg->type = BABEL_TLV_SEQNO_REQUEST;
        !           905:   msg->seqno = get_u16(&tlv->seqno);
        !           906:   msg->hop_count = tlv->hop_count;
        !           907:   msg->router_id = get_u64(&tlv->router_id);
        !           908:   msg->sender = state->saddr;
        !           909: 
        !           910:   if (tlv->hop_count == 0)
        !           911:     return PARSE_ERROR;
        !           912: 
        !           913:   switch (tlv->ae)
        !           914:   {
        !           915:   case BABEL_AE_WILDCARD:
        !           916:     return PARSE_ERROR;
        !           917: 
        !           918:   case BABEL_AE_IP4:
        !           919:     if (tlv->plen > IP4_MAX_PREFIX_LENGTH)
        !           920:       return PARSE_ERROR;
        !           921: 
        !           922:     if (TLV_OPT_LENGTH(tlv) < BYTES(tlv->plen))
        !           923:       return PARSE_ERROR;
        !           924: 
        !           925:     read_ip4_px(&msg->net, tlv->addr, tlv->plen);
        !           926:     state->current_tlv_endpos += BYTES(tlv->plen);
        !           927:     return PARSE_SUCCESS;
        !           928: 
        !           929:   case BABEL_AE_IP6:
        !           930:     if (tlv->plen > IP6_MAX_PREFIX_LENGTH)
        !           931:       return PARSE_ERROR;
        !           932: 
        !           933:     if (TLV_OPT_LENGTH(tlv) < BYTES(tlv->plen))
        !           934:       return PARSE_ERROR;
        !           935: 
        !           936:     read_ip6_px(&msg->net, tlv->addr, tlv->plen);
        !           937:     state->current_tlv_endpos += BYTES(tlv->plen);
        !           938: 
        !           939:     if (state->sadr_enabled)
        !           940:       net_make_ip6_sadr(&msg->net);
        !           941: 
        !           942:     return PARSE_SUCCESS;
        !           943: 
        !           944:   case BABEL_AE_IP6_LL:
        !           945:     return PARSE_ERROR;
        !           946: 
        !           947:   default:
        !           948:     return PARSE_IGNORE;
        !           949:   }
        !           950: 
        !           951:   return PARSE_IGNORE;
        !           952: }
        !           953: 
        !           954: static uint
        !           955: babel_write_seqno_request(struct babel_tlv *hdr, union babel_msg *m,
        !           956:                          struct babel_write_state *state UNUSED, uint max_len)
        !           957: {
        !           958:   struct babel_tlv_seqno_request *tlv = (void *) hdr;
        !           959:   struct babel_msg_seqno_request *msg = &m->seqno_request;
        !           960: 
        !           961:   uint len = sizeof(struct babel_tlv_seqno_request) + NET_SIZE(&msg->net);
        !           962: 
        !           963:   if (len > max_len)
        !           964:     return 0;
        !           965: 
        !           966:   TLV_HDR(tlv, BABEL_TLV_SEQNO_REQUEST, len);
        !           967: 
        !           968:   if (msg->net.type == NET_IP4)
        !           969:   {
        !           970:     tlv->ae = BABEL_AE_IP4;
        !           971:     tlv->plen = net4_pxlen(&msg->net);
        !           972:     put_ip4_px(tlv->addr, &msg->net);
        !           973:   }
        !           974:   else
        !           975:   {
        !           976:     tlv->ae = BABEL_AE_IP6;
        !           977:     tlv->plen = net6_pxlen(&msg->net);
        !           978:     put_ip6_px(tlv->addr, &msg->net);
        !           979:   }
        !           980: 
        !           981:   put_u16(&tlv->seqno, msg->seqno);
        !           982:   tlv->hop_count = msg->hop_count;
        !           983:   put_u64(&tlv->router_id, msg->router_id);
        !           984: 
        !           985:   if (msg->net.type == NET_IP6_SADR)
        !           986:   {
        !           987:     int l = babel_write_source_prefix(hdr, &msg->net, max_len - len);
        !           988:     if (l < 0)
        !           989:       return 0;
        !           990: 
        !           991:     len += l;
        !           992:   }
        !           993: 
        !           994:   return len;
        !           995: }
        !           996: 
        !           997: static int
        !           998: babel_read_source_prefix(struct babel_tlv *hdr, union babel_msg *msg,
        !           999:                         struct babel_parse_state *state UNUSED)
        !          1000: {
        !          1001:   struct babel_subtlv_source_prefix *tlv = (void *) hdr;
        !          1002:   net_addr_ip6_sadr *net;
        !          1003: 
        !          1004:   /*
        !          1005:    * We would like to skip the sub-TLV if SADR is not enabled, but we do not
        !          1006:    * know AF of the enclosing TLV yet. We will do that later.
        !          1007:    */
        !          1008: 
        !          1009:   /* Check internal consistency */
        !          1010:   if ((tlv->length < 1) ||
        !          1011:       (tlv->plen > IP6_MAX_PREFIX_LENGTH) ||
        !          1012:       (tlv->length < (1 + BYTES(tlv->plen))))
        !          1013:     return PARSE_ERROR;
        !          1014: 
        !          1015:   /* Plen MUST NOT be 0 */
        !          1016:   if (tlv->plen == 0)
        !          1017:     return PARSE_ERROR;
        !          1018: 
        !          1019:   switch(msg->type)
        !          1020:   {
        !          1021:   case BABEL_TLV_UPDATE:
        !          1022:     /* Wildcard updates with source prefix MUST be silently ignored */
        !          1023:     if (msg->update.wildcard)
        !          1024:       return PARSE_IGNORE;
        !          1025: 
        !          1026:     net = (void *) &msg->update.net;
        !          1027:     break;
        !          1028: 
        !          1029:   case BABEL_TLV_ROUTE_REQUEST:
        !          1030:     /* Wildcard requests with source addresses MUST be silently ignored */
        !          1031:     if (msg->route_request.full)
        !          1032:       return PARSE_IGNORE;
        !          1033: 
        !          1034:     net = (void *) &msg->route_request.net;
        !          1035:     break;
        !          1036: 
        !          1037:   case BABEL_TLV_SEQNO_REQUEST:
        !          1038:     net = (void *) &msg->seqno_request.net;
        !          1039:     break;
        !          1040: 
        !          1041:   default:
        !          1042:     return PARSE_ERROR;
        !          1043:   }
        !          1044: 
        !          1045:   /* If SADR is active, the net has appropriate type */
        !          1046:   if (net->type != NET_IP6_SADR)
        !          1047:     return PARSE_IGNORE;
        !          1048: 
        !          1049:   /* Duplicate Source Prefix sub-TLV; SHOULD ignore whole TLV */
        !          1050:   if (net->src_pxlen > 0)
        !          1051:     return PARSE_IGNORE;
        !          1052: 
        !          1053:   net_addr_ip6 src;
        !          1054:   read_ip6_px((void *) &src, tlv->addr, tlv->plen);
        !          1055:   net->src_prefix = src.prefix;
        !          1056:   net->src_pxlen = src.pxlen;
        !          1057: 
        !          1058:   return PARSE_SUCCESS;
        !          1059: }
        !          1060: 
        !          1061: static int
        !          1062: babel_write_source_prefix(struct babel_tlv *hdr, net_addr *n, uint max_len)
        !          1063: {
        !          1064:   struct babel_subtlv_source_prefix *tlv = (void *) NEXT_TLV(hdr);
        !          1065:   net_addr_ip6_sadr *net = (void *) n;
        !          1066: 
        !          1067:   /* Do not use this sub-TLV for default prefix */
        !          1068:   if (net->src_pxlen == 0)
        !          1069:     return 0;
        !          1070: 
        !          1071:   uint len = sizeof(*tlv) + BYTES(net->src_pxlen);
        !          1072: 
        !          1073:   if (len > max_len)
        !          1074:     return -1;
        !          1075: 
        !          1076:   TLV_HDR(tlv, BABEL_SUBTLV_SOURCE_PREFIX, len);
        !          1077:   hdr->length += len;
        !          1078: 
        !          1079:   net_addr_ip6 src = NET_ADDR_IP6(net->src_prefix, net->src_pxlen);
        !          1080:   tlv->plen = src.pxlen;
        !          1081:   put_ip6_px(tlv->addr, (void *) &src);
        !          1082: 
        !          1083:   return len;
        !          1084: }
        !          1085: 
        !          1086: 
        !          1087: static inline int
        !          1088: babel_read_subtlvs(struct babel_tlv *hdr,
        !          1089:                   union babel_msg *msg,
        !          1090:                   struct babel_parse_state *state)
        !          1091: {
        !          1092:   struct babel_tlv *tlv;
        !          1093:   byte *pos, *end = (byte *) hdr + TLV_LENGTH(hdr);
        !          1094:   int res;
        !          1095: 
        !          1096:   for (tlv = (void *) hdr + state->current_tlv_endpos;
        !          1097:        (byte *) tlv < end;
        !          1098:        tlv = NEXT_TLV(tlv))
        !          1099:   {
        !          1100:     /* Ugly special case */
        !          1101:     if (tlv->type == BABEL_TLV_PAD1)
        !          1102:       continue;
        !          1103: 
        !          1104:     /* The end of the common TLV header */
        !          1105:     pos = (byte *)tlv + sizeof(struct babel_tlv);
        !          1106:     if ((pos > end) || (pos + tlv->length > end))
        !          1107:       return PARSE_ERROR;
        !          1108: 
        !          1109:     /*
        !          1110:      * The subtlv type space is non-contiguous (due to the mandatory bit), so
        !          1111:      * use a switch for dispatch instead of the mapping array we use for TLVs
        !          1112:      */
        !          1113:     switch (tlv->type)
        !          1114:     {
        !          1115:     case BABEL_SUBTLV_SOURCE_PREFIX:
        !          1116:       res = babel_read_source_prefix(tlv, msg, state);
        !          1117:       if (res != PARSE_SUCCESS)
        !          1118:        return res;
        !          1119:       break;
        !          1120: 
        !          1121:     case BABEL_SUBTLV_PADN:
        !          1122:     default:
        !          1123:       /* Unknown mandatory subtlv; PARSE_IGNORE ignores the whole TLV */
        !          1124:       if (tlv->type >= 128)
        !          1125:        return PARSE_IGNORE;
        !          1126:       break;
        !          1127:     }
        !          1128:   }
        !          1129: 
        !          1130:   return PARSE_SUCCESS;
        !          1131: }
        !          1132: 
        !          1133: static inline int
        !          1134: babel_read_tlv(struct babel_tlv *hdr,
        !          1135:                union babel_msg *msg,
        !          1136:                struct babel_parse_state *state)
        !          1137: {
        !          1138:   if ((hdr->type <= BABEL_TLV_PADN) ||
        !          1139:       (hdr->type >= BABEL_TLV_MAX) ||
        !          1140:       !tlv_data[hdr->type].read_tlv)
        !          1141:     return PARSE_IGNORE;
        !          1142: 
        !          1143:   if (TLV_LENGTH(hdr) < tlv_data[hdr->type].min_length)
        !          1144:     return PARSE_ERROR;
        !          1145: 
        !          1146:   state->current_tlv_endpos = tlv_data[hdr->type].min_length;
        !          1147:   memset(msg, 0, sizeof(*msg));
        !          1148: 
        !          1149:   int res = tlv_data[hdr->type].read_tlv(hdr, msg, state);
        !          1150:   if (res != PARSE_SUCCESS)
        !          1151:     return res;
        !          1152: 
        !          1153:   return babel_read_subtlvs(hdr, msg, state);
        !          1154: }
        !          1155: 
        !          1156: static uint
        !          1157: babel_write_tlv(struct babel_tlv *hdr,
        !          1158:                union babel_msg *msg,
        !          1159:                struct babel_write_state *state,
        !          1160:                uint max_len)
        !          1161: {
        !          1162:   if ((msg->type <= BABEL_TLV_PADN) ||
        !          1163:       (msg->type >= BABEL_TLV_MAX) ||
        !          1164:       !tlv_data[msg->type].write_tlv)
        !          1165:     return 0;
        !          1166: 
        !          1167:   if (tlv_data[msg->type].min_length > max_len)
        !          1168:     return 0;
        !          1169: 
        !          1170:   memset(hdr, 0, tlv_data[msg->type].min_length);
        !          1171:   return tlv_data[msg->type].write_tlv(hdr, msg, state, max_len);
        !          1172: }
        !          1173: 
        !          1174: 
        !          1175: /*
        !          1176:  *     Packet RX/TX functions
        !          1177:  */
        !          1178: 
        !          1179: static int
        !          1180: babel_send_to(struct babel_iface *ifa, ip_addr dest)
        !          1181: {
        !          1182:   sock *sk = ifa->sk;
        !          1183:   struct babel_pkt_header *hdr = (void *) sk->tbuf;
        !          1184:   int len = get_u16(&hdr->length) + sizeof(struct babel_pkt_header);
        !          1185: 
        !          1186:   DBG("Babel: Sending %d bytes to %I\n", len, dest);
        !          1187:   return sk_send_to(sk, len, dest, 0);
        !          1188: }
        !          1189: 
        !          1190: /**
        !          1191:  * babel_write_queue - Write a TLV queue to a transmission buffer
        !          1192:  * @ifa: Interface holding the transmission buffer
        !          1193:  * @queue: TLV queue to write (containing internal-format TLVs)
        !          1194:  *
        !          1195:  * This function writes a packet to the interface transmission buffer with as
        !          1196:  * many TLVs from the &queue as will fit in the buffer. It returns the number of
        !          1197:  * bytes written (NOT counting the packet header). The function is called by
        !          1198:  * babel_send_queue() and babel_send_unicast() to construct packets for
        !          1199:  * transmission, and uses per-TLV helper functions to convert the
        !          1200:  * internal-format TLVs to their wire representations.
        !          1201:  *
        !          1202:  * The TLVs in the queue are freed after they are written to the buffer.
        !          1203:  */
        !          1204: static uint
        !          1205: babel_write_queue(struct babel_iface *ifa, list *queue)
        !          1206: {
        !          1207:   struct babel_proto *p = ifa->proto;
        !          1208:   struct babel_write_state state = { .next_hop_ip6 = ifa->addr };
        !          1209: 
        !          1210:   if (EMPTY_LIST(*queue))
        !          1211:     return 0;
        !          1212: 
        !          1213:   byte *pos = ifa->sk->tbuf;
        !          1214:   byte *end = pos + ifa->tx_length;
        !          1215: 
        !          1216:   struct babel_pkt_header *pkt = (void *) pos;
        !          1217:   pkt->magic = BABEL_MAGIC;
        !          1218:   pkt->version = BABEL_VERSION;
        !          1219:   pkt->length = 0;
        !          1220:   pos += sizeof(struct babel_pkt_header);
        !          1221: 
        !          1222:   struct babel_msg_node *msg;
        !          1223:   WALK_LIST_FIRST(msg, *queue)
        !          1224:   {
        !          1225:     if (pos >= end)
        !          1226:       break;
        !          1227: 
        !          1228:     int len = babel_write_tlv((struct babel_tlv *) pos, &msg->msg, &state, end - pos);
        !          1229: 
        !          1230:     if (!len)
        !          1231:       break;
        !          1232: 
        !          1233:     pos += len;
        !          1234:     rem_node(NODE msg);
        !          1235:     sl_free(p->msg_slab, msg);
        !          1236:   }
        !          1237: 
        !          1238:   uint plen = pos - (byte *) pkt;
        !          1239:   put_u16(&pkt->length, plen - sizeof(struct babel_pkt_header));
        !          1240: 
        !          1241:   return plen;
        !          1242: }
        !          1243: 
        !          1244: void
        !          1245: babel_send_queue(void *arg)
        !          1246: {
        !          1247:   struct babel_iface *ifa = arg;
        !          1248:   while ((babel_write_queue(ifa, &ifa->msg_queue) > 0) &&
        !          1249:         (babel_send_to(ifa, IP6_BABEL_ROUTERS) > 0));
        !          1250: }
        !          1251: 
        !          1252: static inline void
        !          1253: babel_kick_queue(struct babel_iface *ifa)
        !          1254: {
        !          1255:   /*
        !          1256:    * Only schedule send event if there is not already data in the socket buffer.
        !          1257:    * Otherwise we may overwrite the data already in the buffer.
        !          1258:    */
        !          1259: 
        !          1260:   if ((ifa->sk->tpos == ifa->sk->tbuf) && !ev_active(ifa->send_event))
        !          1261:     ev_schedule(ifa->send_event);
        !          1262: }
        !          1263: 
        !          1264: /**
        !          1265:  * babel_send_unicast - send a single TLV via unicast to a destination
        !          1266:  * @msg: TLV to send
        !          1267:  * @ifa: Interface to send via
        !          1268:  * @dest: Destination of the TLV
        !          1269:  *
        !          1270:  * This function is used to send a single TLV via unicast to a designated
        !          1271:  * receiver. This is used for replying to certain incoming requests, and for
        !          1272:  * sending unicast requests to refresh routes before they expire.
        !          1273:  */
        !          1274: void
        !          1275: babel_send_unicast(union babel_msg *msg, struct babel_iface *ifa, ip_addr dest)
        !          1276: {
        !          1277:   struct babel_proto *p = ifa->proto;
        !          1278:   struct babel_msg_node *msgn = sl_alloc(p->msg_slab);
        !          1279:   list queue;
        !          1280: 
        !          1281:   msgn->msg = *msg;
        !          1282:   init_list(&queue);
        !          1283:   add_tail(&queue, NODE msgn);
        !          1284:   babel_write_queue(ifa, &queue);
        !          1285:   babel_send_to(ifa, dest);
        !          1286: 
        !          1287:   /* We could overwrite waiting packet here, we may have to kick TX queue */
        !          1288:   if (!EMPTY_LIST(ifa->msg_queue))
        !          1289:     babel_kick_queue(ifa);
        !          1290: }
        !          1291: 
        !          1292: /**
        !          1293:  * babel_enqueue - enqueue a TLV for transmission on an interface
        !          1294:  * @msg: TLV to enqueue (in internal TLV format)
        !          1295:  * @ifa: Interface to enqueue to
        !          1296:  *
        !          1297:  * This function is called to enqueue a TLV for subsequent transmission on an
        !          1298:  * interface. The transmission event is triggered whenever a TLV is enqueued;
        !          1299:  * this ensures that TLVs will be transmitted in a timely manner, but that TLVs
        !          1300:  * which are enqueued in rapid succession can be transmitted together in one
        !          1301:  * packet.
        !          1302:  */
        !          1303: void
        !          1304: babel_enqueue(union babel_msg *msg, struct babel_iface *ifa)
        !          1305: {
        !          1306:   struct babel_proto *p = ifa->proto;
        !          1307:   struct babel_msg_node *msgn = sl_alloc(p->msg_slab);
        !          1308:   msgn->msg = *msg;
        !          1309:   add_tail(&ifa->msg_queue, NODE msgn);
        !          1310:   babel_kick_queue(ifa);
        !          1311: }
        !          1312: 
        !          1313: /**
        !          1314:  * babel_process_packet - process incoming data packet
        !          1315:  * @pkt: Pointer to the packet data
        !          1316:  * @len: Length of received packet
        !          1317:  * @saddr: Address of packet sender
        !          1318:  * @ifa: Interface packet was received on.
        !          1319:  *
        !          1320:  * This function is the main processing hook of incoming Babel packets. It
        !          1321:  * checks that the packet header is well-formed, then processes the TLVs
        !          1322:  * contained in the packet. This is done in two passes: First all TLVs are
        !          1323:  * parsed into the internal TLV format. If a TLV parser fails, processing of the
        !          1324:  * rest of the packet is aborted.
        !          1325:  *
        !          1326:  * After the parsing step, the TLV handlers are called for each parsed TLV in
        !          1327:  * order.
        !          1328:  */
        !          1329: static void
        !          1330: babel_process_packet(struct babel_pkt_header *pkt, int len,
        !          1331:                      ip_addr saddr, struct babel_iface *ifa)
        !          1332: {
        !          1333:   struct babel_proto *p = ifa->proto;
        !          1334:   struct babel_tlv *tlv;
        !          1335:   struct babel_msg_node *msg;
        !          1336:   list msgs;
        !          1337:   int res;
        !          1338: 
        !          1339:   int plen = sizeof(struct babel_pkt_header) + get_u16(&pkt->length);
        !          1340:   byte *pos;
        !          1341:   byte *end = (byte *)pkt + plen;
        !          1342: 
        !          1343:   struct babel_parse_state state = {
        !          1344:     .proto       = p,
        !          1345:     .ifa         = ifa,
        !          1346:     .saddr       = saddr,
        !          1347:     .next_hop_ip6 = saddr,
        !          1348:     .sadr_enabled = babel_sadr_enabled(p),
        !          1349:   };
        !          1350: 
        !          1351:   if ((pkt->magic != BABEL_MAGIC) || (pkt->version != BABEL_VERSION))
        !          1352:   {
        !          1353:     TRACE(D_PACKETS, "Strange packet from %I via %s - magic %d version %d",
        !          1354:          saddr, ifa->iface->name, pkt->magic, pkt->version);
        !          1355:     return;
        !          1356:   }
        !          1357: 
        !          1358:   if (plen > len)
        !          1359:   {
        !          1360:     LOG_PKT("Bad packet from %I via %s - %s (%u)",
        !          1361:            saddr, ifa->iface->name, "length mismatch", plen);
        !          1362:     return;
        !          1363:   }
        !          1364: 
        !          1365:   TRACE(D_PACKETS, "Packet received from %I via %s",
        !          1366:         saddr, ifa->iface->name);
        !          1367: 
        !          1368:   init_list(&msgs);
        !          1369: 
        !          1370:   /* First pass through the packet TLV by TLV, parsing each into internal data
        !          1371:      structures. */
        !          1372:   for (tlv = FIRST_TLV(pkt);
        !          1373:        (byte *)tlv < end;
        !          1374:        tlv = NEXT_TLV(tlv))
        !          1375:   {
        !          1376:     /* Ugly special case */
        !          1377:     if (tlv->type == BABEL_TLV_PAD1)
        !          1378:       continue;
        !          1379: 
        !          1380:     /* The end of the common TLV header */
        !          1381:     pos = (byte *)tlv + sizeof(struct babel_tlv);
        !          1382:     if ((pos > end) || (pos + tlv->length > end))
        !          1383:     {
        !          1384:       LOG_PKT("Bad TLV from %I via %s type %d pos %d - framing error",
        !          1385:              saddr, ifa->iface->name, tlv->type, (byte *)tlv - (byte *)pkt);
        !          1386:       break;
        !          1387:     }
        !          1388: 
        !          1389:     msg = sl_alloc(p->msg_slab);
        !          1390:     res = babel_read_tlv(tlv, &msg->msg, &state);
        !          1391:     if (res == PARSE_SUCCESS)
        !          1392:     {
        !          1393:       add_tail(&msgs, NODE msg);
        !          1394:     }
        !          1395:     else if (res == PARSE_IGNORE)
        !          1396:     {
        !          1397:       DBG("Babel: Ignoring TLV of type %d\n", tlv->type);
        !          1398:       sl_free(p->msg_slab, msg);
        !          1399:     }
        !          1400:     else /* PARSE_ERROR */
        !          1401:     {
        !          1402:       LOG_PKT("Bad TLV from %I via %s type %d pos %d - parse error",
        !          1403:              saddr, ifa->iface->name, tlv->type, (byte *)tlv - (byte *)pkt);
        !          1404:       sl_free(p->msg_slab, msg);
        !          1405:       break;
        !          1406:     }
        !          1407:   }
        !          1408: 
        !          1409:   /* Parsing done, handle all parsed TLVs */
        !          1410:   WALK_LIST_FIRST(msg, msgs)
        !          1411:   {
        !          1412:     if (tlv_data[msg->msg.type].handle_tlv)
        !          1413:       tlv_data[msg->msg.type].handle_tlv(&msg->msg, ifa);
        !          1414:     rem_node(NODE msg);
        !          1415:     sl_free(p->msg_slab, msg);
        !          1416:   }
        !          1417: }
        !          1418: 
        !          1419: static void
        !          1420: babel_err_hook(sock *sk, int err)
        !          1421: {
        !          1422:   struct babel_iface *ifa = sk->data;
        !          1423:   struct babel_proto *p = ifa->proto;
        !          1424: 
        !          1425:   log(L_ERR "%s: Socket error on %s: %M", p->p.name, ifa->iface->name, err);
        !          1426:   /* FIXME: Drop queued TLVs here? */
        !          1427: }
        !          1428: 
        !          1429: 
        !          1430: static void
        !          1431: babel_tx_hook(sock *sk)
        !          1432: {
        !          1433:   struct babel_iface *ifa = sk->data;
        !          1434: 
        !          1435:   DBG("Babel: TX hook called (iface %s, src %I, dst %I)\n",
        !          1436:       sk->iface->name, sk->saddr, sk->daddr);
        !          1437: 
        !          1438:   babel_send_queue(ifa);
        !          1439: }
        !          1440: 
        !          1441: 
        !          1442: static int
        !          1443: babel_rx_hook(sock *sk, uint len)
        !          1444: {
        !          1445:   struct babel_iface *ifa = sk->data;
        !          1446:   struct babel_proto *p = ifa->proto;
        !          1447:   const char *err_dsc = NULL;
        !          1448:   uint err_val = 0;
        !          1449: 
        !          1450:   if (sk->lifindex != ifa->iface->index)
        !          1451:     return 1;
        !          1452: 
        !          1453:   DBG("Babel: RX hook called (iface %s, src %I, dst %I)\n",
        !          1454:       sk->iface->name, sk->faddr, sk->laddr);
        !          1455: 
        !          1456:   /* Silently ignore my own packets */
        !          1457:   if (ipa_equal(sk->faddr, sk->saddr))
        !          1458:     return 1;
        !          1459: 
        !          1460:   if (!ipa_is_link_local(sk->faddr))
        !          1461:     DROP1("wrong src address");
        !          1462: 
        !          1463:   if (sk->fport != ifa->cf->port)
        !          1464:     DROP("wrong src port", sk->fport);
        !          1465: 
        !          1466:   if (len < sizeof(struct babel_pkt_header))
        !          1467:     DROP("too short", len);
        !          1468: 
        !          1469:   if (sk->flags & SKF_TRUNCATED)
        !          1470:     DROP("truncated", len);
        !          1471: 
        !          1472:   babel_process_packet((struct babel_pkt_header *) sk->rbuf, len, sk->faddr, ifa);
        !          1473:   return 1;
        !          1474: 
        !          1475: drop:
        !          1476:   LOG_PKT("Bad packet from %I via %s - %s (%u)",
        !          1477:          sk->faddr, sk->iface->name, err_dsc, err_val);
        !          1478:   return 1;
        !          1479: }
        !          1480: 
        !          1481: int
        !          1482: babel_open_socket(struct babel_iface *ifa)
        !          1483: {
        !          1484:   struct babel_proto *p = ifa->proto;
        !          1485: 
        !          1486:   sock *sk;
        !          1487:   sk = sk_new(ifa->pool);
        !          1488:   sk->type = SK_UDP;
        !          1489:   sk->sport = ifa->cf->port;
        !          1490:   sk->dport = ifa->cf->port;
        !          1491:   sk->iface = ifa->iface;
        !          1492:   sk->saddr = ifa->addr;
        !          1493:   sk->vrf = p->p.vrf;
        !          1494: 
        !          1495:   sk->rx_hook = babel_rx_hook;
        !          1496:   sk->tx_hook = babel_tx_hook;
        !          1497:   sk->err_hook = babel_err_hook;
        !          1498:   sk->data = ifa;
        !          1499: 
        !          1500:   sk->tos = ifa->cf->tx_tos;
        !          1501:   sk->priority = ifa->cf->tx_priority;
        !          1502:   sk->ttl = 1;
        !          1503:   sk->flags = SKF_LADDR_RX;
        !          1504: 
        !          1505:   if (sk_open(sk) < 0)
        !          1506:     goto err;
        !          1507: 
        !          1508:   if (sk_setup_multicast(sk) < 0)
        !          1509:     goto err;
        !          1510: 
        !          1511:   if (sk_join_group(sk, IP6_BABEL_ROUTERS) < 0)
        !          1512:     goto err;
        !          1513: 
        !          1514:   ifa->sk = sk;
        !          1515:   return 1;
        !          1516: 
        !          1517: err:
        !          1518:   sk_log_error(sk, p->p.name);
        !          1519:   rfree(sk);
        !          1520:   return 0;
        !          1521: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>