diff options
author | Keith <keith@rhizomatica.org> | 2020-11-12 06:59:37 +0100 |
---|---|---|
committer | Keith <keith@rhizomatica.org> | 2021-04-13 23:28:02 +0200 |
commit | 2672a2a2a706b03fbb0b1c5e49526368987c7658 (patch) | |
tree | 171abaae05c6753b38115b3eece176e2cd9f642c | |
parent | 4aea11befca1b588270fecd0e60709d5cee826c0 (diff) |
Configure E1 pcap file per line
In order to allow configuration of pcap files per e1_line
the vty command is now (for example line 0):
e1_line 0 pcap /tmp/e1cap.pcap
in place of:
pcap /tmp/e1cap.pcap
Also ensures that a configured pcap appears in 'show running-config'
and is written to the config file on issuing 'write'
This commit deprecates e1_set_pcap_fd()
Change-Id: I316c3d6a839e84c2f52a148c6b8dd6f5933cf4bf
-rw-r--r-- | include/osmocom/abis/e1_input.h | 7 | ||||
-rw-r--r-- | src/e1_input.c | 52 | ||||
-rw-r--r-- | src/e1_input_vty.c | 65 |
3 files changed, 105 insertions, 19 deletions
diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h index 9b99f12..9c3fe56 100644 --- a/include/osmocom/abis/e1_input.h +++ b/include/osmocom/abis/e1_input.h @@ -223,6 +223,10 @@ struct e1inp_line { void *driver_data; struct osmo_use_count use_count; + + /* file name and file descriptor of pcap for this line */ + char *pcap_file; + int pcap_fd; }; #define e1inp_line_ipa_oml_ts(line) (&line->ts[0]) #define e1inp_line_ipa_rsl_ts(line, trx_id) (&line->ts[1 + (trx_id)]) @@ -317,8 +321,11 @@ void e1inp_dlsap_up(struct osmo_dlsap_prim *odp, uint8_t tei, uint8_t sapi, void *rx_cbdata); /* Write LAPD frames to the fd. */ +OSMO_DEPRECATED("Use e1_set_pcap_fd2() instead") int e1_set_pcap_fd(int fd); +int e1_set_pcap_fd2(struct e1inp_line *line, int fd); + /* called by TRAU muxer to obtain the destination mux entity */ struct subch_mux *e1inp_get_mux(uint8_t e1_nr, uint8_t ts_nr); diff --git a/src/e1_input.c b/src/e1_input.c index 04c464a..93ab446 100644 --- a/src/e1_input.c +++ b/src/e1_input.c @@ -139,6 +139,40 @@ osmo_static_assert(offsetof(struct fake_linux_lapd_header, addr) == 6, addr osmo_static_assert(offsetof(struct fake_linux_lapd_header, protocol) == 14, proto_offset); osmo_static_assert(sizeof(struct fake_linux_lapd_header) == 16, lapd_header_size); +int e1_set_pcap_fd2(struct e1inp_line *line, int fd) +{ + static const struct pcap_hdr header = { + .magic_number = 0xa1b2c3d4, + .version_major = 2, + .version_minor = 4, + .thiszone = 0, + .sigfigs = 0, + .snaplen = 65535, + .network = DLT_LINUX_LAPD, + }; + int i; + + /* write header */ + if (fd >= 0) { + int rc = write(fd, &header, sizeof(header)); + if (rc < 0) + return rc; + } + + /* Set the PCAP file descriptor for all timeslots that have + * software LAPD instances, to ensure the osmo_lapd_pcap code is + * used to write PCAP files (if requested) */ + for (i = 0; i < ARRAY_SIZE(line->ts); i++) { + struct e1inp_ts *e1i_ts = &line->ts[i]; + if (e1i_ts->lapd) + e1i_ts->lapd->pcap_fd = fd; + } + /* close previous and update */ + if (line->pcap_fd >= 0) + close(line->pcap_fd); + line->pcap_fd = fd; + return 0; +} static int pcap_fd = -1; @@ -185,7 +219,7 @@ int e1_set_pcap_fd(int fd) /* This currently only works for the D-Channel */ static void write_pcap_packet(int direction, int sapi, int tei, - struct msgb *msg) { + struct msgb *msg, int pcap_fd) { if (pcap_fd < 0) return; @@ -286,7 +320,7 @@ int abis_sendmsg(struct msgb *msg) * the _actual_ LAPD packet */ if (!e1i_ts->lapd) { write_pcap_packet(PCAP_OUTPUT, sign_link->sapi, - sign_link->tei, msg); + sign_link->tei, msg, e1i_ts->line->pcap_fd); } return 0; @@ -460,6 +494,7 @@ e1inp_line_create(uint8_t e1_nr, const char *driver_name) line->driver = driver; line->num = e1_nr; + line->pcap_fd = -1; line->rate_ctr = rate_ctr_group_alloc(line, &e1inp_ctr_g_d, line->num); if (!line->rate_ctr) { @@ -664,7 +699,7 @@ int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg, * the libosmocore LAPD implementation, it will take * care of writing the _actual_ LAPD packet */ if (!ts->lapd) - write_pcap_packet(PCAP_INPUT, sapi, tei, msg); + write_pcap_packet(PCAP_INPUT, sapi, tei, msg, ts->line->pcap_fd); /* consult the list of signalling links */ link = e1inp_lookup_sign_link(ts, tei, sapi); if (!link) { @@ -901,7 +936,7 @@ int e1inp_line_update(struct e1inp_line *line) for (i = 0; i < ARRAY_SIZE(line->ts); i++) { struct e1inp_ts *e1i_ts = &line->ts[i]; if (e1i_ts->lapd) - e1i_ts->lapd->pcap_fd = pcap_fd; + e1i_ts->lapd->pcap_fd = line->pcap_fd; } /* Send a signal to anyone who is interested in new lines being @@ -916,13 +951,16 @@ int e1inp_line_update(struct e1inp_line *line) static int e1i_sig_cb(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data) { + struct e1inp_line *line; + if (subsys != SS_L_GLOBAL || signal != S_L_GLOBAL_SHUTDOWN) return 0; - if (pcap_fd) { - close(pcap_fd); - pcap_fd = -1; + llist_for_each_entry(line, &e1inp_line_list, list) { + if (line->pcap_fd >=0) + close(line->pcap_fd); + line->pcap_fd = -1; } return 0; diff --git a/src/e1_input_vty.c b/src/e1_input_vty.c index d915c19..64f5f63 100644 --- a/src/e1_input_vty.c +++ b/src/e1_input_vty.c @@ -245,33 +245,67 @@ DEFUN_ATTR(cfg_e1line_name, cfg_e1_line_name_cmd, return CMD_SUCCESS; } -DEFUN_ATTR(cfg_e1_pcap, cfg_e1_pcap_cmd, - "pcap .FILE", - "Setup a pcap recording of all E1 traffic\n" +DEFUN_ATTR(cfg_e1line_pcap, cfg_e1line_pcap_cmd, + "e1_line <0-255> pcap .FILE", + E1_LINE_HELP "Setup a pcap recording of E1 traffic for line\n" "Filename to save the packets to\n", CMD_ATTR_IMMEDIATE) { + struct e1inp_line *line; int fd; + int rc; + int e1_nr = atoi(argv[0]); + + line = e1inp_line_find(e1_nr); + if (!line) { + vty_out(vty, "%% Line %d doesn't exist%s", e1_nr, VTY_NEWLINE); + return CMD_WARNING; + } - fd = open(argv[0], O_WRONLY | O_CREAT | O_TRUNC, 0660); + fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0660); if (fd < 0) { - vty_out(vty, "Failed to setup E1 pcap recording to %s.%s", argv[0], VTY_NEWLINE); + vty_out(vty, "Failed to setup E1 pcap recording to %s%s", argv[1], VTY_NEWLINE); return CMD_WARNING; } - e1_set_pcap_fd(fd); + rc = e1_set_pcap_fd2(line, fd); + if (rc < 0) { + vty_out(vty, "Failed to write to E1 pcap file %s%s", argv[1], VTY_NEWLINE); + close(fd); + return CMD_WARNING; + } + osmo_talloc_replace_string(line, &line->pcap_file, argv[1]); return CMD_SUCCESS; } -DEFUN_ATTR(cfg_e1_no_pcap, cfg_e1_no_pcap_cmd, - "no pcap", - NO_STR "Disable pcap recording of all E1 traffic\n", +DEFUN_ATTR(cfg_e1line_no_pcap, cfg_e1line_no_pcap_cmd, + "no e1_line <0-255> pcap", + NO_STR E1_LINE_HELP "Disable pcap recording of E1 traffic for line\n", CMD_ATTR_IMMEDIATE) { - e1_set_pcap_fd(-1); + struct e1inp_line *line; + int e1_nr = atoi(argv[0]); + line = e1inp_line_find(e1_nr); + + e1_set_pcap_fd2(line, -1); + if (line->pcap_file) { + talloc_free(line->pcap_file); + line->pcap_file = NULL; + } return CMD_SUCCESS; } +DEFUN_DEPRECATED(cfg_e1_pcap_deprec, cfg_e1_pcap_deprec_cmd, + "pcap .FILE", "Legacy") +{ + vty_out(vty, "%% 'pcap' is deprecated and has no effect: use e1_line <0-255> pcap%s", + VTY_NEWLINE); + return CMD_WARNING; +} + +ALIAS_DEPRECATED(cfg_e1_pcap_deprec, cfg_e1_pcap_deprec_no_cmd, + "no pcap", NO_STR); + DEFUN_ATTR(cfg_e1inp, cfg_e1inp_cmd, "e1_input", "Configure E1/T1/J1 TDM input\n", CMD_ATTR_IMMEDIATE) @@ -329,6 +363,9 @@ static int e1inp_config_write(struct vty *vty) vty_out(vty, " e1_line %u ipa-keepalive %d %d%s", line->num, line->ipa_kap->interval, line->ipa_kap->wait_for_resp, VTY_NEWLINE); + if (line->pcap_file) + vty_out(vty, " e1_line %u pcap %s%s", line->num, + line->pcap_file, VTY_NEWLINE); } const char *ipa_bind = e1inp_ipa_get_bind_addr(); @@ -365,6 +402,8 @@ static void e1line_dump_vty(struct vty *vty, struct e1inp_line *line, vty_out(vty, "E1 Line Number %u, Name %s, Driver %s%s", line->num, line->name ? line->name : "", line->driver->name, VTY_NEWLINE); + if (line->pcap_file) + vty_out(vty, "PCAP %s%s", line->pcap_file, VTY_NEWLINE); if (line->driver->vty_show) line->driver->vty_show(vty, line); if (stats) @@ -477,8 +516,10 @@ int e1inp_vty_init(void) install_lib_element(CONFIG_NODE, &cfg_e1inp_cmd); install_node(&e1inp_node, e1inp_config_write); - install_lib_element(L_E1INP_NODE, &cfg_e1_pcap_cmd); - install_lib_element(L_E1INP_NODE, &cfg_e1_no_pcap_cmd); + install_lib_element(L_E1INP_NODE, &cfg_e1line_pcap_cmd); + install_lib_element(L_E1INP_NODE, &cfg_e1line_no_pcap_cmd); + install_lib_element(L_E1INP_NODE, &cfg_e1_pcap_deprec_cmd); + install_lib_element(L_E1INP_NODE, &cfg_e1_pcap_deprec_no_cmd); install_lib_element(L_E1INP_NODE, &cfg_e1_line_driver_cmd); install_lib_element(L_E1INP_NODE, &cfg_e1_line_port_cmd); |