1 /* For terms of usage/redistribution/modification see the LICENSE file */
2 /* For authors and contributors see the AUTHORS file */
6 landesc.c - LAN host description management module
7 Currently includes support for Ethernet, PLIP,
12 #include "iptraf-ng-compat.h"
14 #include "tui/input.h"
15 #include "tui/listbox.h"
16 #include "tui/msgboxes.h"
17 #include "tui/menurt.h"
24 static int check_mac_addr(const char *mac
)
26 if (strlen(mac
) != 17)
29 char a
[3], b
[3], c
[3], d
[3], e
[3], f
[3];
31 int success
= sscanf(mac
, "%02s:%02s:%02s:%02s:%02s:%02s",
39 sprintf(mac_hex
, "%s%s%s%s%s%s", a
, b
, c
, d
, e
, f
);
41 for (int ii
= 0; ii
< 12; ++ii
)
42 if (!isxdigit(mac_hex
[ii
]))
48 /* parse and insert unique eth description.
49 * caller is responsible for freeing whole list
51 static void parse_eth_desc(FILE * fp
, struct eth_desc
*hd
)
57 while ((read
= getline(&l
, &len
, fp
)) != -1) {
58 if (l
[0] == '\n' || l
[0] == '#')
63 if (strchr(line
, '\n'))
64 strchr(line
, '\n')[0] = '\0';
66 strncpy(mac
, line
, 17);
68 if (!check_mac_addr(mac
)) {
69 tui_error(ANYKEY_MSG
, "Not a mac '%s' address, skipped",
74 /* skip mac address */
77 /* mandatory space between mac and ip */
78 if (!isspace(*line
)) {
80 "Missing mandatory space between"
81 "mac and host/ip address, skipped");
85 line
= skip_whitespace(line
);
88 tui_error(ANYKEY_MSG
, "Missing description, skipped");
92 struct eth_desc
*new = xmalloc(sizeof(struct eth_desc
));
94 memcpy(new->hd_mac
, mac
, sizeof(mac
));
95 new->hd_desc
= xstrdup(line
);
97 struct eth_desc
*desc
= NULL
;
99 list_for_each_entry(desc
, &hd
->hd_list
, hd_list
)
100 if ((strcmp(desc
->hd_mac
, mac
) == 0)
101 || (strcmp(desc
->hd_desc
, line
) == 0))
104 list_add_tail(&new->hd_list
, &hd
->hd_list
);
111 struct eth_desc
*load_eth_desc(unsigned link_type
)
113 /* why is usefull to have it two files with same content?
114 * There is two options how to merge it.
115 * 1) separate by comments
117 * # ethernet host description
120 * # fddi host description
122 * 2) put it into groups
129 char *filename
= NULL
;
132 if (link_type
== ARPHRD_ETHER
)
134 else if (link_type
== ARPHRD_FDDI
)
137 struct eth_desc
*hd
= xmallocz(sizeof(struct eth_desc
));
139 INIT_LIST_HEAD(&hd
->hd_list
);
141 fp
= fopen(filename
, "r");
143 parse_eth_desc(fp
, hd
);
147 /* merge with /etc/ethers */
148 fp
= fopen("/etc/ethers", "r");
150 parse_eth_desc(fp
, hd
);
157 static void save_eth_desc(struct eth_desc
*hd
, unsigned linktype
)
161 if (linktype
== ARPHRD_ETHER
)
162 fd
= fopen(ETHFILE
, "w");
163 else if (linktype
== ARPHRD_FDDI
)
164 fd
= fopen(FDDIFILE
, "w");
167 tui_error(ANYKEY_MSG
, "Unable to save host description file");
171 fprintf(fd
, "# see man ethers for syntax\n\n");
172 struct eth_desc
*desc
= NULL
;
174 list_for_each_entry(desc
, &hd
->hd_list
, hd_list
)
175 fprintf(fd
, "%s %s\n", desc
->hd_mac
, desc
->hd_desc
);
181 void free_eth_desc(struct eth_desc
*hd
)
183 struct eth_desc
*entry
= NULL
;
184 struct list_head
*l
, *n
;
186 list_for_each_safe(l
, n
, &hd
->hd_list
) {
187 entry
= list_entry(l
, struct eth_desc
, hd_list
);
189 free(entry
->hd_desc
);
195 static struct eth_desc
*select_eth_desc(const struct eth_desc
*hd
)
198 struct scroll_list slist
;
201 if (list_empty(&hd
->hd_list
)) {
202 tui_error(ANYKEY_MSG
, "No descriptions");
206 tx_init_listbox(&slist
, COLS
, 20, 0, (LINES
- 20) / 2, STDATTR
, BOXATTR
,
207 BARSTDATTR
, HIGHATTR
);
209 tx_set_listbox_title(&slist
, "Address", 1);
210 tx_set_listbox_title(&slist
, "Description", 19);
212 struct eth_desc
*entry
= NULL
;
214 list_for_each_entry(entry
, &hd
->hd_list
, hd_list
) {
215 snprintf(descline
, 80, "%-18s%s", entry
->hd_mac
,
217 tx_add_list_entry(&slist
, (char *) entry
, descline
);
220 tx_show_listbox(&slist
);
224 tx_operate_listbox(&slist
, &aborted
);
227 entry
= (struct eth_desc
*) slist
.textptr
->nodeptr
;
231 tx_close_listbox(&slist
);
232 tx_destroy_list(&slist
);
240 static int dialog_eth_desc(struct FIELDLIST
*fields
, const char *initaddr
,
241 const char *initdesc
)
243 /* TODO: move to tui */
244 WINDOW
*win
= newwin(8, 70, 8, (COLS
- 70) / 2);
245 PANEL
*panel
= new_panel(win
);
247 wattrset(win
, DLGBOXATTR
);
249 tx_box(win
, ACS_VLINE
, ACS_HLINE
);
250 wmove(win
, 6, 2 * COLS
/ 80);
252 wmove(win
, 6, 20 * COLS
/ 80);
255 wattrset(win
, DLGTEXTATTR
);
256 mvwprintw(win
, 2, 2 * COLS
/ 80, "MAC Address:");
257 mvwprintw(win
, 4, 2 * COLS
/ 80, "Description:");
259 tx_initfields(fields
, 3, 52, 10, (COLS
- 52) / 2 + 6 * COLS
/ 80,
260 DLGTEXTATTR
, FIELDATTR
);
261 tx_addfield(fields
, 17, 0, 0, initaddr
);
262 tx_addfield(fields
, 50, 2, 0, initdesc
);
266 tx_fillfields(fields
, &aborted
);
274 static void add_eth_desc(struct eth_desc
*list
)
276 struct FIELDLIST fields
;
278 int aborted
= dialog_eth_desc(&fields
, "", "");
281 struct eth_desc
*new = xmalloc(sizeof(struct eth_desc
));
283 memcpy(new->hd_mac
, fields
.list
->buf
, sizeof(new->hd_mac
));
284 new->hd_desc
= xstrdup(fields
.list
->nextfield
->buf
);
286 list_add_tail(&new->hd_list
, &list
->hd_list
);
289 tx_destroyfields(&fields
);
294 static void edit_eth_desc(struct eth_desc
*list
)
296 struct eth_desc
*hd
= select_eth_desc(list
);
301 struct FIELDLIST fields
;
302 int aborted
= dialog_eth_desc(&fields
, hd
->hd_mac
, hd
->hd_desc
);
306 memcpy(hd
->hd_mac
, fields
.list
->buf
, sizeof(hd
->hd_mac
));
307 hd
->hd_desc
= xstrdup(fields
.list
->nextfield
->buf
);
310 tx_destroyfields(&fields
);
313 static void del_eth_desc(struct eth_desc
*list
)
315 struct eth_desc
*hd
= select_eth_desc(list
);
319 list_del(&hd
->hd_list
);
324 void manage_eth_desc(unsigned linktype
)
330 tx_initmenu(&menu
, 7, 31, (LINES
- 6) / 2, (COLS
- 31) / 2, BOXATTR
,
331 STDATTR
, HIGHATTR
, BARSTDATTR
, BARHIGHATTR
, DESCATTR
);
332 tx_additem(&menu
, " ^A^dd description...",
333 "Adds a description for a MAC address");
334 tx_additem(&menu
, " ^E^dit description...",
335 "Modifies an existing MAC address description");
336 tx_additem(&menu
, " ^D^elete description...",
337 "Deletes an existing MAC address description");
338 tx_additem(&menu
, NULL
, NULL
);
339 tx_additem(&menu
, " E^x^it menu", "Returns to the main menu");
341 struct eth_desc
*list
=
342 load_eth_desc(linktype
/*, WITHOUTETCETHERS */ );
346 tx_operatemenu(&menu
, &row
, &aborted
);
361 tx_destroymenu(&menu
);
364 save_eth_desc(list
, linktype
);