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>