Return to packets.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird2 / proto / babel |
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: }