1 /*
2 * $Id$
3 *
4 * Copyright (c) 2008, 2009
5 * Sten Spans <sten@blinkenlights.nl>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #include "config.h"
21 #include <check.h>
22 #include <paths.h>
23 #include <pcap.h>
24
25 #include "common.h"
26 #include "util.h"
27 #include "proto/protos.h"
28 #include "main.h"
29 #include "check_wrap.h"
30
31 uint32_t options = OPT_DAEMON | OPT_CHECK;
32
START_TEST(test_my)33 START_TEST(test_my) {
34 char *ptr = NULL;
35 int s = -1, spair[2];
36 const char *errstr = NULL;
37 char buf[1024], *bp = NULL;
38 ssize_t len = 0;
39 size_t left;
40
41 mark_point();
42 loglevel = INFO;
43 errstr = "empty";
44 my_log(CRIT, errstr);
45 my_log(DEBUG, "0123456789");
46 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
47 "incorrect message logged: %s", check_wrap_errstr);
48
49 mark_point();
50 loglevel = DEBUG;
51 errstr = "0123456789";
52 my_log(INFO, errstr);
53 fail_unless (strcmp(check_wrap_errstr, errstr) == 0, "message not logged");
54
55 mark_point();
56 s = dup(STDERR_FILENO);
57 close(STDERR_FILENO);
58 my_socketpair(spair);
59 my_nonblock(spair[1]);
60 options &= ~OPT_DAEMON;
61 errstr = "test_my: debug\n";
62 memset(buf, 0, 1024);
63 my_log(INFO, "debug");
64 fflush(stderr);
65
66 bp = buf;
67 left = 1024;
68 while (left > 0) {
69 len = read(spair[1], bp, left);
70 if (len <= 0)
71 break;
72 left -= len;
73 bp += len;
74 }
75 fail_unless(strcmp(buf, errstr) == 0, "invalid output: %s", buf);
76 options |= OPT_DAEMON;
77 close(spair[0]);
78 fail_if(dup(s) != STDERR_FILENO, "dup should re-create stderr");
79 close(s);
80 close(spair[1]);
81
82 mark_point();
83 WRAP_FATAL_START();
84 my_fatal("error");
85 WRAP_FATAL_END();
86 fail_unless (strcmp(check_wrap_errstr, "error") == 0,
87 "error not logged");
88
89 mark_point();
90 ptr = my_malloc(100);
91 fail_unless (ptr != NULL, "a valid pointer should be returned");
92 free(ptr);
93 ptr = NULL;
94
95 mark_point();
96 ptr = my_calloc(10, 10);
97 fail_unless (ptr != NULL, "a valid pointer should be returned");
98 free(ptr);
99 ptr = NULL;
100
101 check_wrap_fail |= FAIL_CALLOC;
102 WRAP_FATAL_START();
103 ptr = my_calloc(10, 10);
104 WRAP_FATAL_END();
105 check_wrap_fail &= ~FAIL_CALLOC;
106 fail_unless (strcmp(check_wrap_errstr, "calloc failed") == 0,
107 "error not logged");
108
109 mark_point();
110 ptr = my_strdup("foo");
111 fail_unless (ptr != NULL, "a valid pointer should be returned");
112 free(ptr);
113 ptr = NULL;
114
115 check_wrap_fail |= FAIL_STRDUP;
116 WRAP_FATAL_START();
117 ptr = my_strdup("bar");
118 WRAP_FATAL_END();
119 check_wrap_fail &= ~FAIL_STRDUP;
120 fail_unless (strcmp(check_wrap_errstr, "strdup failed") == 0,
121 "error not logged");
122
123 // skip the socket tests if there is no networking
124 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
125 return;
126 close(s);
127
128 mark_point();
129 s = my_socket(AF_INET, SOCK_DGRAM, 0);
130 fail_unless (s != -1, "a valid socket should be returned");
131 close(s);
132 s = 0;
133
134 errstr = "opening socket failed";
135 WRAP_FATAL_START();
136 s = my_socket(AF_MAX, 0, 0);
137 WRAP_FATAL_END();
138 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
139 "incorrect message logged: %s", check_wrap_errstr);
140 }
141 END_TEST
142
START_TEST(test_my_mreq)143 START_TEST(test_my_mreq) {
144 struct parent_req mreq = {};
145 int spair[2];
146 extern int msock;
147 size_t ret;
148 const char *errstr = NULL;
149
150 loglevel = INFO;
151 my_socketpair(spair);
152
153 mark_point();
154 msock = -1;
155 errstr = "only -1 bytes written";
156 WRAP_FATAL_START();
157 my_mreq(&mreq);
158 WRAP_FATAL_END();
159 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
160 "incorrect message logged: %s", check_wrap_errstr);
161
162 mark_point();
163 msock = spair[1];
164 errstr = "check";
165 my_log(CRIT, errstr);
166 mreq.len = ETHER_MIN_LEN;
167 WRAP_WRITE(spair[0], &mreq, PARENT_REQ_LEN(mreq.len));
168 ret = my_mreq(&mreq);
169 fail_unless (ret == ETHER_MIN_LEN,
170 "incorrect size %lu returned from my_mreq", ret);
171
172 mark_point();
173 errstr = "invalid reply received from parent";
174 WRAP_WRITE(spair[0], &mreq, ETHER_MIN_LEN);
175 WRAP_FATAL_START();
176 my_mreq(&mreq);
177 WRAP_FATAL_END();
178 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
179 "incorrect message logged: %s", check_wrap_errstr);
180
181 close(spair[0]);
182 close(spair[1]);
183 }
184 END_TEST
185
START_TEST(test_netif)186 START_TEST(test_netif) {
187 struct nhead nqueue;
188 struct nhead *netifs = &nqueue;
189 struct netif tnetifs[6];
190 struct netif *netif = NULL, *subif = NULL;
191 struct mhead mqueue;
192 struct parent_msg *msg = NULL, *nmsg = NULL;
193 struct parent_req *mreq = NULL;
194 char *descr = NULL;
195 int spair[2];
196 ssize_t len;
197 extern int msock;
198
199 TAILQ_INIT(&nqueue);
200 TAILQ_INIT(&mqueue);
201 my_socketpair(spair);
202
203 tnetifs[0].index = 0;
204 tnetifs[0].argv = 0;
205 tnetifs[0].child = 0;
206 tnetifs[0].type = NETIF_BONDING;
207 tnetifs[0].subif = &tnetifs[1];
208 strlcpy(tnetifs[0].name, "bond0", IFNAMSIZ);
209 strlcpy(tnetifs[0].description, "bond0", IFDESCRSIZE);
210
211 tnetifs[1].index = 1;
212 tnetifs[1].argv = 1;
213 tnetifs[1].child = 1;
214 tnetifs[1].type = NETIF_REGULAR;
215 tnetifs[1].subif = &tnetifs[2];
216 strlcpy(tnetifs[1].name, "eth0", IFNAMSIZ);
217 strlcpy(tnetifs[1].description, "eth0", IFDESCRSIZE);
218
219 tnetifs[2].index = 2;
220 tnetifs[2].argv = 0;
221 tnetifs[2].child = 1;
222 tnetifs[2].type = NETIF_REGULAR;
223 tnetifs[2].subif = NULL,
224 strlcpy(tnetifs[2].name, "eth2", IFNAMSIZ);
225 strlcpy(tnetifs[2].description, "eth2", IFDESCRSIZE);
226
227 tnetifs[3].index = 4;
228 tnetifs[3].argv = 0;
229 tnetifs[3].child = 0;
230 tnetifs[3].type = NETIF_BRIDGE;
231 tnetifs[3].subif = NULL,
232 strlcpy(tnetifs[3].name, "bridge0", IFNAMSIZ);
233
234 tnetifs[4].index = 5;
235 tnetifs[4].argv = 1;
236 tnetifs[4].child = 0;
237 tnetifs[4].type = NETIF_BONDING;
238 tnetifs[4].subif = NULL,
239 strlcpy(tnetifs[4].name, "lagg0", IFNAMSIZ);
240 strlcpy(tnetifs[4].description, "lagg0", IFDESCRSIZE);
241
242 tnetifs[5].index = 3;
243 tnetifs[5].argv = 1;
244 tnetifs[5].child = 0;
245 tnetifs[5].type = NETIF_REGULAR;
246 tnetifs[5].subif = NULL,
247 strlcpy(tnetifs[5].name, "eth1", IFNAMSIZ);
248 strlcpy(tnetifs[5].description, "eth1", IFDESCRSIZE);
249
250 TAILQ_INSERT_TAIL(netifs, &tnetifs[0], entries);
251 TAILQ_INSERT_TAIL(netifs, &tnetifs[1], entries);
252 TAILQ_INSERT_TAIL(netifs, &tnetifs[2], entries);
253 TAILQ_INSERT_TAIL(netifs, &tnetifs[3], entries);
254 TAILQ_INSERT_TAIL(netifs, &tnetifs[4], entries);
255 TAILQ_INSERT_TAIL(netifs, &tnetifs[5], entries);
256
257 // netif_iter checks
258 mark_point();
259 netif = NULL;
260 fail_unless (netif_iter(netif, NULL) == NULL,
261 "NULL should be returned on invalid netifs");
262
263 netif = NULL;
264 netif = netif_iter(netif, netifs);
265 fail_unless (netif == &tnetifs[0], "the first netif should be returned");
266 netif = netif_iter(netif, netifs);
267 fail_unless (netif == &tnetifs[5], "the sixth netif should be returned");
268 netif = netif_iter(netif, netifs);
269 fail_unless (netif == NULL, "NULL should be returned");
270
271 netif = NULL;
272 options |= OPT_ARGV;
273 netif = netif_iter(netif, netifs);
274 fail_unless (netif == &tnetifs[1], "the second netif should be returned");
275 netif = netif_iter(netif, netifs);
276 fail_unless (netif == &tnetifs[5], "the sixth netif should be returned");
277 netif = netif_iter(netif, netifs);
278 fail_unless (netif == NULL, "NULL should be returned");
279
280
281 // subif_iter checks
282 mark_point();
283 netif = &tnetifs[0];
284 subif = NULL;
285 subif = subif_iter(subif, subif);
286 fail_unless (subif == NULL, "NULL should be returned");
287 subif = subif_iter(subif, netif);
288 fail_unless (subif == &tnetifs[1], "the second netif should be returned");
289 subif = subif_iter(subif, netif);
290 fail_unless (subif == &tnetifs[2], "the third netif should be returned");
291 subif = subif_iter(subif, netif);
292 fail_unless (subif == NULL, "NULL should be returned");
293
294 netif = &tnetifs[3];
295 subif = NULL;
296 subif = subif_iter(subif, netif);
297 fail_unless (subif == NULL, "NULL should be returned");
298
299 netif = &tnetifs[4];
300 subif = NULL;
301 subif = subif_iter(subif, netif);
302 fail_unless (subif == NULL, "NULL should be returned");
303
304 netif = &tnetifs[5];
305 subif = NULL;
306 subif = subif_iter(subif, netif);
307 fail_unless (subif == &tnetifs[5], "the sixth netif should be returned");
308 subif = subif_iter(subif, netif);
309 fail_unless (subif == NULL, "NULL should be returned");
310
311
312 // netif_byindex checks
313 mark_point();
314 fail_unless (netif_byindex(netifs, 0) == &tnetifs[0],
315 "incorrect netif struct returned");
316 fail_unless (netif_byindex(netifs, 1) == &tnetifs[1],
317 "incorrect netif struct returned");
318 fail_unless (netif_byindex(netifs, 2) == &tnetifs[2],
319 "incorrect netif struct returned");
320 fail_unless (netif_byindex(netifs, 3) == &tnetifs[5],
321 "incorrect netif struct returned");
322 fail_unless (netif_byindex(netifs, 6) == NULL,
323 "NULL should be returned on not found netif");
324
325
326 // netif_byname checks
327 mark_point();
328 fail_unless (netif_byname(netifs, "bond0") == &tnetifs[0],
329 "incorrect netif struct returned");
330 fail_unless (netif_byname(netifs, "eth0") == &tnetifs[1],
331 "incorrect netif struct returned");
332 fail_unless (netif_byname(netifs, "eth2") == &tnetifs[2],
333 "incorrect netif struct returned");
334 fail_unless (netif_byname(netifs, "eth1") == &tnetifs[5],
335 "incorrect netif struct returned");
336 fail_unless (netif_byname(netifs, "eth3") == NULL,
337 "NULL should be returned on not found netif");
338
339 // XXX: netif_byaddr checks
340
341 msg = my_malloc(PARENT_MSG_SIZ);
342 netif = netif_byname(netifs, "eth0");
343 msg->index = netif->index;
344 msg->proto = PROTO_LLDP;
345 memcpy(msg->msg + ETHER_ADDR_LEN, "\x02\x00\x01", 3);
346 msg->peer[PEER_HOSTNAME] = my_strdup("foo");
347 msg->peer[PEER_PORTNAME] = my_strdup("FastEthernet6/20");
348 TAILQ_INSERT_TAIL(&mqueue, msg, entries);
349
350 msg = my_malloc(PARENT_MSG_SIZ);
351 netif = netif_byname(netifs, "eth2");
352 msg->index = netif->index;
353 msg->proto = PROTO_CDP;
354 memcpy(msg->msg + ETHER_ADDR_LEN, "\x02\x00\x02", 3);
355 msg->peer[PEER_HOSTNAME] = my_strdup("bar");
356 TAILQ_INSERT_TAIL(&mqueue, msg, entries);
357
358 msg = my_malloc(PARENT_MSG_SIZ);
359 netif = netif_byname(netifs, "eth1");
360 msg->index = netif->index;
361 msg->proto = PROTO_LLDP;
362 memcpy(msg->msg + ETHER_ADDR_LEN, "\x02\x00\x03", 3);
363 msg->peer[PEER_HOSTNAME] = my_strdup("baz");
364 msg->peer[PEER_PORTNAME] = my_strdup("Ethernet4");
365 TAILQ_INSERT_TAIL(&mqueue, msg, entries);
366
367 msg = my_malloc(PARENT_MSG_SIZ);
368 netif = netif_byname(netifs, "eth1");
369 msg->index = netif->index;
370 msg->proto = PROTO_LLDP;
371 memcpy(msg->msg + ETHER_ADDR_LEN, "\x02\x00\x04", 3);
372 msg->peer[PEER_HOSTNAME] = my_strdup("quux");
373 msg->peer[PEER_PORTNAME] = my_strdup("Ethernet5");
374 TAILQ_INSERT_TAIL(&mqueue, msg, entries);
375
376 msg = my_malloc(PARENT_MSG_SIZ);
377 netif = netif_byname(netifs, "eth1");
378 msg->index = netif->index;
379 msg->proto = PROTO_FDP;
380 memcpy(msg->msg + ETHER_ADDR_LEN, "\x02\x00\x04", 3);
381 msg->peer[PEER_HOSTNAME] = my_strdup("quux");
382 msg->peer[PEER_PORTNAME] = my_strdup("Ethernet5");
383 TAILQ_INSERT_TAIL(&mqueue, msg, entries);
384
385 msg = my_malloc(PARENT_MSG_SIZ);
386 netif = netif_byname(netifs, "lagg0");
387 msg->index = netif->index;
388 msg->proto = PROTO_LLDP;
389 memcpy(msg->msg + ETHER_ADDR_LEN, "\x02\x00\x05", 3);
390 TAILQ_INSERT_TAIL(&mqueue, msg, entries);
391
392 // netif_protos checks
393 mark_point();
394 netif = netif_byname(netifs, "bond0");
395 netif_protos(netif, &mqueue);
396 fail_unless (netif->protos == ((1 << PROTO_LLDP)|(1 << PROTO_CDP)),
397 "incorrect protos calculation");
398
399 netif = netif_byname(netifs, "eth1");
400 netif_protos(netif, &mqueue);
401 fail_unless (netif->protos == ((1 << PROTO_LLDP)|(1 << PROTO_FDP)),
402 "incorrect protos calculation");
403
404 netif = netif_byname(netifs, "lagg0");
405 netif_protos(netif, &mqueue);
406 fail_unless (netif->protos == 0, "incorrect protos calculation");
407
408 // netif_descr checks
409 mark_point();
410 msock = spair[1];
411 mreq = my_malloc(PARENT_REQ_MAX);
412 mreq->len = IFDESCRSIZE;
413
414 netif = netif_byname(netifs, "bond0");
415 descr = "";
416 WRAP_WRITE(spair[0], mreq, PARENT_REQ_LEN(mreq->len));
417 netif_descr(netif, &mqueue);
418 WRAP_REQ_READ(spair[0], mreq, len);
419 fail_unless (mreq->op == PARENT_DESCR,
420 "incorrect command: %d", mreq->op);
421 fail_unless (mreq->index == netif->index,
422 "incorrect interface index: %d", mreq->index);
423 fail_unless (mreq->len == strlen(descr) + 1,
424 "incorrect message length: %d", mreq->len);
425 fail_unless (strncmp(mreq->buf, descr, IFDESCRSIZE) == 0,
426 "incorrect interface description: %s", mreq->buf);
427
428 netif = netif_byname(netifs, "eth0");
429 descr = "connected to foo (Fa6/20)";
430 WRAP_WRITE(spair[0], mreq, PARENT_REQ_LEN(mreq->len));
431 netif_descr(netif, &mqueue);
432 WRAP_REQ_READ(spair[0], mreq, len);
433 fail_unless (mreq->op == PARENT_DESCR,
434 "incorrect command: %d", mreq->op);
435 fail_unless (mreq->index == netif->index,
436 "incorrect interface index: %d", mreq->index);
437 fail_unless (mreq->len == strlen(descr) + 1,
438 "incorrect message length: %d", mreq->len);
439 fail_unless (strncmp(mreq->buf, descr, IFDESCRSIZE) == 0,
440 "incorrect interface description: %s", mreq->buf);
441
442 netif = netif_byname(netifs, "eth2");
443 descr = "connected to bar";
444 WRAP_WRITE(spair[0], mreq, PARENT_REQ_LEN(mreq->len));
445 netif_descr(netif, &mqueue);
446 WRAP_REQ_READ(spair[0], mreq, len);
447 fail_unless (mreq->op == PARENT_DESCR,
448 "incorrect command: %d", mreq->op);
449 fail_unless (mreq->index == netif->index,
450 "incorrect interface index: %d", mreq->index);
451 fail_unless (mreq->len == strlen(descr) + 1,
452 "incorrect message length: %d", mreq->len);
453 fail_unless (strncmp(mreq->buf, descr, IFDESCRSIZE) == 0,
454 "incorrect interface description: %s", mreq->buf);
455
456 netif = netif_byname(netifs, "eth1");
457 descr = "connected to 2 peers";
458 WRAP_WRITE(spair[0], mreq, PARENT_REQ_LEN(mreq->len));
459 netif_descr(netif, &mqueue);
460 WRAP_REQ_READ(spair[0], mreq, len);
461 fail_unless (mreq->op == PARENT_DESCR,
462 "incorrect command: %d", mreq->op);
463 fail_unless (mreq->index == netif->index,
464 "incorrect interface index: %d", mreq->index);
465 fail_unless (mreq->len == strlen(descr) + 1,
466 "incorrect message length: %d", mreq->len);
467 fail_unless (strncmp(mreq->buf, descr, IFDESCRSIZE) == 0,
468 "incorrect interface description: %s", mreq->buf);
469
470 netif = netif_byname(netifs, "lagg0");
471 descr = "";
472 WRAP_WRITE(spair[0], mreq, PARENT_REQ_LEN(mreq->len));
473 netif_descr(netif, &mqueue);
474 WRAP_REQ_READ(spair[0], mreq, len);
475 fail_unless (mreq->op == PARENT_DESCR,
476 "incorrect command: %d", mreq->op);
477 fail_unless (mreq->index == netif->index,
478 "incorrect interface index: %d", mreq->index);
479 fail_unless (mreq->len == strlen(descr) + 1,
480 "incorrect message length: %d", mreq->len);
481 fail_unless (strncmp(mreq->buf, descr, IFDESCRSIZE) == 0,
482 "incorrect interface description: %s", mreq->buf);
483
484 free(mreq);
485 TAILQ_FOREACH_SAFE(msg, &mqueue, entries, nmsg) {
486 TAILQ_REMOVE(&mqueue, msg, entries);
487 peer_free(msg->peer);
488 free(msg);
489 }
490 TAILQ_FOREACH_SAFE(netif, &nqueue, entries, subif) {
491 TAILQ_REMOVE(&nqueue, netif, entries);
492 }
493
494 close(spair[0]);
495 close(spair[1]);
496 }
497 END_TEST
498
START_TEST(test_read_line)499 START_TEST(test_read_line) {
500 char line[128];
501 const char *data = "0123456789ABCDEF";
502 const char *null = _PATH_DEVNULL;
503 const char *file = "testfile";
504 char *prefix, *path = NULL;
505
506 if ((prefix = getenv("srcdir")) == NULL)
507 prefix = ".";
508
509 fail_if(asprintf(&path, "%s/%s", prefix, file) == -1, "asprintf failed");
510
511 fail_unless (read_line("non-existant", line, 0) == 0,
512 "0 should be returned on a missing file");
513
514 fail_unless (read_line(null, line, 10) == 0,
515 "0 should be returned on a unreadable file");
516
517 fail_unless (read_line(path, line, 0) == 0,
518 "0 should be returned on zero len request");
519
520 fail_unless (read_line(path, line, 1) == 0,
521 "0 bytes should be returned");
522
523 fail_unless (read_line(path, line, 2) == 1,
524 "1 bytes should be returned");
525
526 fail_unless (read_line(path, line, 10) == 9,
527 "9 bytes should be returned");
528
529 fail_unless (read_line(path, line, 17) == 16,
530 "16 bytes should be returned");
531
532 fail_unless (strncmp(line, data, strlen(data)) == 0,
533 "invalid line returned");
534
535 fail_unless (read_line(path, line, 18) == 16,
536 "16 bytes should be returned");
537
538 fail_unless (strncmp(line, data, strlen(data)) == 0,
539 "invalid line returned");
540
541 free(path);
542 }
543 END_TEST
544
START_TEST(test_my_cksum)545 START_TEST(test_my_cksum) {
546 const char *data = "0123456789ABCDEF";
547 uint16_t sum;
548 uint8_t cisco;
549
550 cisco = 0;
551 sum = ntohs(my_chksum(data, strlen(data), cisco));
552 fail_unless(sum == 12585,
553 "IP checksum result should be 12585 not %d", sum);
554
555 cisco = 1;
556 sum = ntohs(my_chksum(data, strlen(data), cisco));
557 fail_unless(sum == 12585,
558 "(Cisco) IP checksum result should be 12585 not %d", sum);
559
560 cisco = 0;
561 sum = ntohs(my_chksum(data, strlen(data) - 1, cisco));
562 fail_unless(sum == 12655,
563 "IP checksum result should be 12655 not %d", sum);
564
565 cisco = 1;
566 sum = ntohs(my_chksum(data, strlen(data) - 1, cisco));
567 fail_unless(sum == 30250,
568 "(Cisco) IP checksum result should be 30250 not %d", sum);
569 }
570 END_TEST
571
START_TEST(test_my_priv)572 START_TEST(test_my_priv) {
573 struct passwd *pwd = NULL;
574 struct stat sb;
575 const char *errstr = NULL;
576 char path[MAXPATHLEN + 1] = {};
577
578 loglevel = INFO;
579 errno = EPERM;
580
581 if ((pwd = getpwnam("root")) == NULL)
582 return;
583 if (stat(_PATH_DEVNULL, &sb) != 0)
584 return;
585
586 mark_point();
587 errstr = "unable to setgroups";
588 check_wrap_fail |= FAIL_SETGRP;
589 WRAP_FATAL_START();
590 my_drop_privs(pwd);
591 WRAP_FATAL_END();
592 check_wrap_fail &= ~FAIL_SETGRP;
593 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
594 "incorrect message logged: %s", check_wrap_errstr);
595
596 mark_point();
597 #ifdef HAVE_SETRESGID
598 errstr = "unable to setresgid";
599 #elif defined(HAVE_SETREGID)
600 errstr = "unable to setregid";
601 #endif
602 check_wrap_fail |= FAIL_SETRESGID;
603 check_wrap_fake |= FAKE_SETGRP;
604 WRAP_FATAL_START();
605 my_drop_privs(pwd);
606 WRAP_FATAL_END();
607 check_wrap_fail &= ~FAIL_SETRESGID;
608 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
609 "incorrect message logged: %s", check_wrap_errstr);
610
611 mark_point();
612 #ifdef HAVE_SETRESUID
613 errstr = "unable to setresuid";
614 #elif defined(HAVE_SETREUID)
615 errstr = "unable to setreuid";
616 #endif
617 check_wrap_fail |= FAIL_SETRESUID;
618 check_wrap_fake |= FAKE_SETRESGID;
619 WRAP_FATAL_START();
620 my_drop_privs(pwd);
621 WRAP_FATAL_END();
622 check_wrap_fail &= ~FAIL_SETRESUID;
623 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
624 "incorrect message logged: %s", check_wrap_errstr);
625
626 mark_point();
627 errno = 0;
628 errstr = "check";
629 my_log(CRIT, errstr);
630 check_wrap_fake |= FAKE_SETRESUID;
631 WRAP_FATAL_START();
632 my_drop_privs(pwd);
633 WRAP_FATAL_END();
634 check_wrap_fail = 0;
635 check_wrap_fake = 0;
636 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
637 "incorrect message logged: %s", check_wrap_errstr);
638
639 mark_point();
640 errstr = "chroot path does not begin at root";
641 memset(path, 'a', MAXPATHLEN);
642 WRAP_FATAL_START();
643 my_chroot(path);
644 WRAP_FATAL_END();
645 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
646 "incorrect message logged: %s", check_wrap_errstr);
647
648 mark_point();
649 errstr = "chroot path too long";
650 path[0] = '/';
651 WRAP_FATAL_START();
652 my_chroot(path);
653 WRAP_FATAL_END();
654 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
655 "incorrect message logged: %s", check_wrap_errstr);
656
657 mark_point();
658 errstr = "stat(\"/inexistant\"): ";
659 WRAP_FATAL_START();
660 my_chroot("/inexistant");
661 WRAP_FATAL_END();
662 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
663 "incorrect message logged: %s", check_wrap_errstr);
664
665 mark_point();
666 errstr = "bad ownership or modes for chroot";
667 WRAP_FATAL_START();
668 my_chroot(_PATH_DEVNULL);
669 WRAP_FATAL_END();
670 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
671 "incorrect message logged: %s", check_wrap_errstr);
672
673 mark_point();
674 if (stat(_PATH_DEV, &sb) != 0)
675 return;
676 if (sb.st_uid != 0 || (sb.st_mode & 022) != 0)
677 return;
678 if (stat(_PATH_CONSOLE, &sb) != 0)
679 return;
680 if (sb.st_uid != 0 || (sb.st_mode & 022) != 0)
681 return;
682
683 mark_point();
684 errstr = "chroot path \"" _PATH_CONSOLE "\" is not a directory";
685 WRAP_FATAL_START();
686 my_chroot(_PATH_CONSOLE);
687 WRAP_FATAL_END();
688 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
689 "incorrect message logged: %s", check_wrap_errstr);
690
691 mark_point();
692 errstr = "unable to chdir to chroot path";
693 strlcpy(path, "/", MAXPATHLEN);
694 check_wrap_fail |= FAIL_CHDIR;
695 WRAP_FATAL_START();
696 my_chroot(path);
697 WRAP_FATAL_END();
698 check_wrap_fail &= ~FAIL_CHDIR;
699 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
700 "incorrect message logged: %s", check_wrap_errstr);
701
702 mark_point();
703 errstr = "chroot(\"/\"):";
704 check_wrap_fail |= FAIL_CHROOT;
705 check_wrap_fake |= FAKE_CHDIR;
706 WRAP_FATAL_START();
707 my_chroot(path);
708 WRAP_FATAL_END();
709 check_wrap_fail &= ~FAIL_CHROOT;
710 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
711 "incorrect message logged: %s", check_wrap_errstr);
712
713 mark_point();
714 errno = 0;
715 errstr = "check";
716 my_log(CRIT, errstr);
717 check_wrap_fake |= FAKE_CHROOT;
718 WRAP_FATAL_START();
719 my_chroot(path);
720 WRAP_FATAL_END();
721 check_wrap_fail = 0;
722 check_wrap_fake = 0;
723 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
724 "incorrect message logged: %s", check_wrap_errstr);
725 }
726 END_TEST
727
START_TEST(test_portname_abbr)728 START_TEST(test_portname_abbr) {
729 char *portname = NULL;
730
731 portname = my_strdup("FastEthernet42/42");
732 portname_abbr(portname);
733 fail_unless(strcmp(portname, "Fa42/42") == 0,
734 "unexpected portname: %s", portname);
735 free(portname);
736
737 portname = my_strdup("GigabitEthernet42");
738 portname_abbr(portname);
739 fail_unless(strcmp(portname, "Gi42") == 0,
740 "unexpected portname: %s", portname);
741 free(portname);
742
743 portname = my_strdup("TenGigabitEthernet0/86");
744 portname_abbr(portname);
745 fail_unless(strcmp(portname, "Te0/86") == 0,
746 "unexpected portname: %s", portname);
747 free(portname);
748
749 portname = my_strdup("Ethernet0/86");
750 portname_abbr(portname);
751 fail_unless(strcmp(portname, "Eth0/86") == 0,
752 "unexpected portname: %s", portname);
753 free(portname);
754
755 portname = my_strdup("eth0");
756 portname_abbr(portname);
757 fail_unless(strcmp(portname, "eth0") == 0,
758 "unexpected portname: %s", portname);
759 free(portname);
760 }
761 END_TEST
762
START_TEST(test_pcap)763 START_TEST(test_pcap) {
764 int spair[2];
765 ssize_t len;
766 const char *errstr = NULL;
767 char buf[1024];
768 struct pcap_file_header pcap_fhdr = {};
769 struct parent_msg msg = {};
770
771 loglevel = INFO;
772 my_socketpair(spair);
773
774 mark_point();
775 errstr = "stdin fd not available";
776 my_log(CRIT, "check");
777 WRAP_FATAL_START();
778 my_pcap_init(-1);
779 WRAP_FATAL_END();
780 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
781 "incorrect message logged: %s", check_wrap_errstr);
782
783 mark_point();
784 my_pcap_init(spair[0]);
785 len = read(spair[1], &pcap_fhdr, sizeof(pcap_fhdr));
786 fail_unless(len == sizeof(pcap_fhdr),
787 "failed to read pcap header");
788 fail_unless(pcap_fhdr.magic == PCAP_MAGIC,
789 "invalid pcap header returned");
790 fail_unless(pcap_fhdr.snaplen == ETHER_MAX_LEN,
791 "invalid pcap header returned");
792 fail_unless(pcap_fhdr.linktype == DLT_EN10MB,
793 "invalid pcap header returned");
794
795 mark_point();
796 errstr = "check";
797 my_log(CRIT, errstr);
798 msg.len = 1;
799 my_pcap_write(&msg);
800 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
801 "incorrect message logged: %s", check_wrap_errstr);
802 len = read(spair[1], buf, 1024);
803 fail_unless(len == (PCAP_PKTHDR_SIZ + msg.len),
804 "failed to read pcap record");
805
806 mark_point();
807 msg.len = ETHER_MIN_LEN;
808 my_pcap_write(&msg);
809 fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
810 "incorrect message logged: %s", check_wrap_errstr);
811 len = read(spair[1], buf, 1024);
812 fail_unless(len == (PCAP_PKTHDR_SIZ + msg.len),
813 "failed to read pcap record");
814
815 close(spair[0]);
816 close(spair[1]);
817 }
818 END_TEST
819
util_suite(void)820 Suite * util_suite (void) {
821 Suite *s = suite_create("util.c");
822
823 // util test case
824 TCase *tc_util = tcase_create("util");
825 tcase_add_test(tc_util, test_my);
826 tcase_add_test(tc_util, test_my_mreq);
827 tcase_add_test(tc_util, test_netif);
828 tcase_add_test(tc_util, test_read_line);
829 tcase_add_test(tc_util, test_my_cksum);
830 tcase_add_test(tc_util, test_my_priv);
831 tcase_add_test(tc_util, test_portname_abbr);
832 tcase_add_test(tc_util, test_pcap);
833 suite_add_tcase(s, tc_util);
834
835 return s;
836 }
837
main(void)838 int main (void) {
839 int number_failed;
840 Suite *s = util_suite ();
841 SRunner *sr = srunner_create (s);
842 srunner_run_all (sr, CK_NORMAL);
843 number_failed = srunner_ntests_failed (sr);
844 srunner_free (sr);
845 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
846 }
847
848