Beispiel #1
0
/* Send a single update or retraction. */
int
send_update(int sock, struct interface *interface, int retract)
{
    unsigned char buf[12 + 20];
    int i = 0;

    if(!have_prefix)
        /* Nothing to announce. */
        return 0;

    buf[i] = MESSAGE_ROUTER_ID; i++; /* Type */
    buf[i] = 10; i++;                /* Length */
    DO_HTONS(buf + i, 0); i += 2;
    memcpy(buf + i, my_router_id, 8); i += 8;

    buf[i] = MESSAGE_UPDATE; i++; /* Type */
    buf[i] = 18; i++;             /* Length */
    buf[i] = AE_IPV6; i++;        /* AE */
    buf[i] = 0; i++;              /* Flags */
    buf[i] = 64; i++;             /* Plen */
    buf[i] = 0; i++;              /* Omitted */
    DO_HTONS(buf + i, update_interval * 100); i+= 2; /* Interval */
    DO_HTONS(buf + i, myseqno); i += 2;              /* Seqno */
    DO_HTONS(buf + i, retract ? INFINITY : 0); i += 2; /* Metric */
    memcpy(buf + i, myprefix, 8); i += 8; /* Address */

    assert(i == 12 + 20);

    return send_packet(sock, interface->ifindex, &babel_group, buf, i);
}
Beispiel #2
0
int
buffer_tlv(int type, const unsigned char *data, int datalen,
           const struct sockaddr_in6 *sin6, struct interface *interface)
{
    if(interface && sin6) {
        errno = EINVAL;
        return -1;
    }

    if(sendbuf == NULL)
        sendbuf = allocate_buffer(SENDBUF_SIZE);
    if(sendbuf == NULL)
        return -1;

    if(buffered &&
       ((interface && interface != buffered_interface) ||
        (!interface && (buffered_interface ||
                        memcmp(sin6, &buffered_sin6, sizeof(*sin6)) != 0)) ||
        buffered + datalen > 1400))
        flushbuf();

    if(buffered + datalen + 4 > SENDBUF_SIZE) {
        errno = EMSGSIZE;
        return -1;
    }

    if(!buffered) {
        /* NODE-ENDPOINT */
        DO_HTONS(sendbuf + 0, 3);
        DO_HTONS(sendbuf + 2, 8);
        memcpy(sendbuf + 4, myid, 4);
        DO_HTONL(sendbuf + 8,
                 interface ? interface->ifindex : sin6->sin6_scope_id);
        buffered = 12;
    }

    if(interface)
        buffered_interface = interface;
    else
        memcpy(&buffered_sin6, sin6, sizeof(*sin6));

    DO_HTONS(sendbuf + buffered, type); buffered += 2;
    DO_HTONS(sendbuf + buffered, datalen); buffered += 2;
    memcpy(sendbuf + buffered, data, datalen); buffered += datalen;

    if(debug_level >= 3)
        debugf("Buffering %s %d (%d)\n",
               interface ? "multicast" : "unicast", type, datalen);

    return 1;
}
Beispiel #3
0
static int
dnsBuildQuery(int id, char *buf, int offset, int n, AtomPtr name, int af)
{
    int i = offset;
    int type;
    switch(af) {
    case 4: type = 1; break;
    case 6: type = 28; break;
    default: return -EINVAL;
    }

    if(i + 12 >= n) return -1;
    DO_HTONS(&buf[i], id); i += 2;
    DO_HTONS(&buf[i], 1<<8); i += 2;
    DO_HTONS(&buf[i], 1); i += 2;
    DO_HTONS(&buf[i], 0); i += 2;
    DO_HTONS(&buf[i], 0); i += 2;
    DO_HTONS(&buf[i], 0); i += 2;

    i = stringToLabels(buf, i, n, name->string);
    if(i < 0) return -ENAMETOOLONG;
    
    if(i + 4 >= n) return -ENAMETOOLONG;
    DO_HTONS(&buf[i], type); i += 2;
    DO_HTONS(&buf[i], 1); i += 2;
    return i;
}
Beispiel #4
0
int
send_hello(int sock, struct interface *interface)
{
    unsigned char buf[8 + 16 * MAXNEIGHBOURS];
    int i = 0, j;
    struct timeval now;

    /* Hello */
    buf[i] = MESSAGE_HELLO; i++; /* Type */
    buf[i] = 6; i++;            /* Length */
    DO_HTONS(buf + i, 0); i += 2;
    DO_HTONS(buf + i, interface->seqno); i += 2; /* Seqno */
    interface->seqno++;
    DO_HTONS(buf + i, hello_interval * 100); i += 2;  /* Interval */

    gettime(&now);
    for(j = 0; j < numneighbours; j++) {
        unsigned short cost;
        if(neighbours[j].interface != interface)
            continue;
        if(neighbour_expired(j, &now))
            cost = INFINITY;
        else
            cost = link_cost;

        /* IHU */
        buf[i] = MESSAGE_IHU; i++; /* Type */
        buf[i] = 14; i++;       /* Length */
        buf[i] = AE_LL; i++;    /* AE */
        buf[i] = 0; i++;
        DO_HTONS(buf + i, cost); i += 2; /* rxcost */
        DO_HTONS(buf + i, hello_interval * 100); i += 2; /* Interval */
        memcpy(buf + i, ((unsigned char *)(&neighbours[j].address)) + 8, 8);
        i += 8;                 /* Address */
    }

    assert((i - 8) % 16 == 0 && i - 8 <= 16 * numneighbours);

    return send_packet(sock, interface->ifindex, &babel_group, buf, i);
}
Beispiel #5
0
int
send_packet(int sock, int ifindex, struct in6_addr *to,
            unsigned char *body, unsigned char bodylen)
{
    struct sockaddr_in6 sin6;
    unsigned char header[4];

    header[0] = 42;
    header[1] = 2;
    DO_HTONS(header + 2, bodylen);

    /* Additional jitter never harms. */
    nap(10);

    memset(&sin6, 0, sizeof(sin6));
    sin6.sin6_family = AF_INET6;
    memcpy(&sin6.sin6_addr, &babel_group, 16);
    sin6.sin6_port = htons(babel_port);
    sin6.sin6_scope_id = ifindex;
    return babel_send(sock, header, 4, body, bodylen,
                      (struct sockaddr*)&sin6, sizeof(sin6));
}