📄 lq_packet.c
字号:
if ((int)(size + req) > rem) { // finalize the OLSR header lq_hello->comm.size = size + off; serialize_common(&lq_hello->comm); // finalize the info header info_head->size = ntohs(buff + size - (unsigned char *)info_head); // output packet net_outbuffer_push(outif, msg_buffer, size + off); net_output(outif); // move to the beginning of the buffer size = 0; rem = net_outbuffer_bytes_left(outif) - off; // we need a new info header is_first = 1; } // create a new info header if (is_first != 0) { info_head = (struct lq_hello_info_header *)(buff + size); size += sizeof (struct lq_hello_info_header); info_head->reserved = 0; info_head->link_code = CREATE_LINK_CODE(i, LINK_ORDER[j]); } // add the current neighbor's IP address COPY_IP(buff + size, &neigh->addr); size += olsr_cnf->ipsize; // add the corresponding link quality buff[size++] = (unsigned char)(neigh->link_quality * 255); buff[size++] = (unsigned char)(neigh->neigh_link_quality * 255); // pad buff[size++] = 0; buff[size++] = 0; is_first = 0; } // finalize the info header, if there are any neighbors with the // current neighbor type and link type if (is_first == 0) info_head->size = ntohs(buff + size - (unsigned char *)info_head); } } // finalize the OLSR header lq_hello->comm.size = size + off; serialize_common((struct olsr_common *)lq_hello); // move the message to the output buffer net_outbuffer_push(outif, msg_buffer, size + off);}static voidserialize_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif){ int off, rem, size; struct lq_tc_header *head; struct tc_mpr_addr *neigh; unsigned char *buff; // leave space for the OLSR header off = common_size(); // initialize the LQ_TC header head = (struct lq_tc_header *)(msg_buffer + off); head->ansn = htons(lq_tc->ansn); head->reserved = 0; // 'off' is the offset of the byte following the LQ_TC header off += sizeof (struct lq_tc_header); // our work buffer starts at 'off'... buff = msg_buffer + off; // ... that's why we start with a 'size' of 0 and subtract 'off' from // the remaining bytes in the output buffer size = 0; rem = net_outbuffer_bytes_left(outif) - off; // initially, we want to put at least an IP address and the corresponding // link quality into the message // force signed comparison if (rem < (int)(olsr_cnf->ipsize + 4)) { net_output(outif); rem = net_outbuffer_bytes_left(outif) - off; } // loop through neighbors for (neigh = lq_tc->neigh; neigh != NULL; neigh = neigh->next) { // we need space for an IP address plus link quality // information // force signed comparison if ((int)(size + olsr_cnf->ipsize + 4) > rem) { // finalize the OLSR header lq_tc->comm.size = size + off; serialize_common((struct olsr_common *)lq_tc); // output packet net_outbuffer_push(outif, msg_buffer, size + off); net_output(outif); // move to the beginning of the buffer size = 0; rem = net_outbuffer_bytes_left(outif) - off; } // add the current neighbor's IP address COPY_IP(buff + size, &neigh->address); size += olsr_cnf->ipsize; // add the corresponding link quality buff[size++] = (unsigned char)(neigh->link_quality * 255); buff[size++] = (unsigned char)(neigh->neigh_link_quality * 255); // pad buff[size++] = 0; buff[size++] = 0; } // finalize the OLSR header lq_tc->comm.size = size + off; serialize_common((struct olsr_common *)lq_tc); net_outbuffer_push(outif, msg_buffer, size + off);}static intdeserialize_lq_hello(struct hello_message *hello, const void *ser){ const unsigned char *limit; olsr_u8_t type; olsr_u16_t size; const unsigned char *curr = ser; pkt_get_u8(&curr, &type); if (type != LQ_HELLO_MESSAGE) { /* No need to do anything more */ return 1; } pkt_get_double(&curr, &hello->vtime); pkt_get_u16(&curr, &size); // Sven-Ola: Check the message source addr if (!olsr_validate_address((const union olsr_ip_addr *)curr)) { /* No need to do anything more */ return 1; } pkt_get_ipaddress(&curr, &hello->source_addr); pkt_get_u8(&curr, &hello->ttl); pkt_get_u8(&curr, &hello->hop_count); pkt_get_u16(&curr, &hello->packet_seq_number); pkt_ignore_u16(&curr); pkt_get_double(&curr, &hello->htime); pkt_get_u8(&curr, &hello->willingness); hello->neighbors = NULL; limit = ser + size; while (curr < limit) { struct lq_hello_info_header *info_head = (struct lq_hello_info_header *)curr; const unsigned char *limit2 = curr + ntohs(info_head->size); curr = (unsigned char *)(info_head + 1); while (curr < limit2) { struct hello_neighbor *neigh = olsr_malloc(sizeof (struct hello_neighbor), "LQ_HELLO deserialization"); pkt_get_ipaddress(&curr, &neigh->address); pkt_get_lq(&curr, &neigh->link_quality); pkt_get_lq(&curr, &neigh->neigh_link_quality); pkt_ignore_u16(&curr); neigh->link = EXTRACT_LINK(info_head->link_code); neigh->status = EXTRACT_STATUS(info_head->link_code); neigh->next = hello->neighbors; hello->neighbors = neigh; } } return 0;}static intdeserialize_lq_tc(struct tc_message *tc, const void *ser, union olsr_ip_addr *from){ const union olsr_ip_addr *addr; olsr_u8_t type; olsr_u16_t size; const unsigned char *limit; // convert received packet from transmission format into internal format const unsigned char *curr = ser; pkt_get_u8(&curr, &type); if (type != LQ_TC_MESSAGE) { /* No need to do anything more */ return 1; } pkt_get_double(&curr, &tc->vtime); pkt_get_u16(&curr, &size); // Sven-Ola: Check the message source addr if (!olsr_validate_address((const union olsr_ip_addr *)curr)) { /* No need to do anything more */ return 1; } pkt_get_ipaddress(&curr, &tc->originator); addr = mid_lookup_main_addr(from); if (addr == NULL) { addr = from; } // Sven-Ola: Check the message source addr if (!olsr_validate_address(addr)) { return 1; } COPY_IP(&tc->source_addr, addr); pkt_get_u8(&curr, &tc->ttl); pkt_get_u8(&curr, &tc->hop_count); pkt_get_u16(&curr, &tc->packet_seq_number); pkt_get_u16(&curr, &tc->ansn); pkt_ignore_u16(&curr); tc->multipoint_relay_selector_address = NULL; limit = ser + size; while (curr < limit) { struct tc_mpr_addr *neigh; if (!olsr_validate_address((const union olsr_ip_addr *)curr)) { /* Ignore the same amount as below */ pkt_ignore_ipaddress(&curr); pkt_ignore_u8(&curr); pkt_ignore_u8(&curr); pkt_ignore_u16(&curr); continue; } neigh = olsr_malloc(sizeof (struct tc_mpr_addr), "LQ_TC deserialization"); pkt_get_ipaddress(&curr, &neigh->address); pkt_get_lq(&curr, &neigh->link_quality); pkt_get_lq(&curr, &neigh->neigh_link_quality); pkt_ignore_u16(&curr); neigh->next = tc->multipoint_relay_selector_address; tc->multipoint_relay_selector_address = neigh; } return 0;}voidolsr_output_lq_hello(void *para){ struct lq_hello_message lq_hello; struct interface *outif = para; if (outif == NULL) { return; } // create LQ_HELLO in internal format create_lq_hello(&lq_hello, outif); // convert internal format into transmission format, send it serialize_lq_hello(&lq_hello, outif); // destroy internal format destroy_lq_hello(&lq_hello); if(net_output_pending(outif)) { net_output(outif); }}voidolsr_output_lq_tc(void *para){ static int prev_empty = 1; struct lq_tc_message lq_tc; struct interface *outif = para; if (outif == NULL) { return; } // create LQ_TC in internal format create_lq_tc(&lq_tc, outif); // a) the message is not empty if (lq_tc.neigh != NULL) { prev_empty = 0; // convert internal format into transmission format, send it serialize_lq_tc(&lq_tc, outif); // b) this is the first empty message } else if (prev_empty == 0) { // initialize timer set_empty_tc_timer(GET_TIMESTAMP(olsr_cnf->max_tc_vtime * 3 * 1000)); prev_empty = 1; // convert internal format into transmission format, send it serialize_lq_tc(&lq_tc, outif); // c) this is not the first empty message, send if timer hasn't fired } else if (!TIMED_OUT(get_empty_tc_timer())) { serialize_lq_tc(&lq_tc, outif); } // destroy internal format destroy_lq_tc(&lq_tc); if(net_output_pending(outif) && TIMED_OUT(outif->fwdtimer)) { set_buffer_timer(outif); }}voidolsr_input_lq_hello(union olsr_message *ser, struct interface *inif, union olsr_ip_addr *from){ struct hello_message hello; if (ser == NULL) { return; } if (deserialize_lq_hello(&hello, ser) != 0) { return; } olsr_hello_tap(&hello, inif, from);}voidolsr_input_lq_tc(union olsr_message *ser, struct interface *inif, union olsr_ip_addr *from){ struct tc_message tc; if (ser == NULL) { return; } if (deserialize_lq_tc(&tc, ser, from) != 0) { return; } olsr_tc_tap(&tc, inif, from, ser);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -