/** * Capture a regular expression from the user, one key at a time. * This modifies the global variables regex_cur and regex_last. * * \param sview * The source viewer. * * \return * 0 if user gave a regex, otherwise 1. */ static int status_bar_regex_input(struct sviewer *sview, int key) { int regex_icase = cgdbrc_get(CGDBRC_IGNORECASE)->variant.int_val; /* Flag to indicate we're done with regex mode, need to switch back */ int done = 0; /* Recieve a regex from the user. */ switch (key) { case '\r': case '\n': case CGDB_KEY_CTRL_M: /* Save for future searches via 'n' or 'N' */ if (regex_last != NULL) { ibuf_free(regex_last); } regex_last = ibuf_dup(regex_cur); regex_direction_last = regex_direction_cur; source_search_regex(sview, ibuf_get(regex_last), 2, regex_direction_last, regex_icase); if_draw(); done = 1; break; case 8: case 127: /* Backspace or DEL key */ if (ibuf_length(regex_cur) == 0) { done = 1; } else { ibuf_delchar(regex_cur); source_search_regex(sview, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(); } break; default: if (kui_term_is_cgdb_key(key)) { const char *keycode = kui_term_get_keycode_from_cgdb_key(key); int length = strlen(keycode), i; for (i = 0; i < length; i++) ibuf_addchar(regex_cur, keycode[i]); } else { ibuf_addchar(regex_cur, key); } source_search_regex(sview, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(); }; if (done) { ibuf_free(regex_cur); regex_cur = NULL; if_set_focus(CGDB); } return 0; }
void tcp_read_buf(int s, short event, void *arg) { ssize_t br; char rbuf[SMALL_READ_BUF_SIZE]; struct ctl_tcp_event *cte = arg; if (event == EV_TIMEOUT) { cte->host->up = HOST_DOWN; ibuf_free(cte->buf); close(s); hce_notify_done(cte->host, HCE_TCP_READ_TIMEOUT); return; } bzero(rbuf, sizeof(rbuf)); br = read(s, rbuf, sizeof(rbuf) - 1); switch (br) { case -1: if (errno == EAGAIN || errno == EINTR) goto retry; cte->host->up = HOST_DOWN; ibuf_free(cte->buf); close(cte->s); hce_notify_done(cte->host, HCE_TCP_READ_FAIL); return; case 0: cte->host->up = HOST_DOWN; (void)cte->validate_close(cte); close(cte->s); ibuf_free(cte->buf); hce_notify_done(cte->host, cte->host->he); return; default: if (ibuf_add(cte->buf, rbuf, br) == -1) fatal("tcp_read_buf: buf_add error"); if (cte->validate_read != NULL) { if (cte->validate_read(cte) != 0) goto retry; close(cte->s); ibuf_free(cte->buf); hce_notify_done(cte->host, cte->host->he); return; } break; /* retry */ } retry: event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, tcp_read_buf, &cte->tv_start, &cte->table->conf.timeout, cte); }
/* main: * * Description of test procedure here. */ int main(int argc, char *argv[]) { ibuf s = NULL; int result = 0; /* Create a tree */ debug("Creating string... "); s = ibuf_init(); if (s == NULL) { printf("FAILED\n"); return 1; } debug("Succeeded.\n"); /* Run tests */ result |= test_add(s); result |= test_addchar(s); result |= test_delchar(s); result |= test_dup(s); result |= test_trim(s); debug("Destroying string...\n"); ibuf_free(s); if (result) { printf("FAILED\n"); return 2; } printf("PASSED\n"); return 0; }
int Ctgdb::Process_console_command(tgdb_request_ptr request) { struct ibuf *command; if (!request) return -1; if (!Can_issue_command()) return -1; if (request->header != TGDB_REQUEST_CONSOLE_COMMAND) return -1; command = ibuf_init (); ibuf_add (command, request->choice.console_command.command); ibuf_addchar (command, '\n'); if (Send(ibuf_get (command), TGDB_COMMAND_CONSOLE) == -1) { Logger_write_pos( __FILE__, __LINE__, "tgdb_send failed"); return -1; } ibuf_free (command); command = NULL; return 0; }
void if_shutdown(void) { /* Shut down curses cleanly */ if (curses_initialized) swin_endwin(); if (status_win) { swin_delwin(status_win); status_win = NULL; } if (gdb_scroller) { scr_free(gdb_scroller); gdb_scroller = NULL; } if (src_viewer) { source_free(src_viewer); src_viewer = NULL; } if (vseparator_win) { swin_delwin(vseparator_win); vseparator_win = NULL; } if (G_line_number) { ibuf_free(G_line_number); G_line_number = 0; } }
int imsg_add(struct ibuf *msg, const void *data, u_int16_t datalen) { if (datalen) if (ibuf_add(msg, data, datalen) == -1) { ibuf_free(msg); return (-1); } return (datalen); }
void tcp_close(struct ctl_tcp_event *cte, int status) { close(cte->s); cte->s = -1; if (status != 0) cte->host->up = status; if (cte->buf) { ibuf_free(cte->buf); cte->buf = NULL; } }
static int test_dup(ibuf s) { ibuf t; /* Test duplicating a string. */ ibuf_add(s, "test string 1"); t = ibuf_dup(s); if (t == NULL) { debug("test_dup: ibuf_dup (attempt #1) returned NULL\n"); return 1; } if (strcmp(ibuf_get(s), ibuf_get(t)) != 0) { debug("test_dup: Strings mismatched: \"%s\" != \"%s\"\n", ibuf_get(s), ibuf_get(t)); return 1; } ibuf_free(t); /* Corner case: duplicate an empty string */ ibuf_clear(s); t = ibuf_dup(s); if (t == NULL) { debug("test_dup: ibuf_dup (attempt #2) returned NULL\n"); return 1; } if (strcmp(ibuf_get(t), "") != 0) { debug("test_dup: Expected empty string, got: %s\n", ibuf_get(t)); return 1; } ibuf_free(t); debug("test_dup: Succeeded.\n"); return 0; }
void ssl_cleanup(struct ctl_tcp_event *cte) { close(cte->s); if (cte->ssl != NULL) { SSL_shutdown(cte->ssl); SSL_clear(cte->ssl); } if (cte->buf != NULL) { ibuf_free(cte->buf); cte->buf = NULL; } }
/* DVMRP neighbors2 packet handling */ int send_nbrs2(struct iface *iface, struct in_addr addr, void *data, int len) { struct sockaddr_in dst; struct ibuf *buf; struct dvmrp_hdr *dvmrp_hdr; int ret = 0; log_debug("send_nbrs2: interface %s addr %s", iface->name, inet_ntoa(addr)); if (iface->passive) return (0); if ((buf = ibuf_open(iface->mtu - sizeof(struct ip))) == NULL) fatal("send_nbrs2"); /* DVMRP header */ if (gen_dvmrp_hdr(buf, iface, DVMRP_CODE_GRAFT_ACK)) goto fail; dst.sin_family = AF_INET; dst.sin_len = sizeof(struct sockaddr_in); dst.sin_addr.s_addr = addr.s_addr; /* update chksum */ dvmrp_hdr = ibuf_seek(buf, 0, sizeof(dvmrp_hdr)); dvmrp_hdr->chksum = in_cksum(buf->buf, buf->wpos); ret = send_packet(iface, buf->buf, buf->wpos, &dst); ibuf_free(buf); return (ret); fail: log_warn("send_nbrs2"); ibuf_free(buf); return (-1); }
/* cleanup: Invoked by the various err_xxx funtions when dying. * -------- */ void cleanup() { char *log_file, *tmp_log_file; int has_recv_data; ibuf_free(current_line); /* Cleanly scroll the screen up for a prompt */ scrl(1); move(LINES - 1, 0); printf("\n"); rline_write_history(rline, readline_history_path); /* The order of these is important. They each must restore the terminal * the way they found it. Thus, the order in which curses/readline is * started, is the reverse order in which they should be shutdown */ /* Shut down interface */ if_shutdown(); #if 0 if (masterfd != -1) util_free_tty(&masterfd, &slavefd, tty_name); #endif /* Finally, should display the errors. * TGDB guarentees the logger to be open at this point. * So, we can get the filename directly from the logger */ logger_get_file(logger, &tmp_log_file); log_file = strdup(tmp_log_file); logger_has_recv_data(logger, &has_recv_data); /* Shut down debugger */ tgdb_shutdown(tgdb); if (tty_set_attributes(STDIN_FILENO, &term_attributes) == -1) logger_write_pos(logger, __FILE__, __LINE__, "tty_reset error"); if (has_recv_data) fprintf(stderr, "CGDB had unexpected results, see %s for details.\n", log_file); free(log_file); log_file = NULL; }
int highlight_node(const char *filename, struct buffer *buf) { int ret; int length = 0; int lasttype = -1; struct ibuf *ibuf = ibuf_init(); struct tokenizer *t = tokenizer_init(); if (tokenizer_set_file(t, filename, buf->language) == -1) { if_print_message("%s:%d tokenizer_set_file error", __FILE__, __LINE__); return -1; } while ((ret = tokenizer_get_token(t)) > 0) { enum tokenizer_type e = tokenizer_get_packet_type(t); /*if_print_message ( "TOKEN(%d:%s)\n", e, tokenizer_get_printable_enum ( e ) ); */ if (e == TOKENIZER_NEWLINE) { sbpush(buf->tlines, strdup(ibuf_get(ibuf))); if (length > buf->max_width) buf->max_width = length; length = 0; lasttype = -1; ibuf_clear(ibuf); } else { const char *tok_data = tokenizer_get_data(t); enum hl_group_kind hlg = hlg_from_tokenizer_type(e, tok_data); if (hlg == HLG_LAST) { logger_write_pos(logger, __FILE__, __LINE__, "Bad hlg_type for '%s', e==%d\n", tok_data, e); hlg = HLG_TEXT; } /* Set the highlight group type */ add_type(ibuf, &lasttype, hlg); /* Add the text and bump our length */ length += ibuf_add(ibuf, tok_data); } } ibuf_free(ibuf); tokenizer_destroy(t); return 0; }
static int status_bar_normal_input(int key) { /* Flag to indicate we're done with status mode, need to switch back */ int done = 0; /* The goal of this state is to recieve a command from the user. */ switch (key) { case '\r': case '\n': case CGDB_KEY_CTRL_M: /* Found a command */ if_run_command(src_win, cur_sbc); done = 1; break; case 8: case 127: /* Backspace or DEL key */ if (ibuf_length(cur_sbc) == 0) { done = 1; } else { ibuf_delchar(cur_sbc); update_status_win(); } break; default: if (kui_term_is_cgdb_key(key)) { const char *keycode = kui_term_get_keycode_from_cgdb_key(key); int length = strlen(keycode), i; for (i = 0; i < length; i++) ibuf_addchar(cur_sbc, keycode[i]); } else { ibuf_addchar(cur_sbc, key); } update_status_win(); break; }; if (done) { ibuf_free(cur_sbc); cur_sbc = NULL; if_set_focus(CGDB); } return 0; }
void filedlg_free(struct filedlg *fdlg) { filedlg_clear(fdlg); ibuf_free(fdlg->G_line_number); hl_regex_free(&fdlg->last_hlregex); fdlg->last_hlregex = NULL; hl_regex_free(&fdlg->hlregex); fdlg->hlregex = NULL; swin_delwin(fdlg->win); fdlg->win = NULL; free(fdlg->buf); fdlg->buf = NULL; free(fdlg); }
void send_notification_full(struct tcp_conn *tcp, struct notify_msg *nm) { struct ibuf *buf; uint16_t size; int err = 0; /* calculate size */ size = LDP_HDR_SIZE + LDP_MSG_SIZE + STATUS_SIZE; if (nm->flags & F_NOTIF_PW_STATUS) size += PW_STATUS_TLV_SIZE; if (nm->flags & F_NOTIF_FEC) { size += TLV_HDR_SIZE; switch (nm->fec.type) { case MAP_TYPE_PWID: size += FEC_PWID_ELM_MIN_LEN; if (nm->fec.flags & F_MAP_PW_ID) size += sizeof(uint32_t); break; } } if ((buf = ibuf_open(size)) == NULL) fatal(__func__); err |= gen_ldp_hdr(buf, size); size -= LDP_HDR_SIZE; err |= gen_msg_hdr(buf, MSG_TYPE_NOTIFICATION, size); err |= gen_status_tlv(buf, nm->status_code, nm->msg_id, nm->msg_type); /* optional tlvs */ if (nm->flags & F_NOTIF_PW_STATUS) err |= gen_pw_status_tlv(buf, nm->pw_status); if (nm->flags & F_NOTIF_FEC) err |= gen_fec_tlv(buf, &nm->fec); if (err) { ibuf_free(buf); return; } evbuf_enqueue(&tcp->wbuf, buf); }
int Ctgdb::Send(char *command, enum tgdb_command_choice command_choice, ITarget* target) { struct tgdb_command *tc; struct ibuf *temp_command = ibuf_init (); int length = strlen (command); /* Add a newline to the end of the command if it doesn't exist */ ibuf_add (temp_command, command); if (command[length - 1] != '\n') ibuf_addchar (temp_command, '\n'); /* Create the client command */ tc = tgdb_command_create (ibuf_get (temp_command), command_choice, NULL); tc->ITarget = (void*) target; ibuf_free (temp_command); temp_command = NULL; if (Run_or_queue_command(tc) == -1) { Logger_write_pos( __FILE__, __LINE__, "tgdb_run_or_queue_command failed"); return -1; } if (tgdb_client_tgdb_ran_command(tcc) == -1) { Logger_write_pos( __FILE__, __LINE__, "tgdb_client_tgdb_ran_command failed"); return -1; } Process_client_commands(); return 0; }
int send_hello(struct iface *iface) { struct sockaddr_in dst; struct ibuf *buf; u_int16_t size; dst.sin_port = htons(LDP_PORT); dst.sin_family = AF_INET; dst.sin_len = sizeof(struct sockaddr_in); inet_aton(AllRouters, &dst.sin_addr); if (iface->passive) return (0); if ((buf = ibuf_open(LDP_MAX_LEN)) == NULL) fatal("send_hello"); size = LDP_HDR_SIZE + sizeof(struct ldp_msg) + sizeof(struct hello_prms_tlv); gen_ldp_hdr(buf, iface, size); size -= LDP_HDR_SIZE; gen_msg_tlv(buf, MSG_TYPE_HELLO, size); size -= sizeof(struct ldp_msg); gen_hello_prms_tlv(iface, buf, size); send_packet(iface, buf->buf, buf->wpos, &dst); ibuf_free(buf); return (0); }
void state_machine_shutdown ( struct state_machine *sm ) { ibuf_free (sm->tgdb_buffer); free ( sm ); sm = NULL; }
int internal_if_input(int key, int *last_key) { /* Normally, CGDB_KEY_ESC, but can be configured by the user */ int cgdb_mode_key = cgdbrc_get_int(CGDBRC_CGDB_MODE_KEY); /* The cgdb mode key, puts the debugger into command mode */ if (focus != CGDB && key == cgdb_mode_key) { enum Focus new_focus = CGDB; /* Depending on which cgdb was in, it can free some memory here that * it was previously using. */ if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_NORMAL) { ibuf_free(cur_sbc); cur_sbc = NULL; } else if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_REGEX) { ibuf_free(regex_cur); regex_cur = NULL; hl_regex_free(&src_viewer->hlregex); src_viewer->cur->sel_rline = orig_line_regex; src_viewer->cur->sel_line = orig_line_regex; sbc_kind = SBC_NORMAL; } else if (focus == GDB && sbc_kind == SBC_REGEX) { ibuf_free(regex_cur); regex_cur = NULL; gdb_scroller->in_search_mode = 0; sbc_kind = SBC_NORMAL; new_focus = GDB; } if_set_focus(new_focus); return 0; } /* If you are already in cgdb mode, the cgdb mode key does nothing */ else if (key == cgdb_mode_key) return 0; /* Check for global keystrokes */ switch (focus) { case CGDB: return cgdb_input(key, last_key); case GDB: return gdb_input(key, last_key); case FILE_DLG: { char filedlg_file[MAX_LINE]; int ret = filedlg_recv_char(fd, key, filedlg_file, last_key_pressed); /* The user cancelled */ if (ret == -1) { if_set_focus(CGDB); return 0; /* Needs more data */ } else if (ret == 0) { return 0; /* The user picked a file */ } else if (ret == 1) { if_show_file(filedlg_file, 0, 0); if_set_focus(CGDB); return 0; } } return 0; case CGDB_STATUS_BAR: return status_bar_input(src_viewer, key); } /* Never gets here */ return 0; }
/** * Capture a regular expression from the user, one key at a time. * This modifies the global variables regex_cur and regex_last. * * \param sview * The source viewer. * * \return * 0 if user gave a regex, otherwise 1. */ static int gdb_input_regex_input(struct scroller *scr, int key) { int regex_icase = cgdbrc_get_int(CGDBRC_IGNORECASE); /* Flag to indicate we're done with regex mode, need to switch back */ int done = 0; /* Receive a regex from the user. */ switch (key) { case '\r': case '\n': case CGDB_KEY_CTRL_M: /* Save for future searches via 'n' or 'N' */ ibuf_free(regex_last); regex_last = ibuf_dup(regex_cur); regex_direction_last = regex_direction_cur; scr_search_regex(scr, ibuf_get(regex_last), 2, regex_direction_last, regex_icase); if_draw(); done = 1; break; case 8: case 127: /* Backspace or DEL key */ if (ibuf_length(regex_cur) == 0) { done = 1; scr_search_regex(scr, "", 2, regex_direction_cur, regex_icase); } else { ibuf_delchar(regex_cur); scr_search_regex(scr, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(WIN_REFRESH); } break; default: if (kui_term_is_cgdb_key(key)) { const char *keycode = kui_term_get_keycode_from_cgdb_key(key); int length = strlen(keycode), i; for (i = 0; i < length; i++) ibuf_addchar(regex_cur, keycode[i]); } else { ibuf_addchar(regex_cur, key); } scr_search_regex(scr, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(WIN_REFRESH); }; if (done) { gdb_scroller->in_search_mode = 0; ibuf_free(regex_cur); regex_cur = NULL; sbc_kind = SBC_NORMAL; if_set_focus(GDB); } return 0; }
int internal_if_input(int key) { int regex_icase = cgdbrc_get(CGDBRC_IGNORECASE)->variant.int_val; /* Normally, CGDB_KEY_ESC, but can be configured by the user */ int cgdb_mode_key = cgdbrc_get(CGDBRC_CGDB_MODE_KEY)->variant.int_val; /* The cgdb mode key, puts the debugger into command mode */ if (focus != CGDB && key == cgdb_mode_key) { /* Depending on which cgdb was in, it can free some memory here that * it was previously using. */ if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_NORMAL) { ibuf_free(cur_sbc); cur_sbc = NULL; } else if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_REGEX) { ibuf_free(regex_cur); regex_cur = NULL; free(src_win->cur->buf.cur_line); src_win->cur->buf.cur_line = NULL; src_win->cur->sel_rline = orig_line_regex; src_win->cur->sel_line = orig_line_regex; } if_set_focus(CGDB); return 0; } /* If you are already in cgdb mode, the cgdb mode key does nothing */ else if (key == cgdb_mode_key) return 0; /* Check for global keystrokes */ switch (focus) { case CGDB: switch (key) { case 'i': if_set_focus(GDB); return 0; case 'I': if_set_focus(TTY); return 0; case ':': /* Set the type of the command the user is typing in the status bar */ sbc_kind = SBC_NORMAL; if_set_focus(CGDB_STATUS_BAR); /* Since the user is about to type in a command, allocate a buffer * in which this command can be stored. */ cur_sbc = ibuf_init(); return 0; case '/': case '?': if (src_win->cur != NULL) { regex_cur = ibuf_init(); regex_direction_cur = ('/' == key); orig_line_regex = src_win->cur->sel_line; sbc_kind = SBC_REGEX; if_set_focus(CGDB_STATUS_BAR); /* Capturing regular expressions */ source_search_regex_init(src_win); /* Initialize the function for finding a regex and tell user */ if_draw(); } return 0; case 'n': source_search_regex(src_win, ibuf_get(regex_last), 2, regex_direction_last, regex_icase); if_draw(); break; case 'N': source_search_regex(src_win, ibuf_get(regex_last), 2, !regex_direction_last, regex_icase); if_draw(); break; case 'T': if (tty_win_on) { tty_win_on = 0; focus = CGDB; } else { tty_win_on = 1; focus = TTY; } if_layout(); break; case CGDB_KEY_CTRL_T: if (tgdb_tty_new(tgdb) == -1) { /* Error */ } else { scr_free(tty_win); tty_win = NULL; if_layout(); } break; case CGDB_KEY_F1: if_display_help(); return 0; case CGDB_KEY_F5: /* Issue GDB run command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_RUN); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F6: /* Issue GDB continue command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_CONTINUE); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F7: /* Issue GDB finish command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_FINISH); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F8: /* Issue GDB next command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_NEXT); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F10: /* Issue GDB step command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_STEP); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_CTRL_L: if_layout(); return 0; } source_input(src_win, key); return 0; break; case TTY: return tty_input(key); case GDB: return gdb_input(key); case FILE_DLG: { static char filedlg_file[MAX_LINE]; int ret = filedlg_recv_char(fd, key, filedlg_file); /* The user cancelled */ if (ret == -1) { if_set_focus(CGDB); return 0; /* Needs more data */ } else if (ret == 0) { return 0; /* The user picked a file */ } else if (ret == 1) { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_filename_pair(tgdb, filedlg_file); handle_request(tgdb, request_ptr); if_set_focus(CGDB); return 0; } } return 0; case CGDB_STATUS_BAR: return status_bar_input(src_win, key); } /* Never gets here */ return 0; }
/* database description packet handling */ int send_db_description(struct nbr *nbr) { struct in6_addr dst; struct db_dscrp_hdr dd_hdr; struct lsa_entry *le, *nle; struct ibuf *buf; int ret = 0; u_int8_t bits = 0; if ((buf = ibuf_open(nbr->iface->mtu - sizeof(struct ip))) == NULL) fatal("send_db_description"); /* OSPF header */ if (gen_ospf_hdr(buf, nbr->iface, PACKET_TYPE_DD)) goto fail; /* reserve space for database description header */ if (ibuf_reserve(buf, sizeof(dd_hdr)) == NULL) goto fail; switch (nbr->state) { case NBR_STA_DOWN: case NBR_STA_ATTEMPT: case NBR_STA_INIT: case NBR_STA_2_WAY: case NBR_STA_SNAP: log_debug("send_db_description: cannot send packet in state %s," " neighbor ID %s", nbr_state_name(nbr->state), inet_ntoa(nbr->id)); ret = -1; goto done; case NBR_STA_XSTRT: bits |= OSPF_DBD_MS | OSPF_DBD_M | OSPF_DBD_I; nbr->dd_more = 1; break; case NBR_STA_XCHNG: if (nbr->dd_master) bits |= OSPF_DBD_MS; else bits &= ~OSPF_DBD_MS; if (TAILQ_EMPTY(&nbr->db_sum_list)) { bits &= ~OSPF_DBD_M; nbr->dd_more = 0; } else { bits |= OSPF_DBD_M; nbr->dd_more = 1; } bits &= ~OSPF_DBD_I; /* build LSA list */ for (le = TAILQ_FIRST(&nbr->db_sum_list); le != NULL && buf->wpos + sizeof(struct lsa_hdr) < buf->max; le = nle) { nbr->dd_end = nle = TAILQ_NEXT(le, entry); if (ibuf_add(buf, le->le_lsa, sizeof(struct lsa_hdr))) goto fail; } break; case NBR_STA_LOAD: case NBR_STA_FULL: if (nbr->dd_master) bits |= OSPF_DBD_MS; else bits &= ~OSPF_DBD_MS; bits &= ~OSPF_DBD_M; bits &= ~OSPF_DBD_I; nbr->dd_more = 0; break; default: fatalx("send_db_description: unknown neighbor state"); } bzero(&dd_hdr, sizeof(dd_hdr)); switch (nbr->iface->type) { case IF_TYPE_POINTOPOINT: inet_pton(AF_INET6, AllSPFRouters, &dst); dd_hdr.iface_mtu = htons(nbr->iface->mtu); break; case IF_TYPE_BROADCAST: dst = nbr->addr; dd_hdr.iface_mtu = htons(nbr->iface->mtu); break; case IF_TYPE_NBMA: case IF_TYPE_POINTOMULTIPOINT: /* XXX not supported */ break; case IF_TYPE_VIRTUALLINK: dst = nbr->iface->dst; dd_hdr.iface_mtu = 0; break; default: fatalx("send_db_description: unknown interface type"); } dd_hdr.opts = htonl(area_ospf_options(area_find(oeconf, nbr->iface->area_id))); dd_hdr.bits = bits; dd_hdr.dd_seq_num = htonl(nbr->dd_seq_num); memcpy(ibuf_seek(buf, sizeof(struct ospf_hdr), sizeof(dd_hdr)), &dd_hdr, sizeof(dd_hdr)); /* calculate checksum */ if (upd_ospf_hdr(buf, nbr->iface)) goto fail; /* transmit packet */ ret = send_packet(nbr->iface, buf->buf, buf->wpos, &dst); done: ibuf_free(buf); return (ret); fail: log_warn("send_db_description"); ibuf_free(buf); return (-1); }