Annotation of embedaddon/arping/src/arping_test.c, revision 1.1.1.1

1.1       misho       1: /* arping/src/arping_test.c
                      2:  *
                      3:  *  Copyright (C) 2015-2019 Thomas Habets <thomas@habets.se>
                      4:  *
                      5:  *  This program is free software; you can redistribute it and/or modify
                      6:  *  it under the terms of the GNU General Public License as published by
                      7:  *  the Free Software Foundation; either version 2 of the License, or
                      8:  *  (at your option) any later version.
                      9:  *
                     10:  *  This program is distributed in the hope that it will be useful,
                     11:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
                     12:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     13:  *  GNU General Public License for more details.
                     14:  *
                     15:  *  You should have received a copy of the GNU General Public License along
                     16:  *  with this program; if not, write to the Free Software Foundation, Inc.,
                     17:  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
                     18:  */
                     19: #include"config.h"
                     20: #define _GNU_SOURCE
                     21: #include<assert.h>
                     22: #include<errno.h>
                     23: #include<fcntl.h>
                     24: #include<inttypes.h>
                     25: #include<pthread.h>
                     26: #include<stdio.h>
                     27: #include<stdlib.h>
                     28: 
                     29: #include<check.h>
                     30: #include<libnet.h>
                     31: #include<pcap.h>
                     32: 
                     33: #include"arping.h"
                     34: 
                     35: #ifndef ETH_ALEN
                     36: #define ETH_ALEN 6
                     37: #endif
                     38: 
                     39: extern libnet_t* libnet;
                     40: extern int mock_libnet_lo_ok;
                     41: extern int mock_libnet_null_ok;
                     42: 
                     43: struct registered_test {
                     44:         void* fn;
                     45:         const char* name;
                     46: };
                     47: 
                     48: static int numtests = 0;
                     49: static struct registered_test test_registry[1024];
                     50: 
                     51: static int num_exit_tests = 0;
                     52: static struct registered_test test_exit_registry[1024];
                     53: 
                     54: int get_mac_addr(const char *in, char *out);
                     55: void strip_newline(char* s);
                     56: 
                     57: 
                     58: #define MYTEST(a) static void a(int);__attribute__((constructor)) \
                     59: static void cons_##a() {                           \
                     60:                 test_registry[numtests].fn = a;    \
                     61:                 test_registry[numtests].name = #a; \
                     62:                 numtests++;                        \
                     63: } START_TEST(a)
                     64: 
                     65: #define MY_EXIT_TEST(a) static void a(int);__attribute__((constructor)) \
                     66: static void cons_##a() {                                      \
                     67:                 test_exit_registry[num_exit_tests].fn = a;    \
                     68:                 test_exit_registry[num_exit_tests].name = #a; \
                     69:                 num_exit_tests++;                             \
                     70: } START_TEST(a)
                     71: 
                     72: /**
                     73:  *
                     74:  */
                     75: static void
                     76: xclose(int* fd)
                     77: {
                     78:         if (0 > close(*fd)) {
                     79:                 fprintf(stderr, "close(%d): %s", *fd, strerror(errno));
                     80:                 *fd = -1;
                     81:         }
                     82: }
                     83: 
                     84: struct captured_output {
                     85:         int saved_fd;  // Old fd, will be dup2()ed back in place when done.
                     86:         int fno;       // Overridden fd (e.g. stdout or stderr).
                     87:         int reader_fd; // Reader end of the pipe.
                     88:         char* buffer;  // Output buffer.
                     89:         size_t bufsize; // Buffer size.
                     90:         pthread_t thread;  // Reader thread.
                     91: };
                     92: 
                     93: /**
                     94:  * Helper function for stdout/stderr catching.
                     95:  *
                     96:  * This is the main() for the thread that reads from the fake stdout pipe
                     97:  * and writes into the buffer.
                     98:  *
                     99:  */
                    100: static void*
                    101: read_main(void* p)
                    102: {
                    103:         struct captured_output* out = p;
                    104:         char *cur = out->buffer;
                    105: 
                    106:         for (;;) {
                    107:                 ssize_t n;
                    108:                 n = out->bufsize - (cur - out->buffer);
                    109:                 assert(n > 0);
                    110:                 n = read(out->reader_fd, cur, n);
                    111:                 if (n > 0) {
                    112:                         cur += n;
                    113:                 }
                    114:                 if (n == 0) {
                    115:                         return NULL;
                    116:                 }
                    117:         }
                    118: }
                    119: 
                    120: /**
                    121:  * Helper function to capture stdout/stderr output.
                    122:  *
                    123:  * Args:
                    124:  *   fd:  The fd to capture.
                    125:  * Returns:
                    126:  *   A structure to be used as a handle. Only thing caller should do with
                    127:  *   this structure is call stop_capture(), read its .buffer member, and
                    128:  *   uncapture().
                    129:  */
                    130: static struct captured_output*
                    131: capture(int fd)
                    132: {
                    133:         struct captured_output* out;
                    134: 
                    135:         out = calloc(1, sizeof(struct captured_output));
                    136:         fail_if(out == NULL);
                    137: 
                    138:         out->fno = fd;
                    139:         out->saved_fd = dup(fd);
                    140:         out->bufsize = 1024*100;
                    141:         out->buffer = calloc(1, out->bufsize);
                    142: 
                    143:         fail_if(0 > out->saved_fd);
                    144:         fail_if(out->buffer == NULL);
                    145: 
                    146:         // set up pipe
                    147:         int fds[2];
                    148:         fail_if(0 > pipe(fds));
                    149:         fail_if(0 > dup2(fds[1], fd));
                    150:         out->reader_fd = fds[0];
                    151:         xclose(&fds[1]);
                    152: 
                    153:         fail_if(pthread_create(&out->thread, NULL, read_main, (void*)out));
                    154:         return out;
                    155: }
                    156: 
                    157: /**
                    158:  * Helper function to capture stdout/stderr output.
                    159:  *
                    160:  * Stop capture, so that .buffer becomes readable.
                    161:  */
                    162: static void
                    163: stop_capture(struct captured_output* out)
                    164: {
                    165:         fail_if(0 > dup2(out->saved_fd, out->fno));
                    166:         xclose(&out->saved_fd);
                    167:         fail_if(pthread_join(out->thread, NULL));
                    168:         xclose(&out->reader_fd);
                    169: }
                    170: 
                    171: /**
                    172:  * Helper function to capture stdout/stderr output.
                    173:  *
                    174:  * Deallocate buffer. stop_capture() must be called before uncapture().
                    175:  */
                    176: static void
                    177: uncapture(struct captured_output* out)
                    178: {
                    179:         free(out->buffer);
                    180:         out->buffer = NULL;
                    181:         free(out);
                    182: }
                    183: 
                    184: static uint8_t*
                    185: mkpacket(struct pcap_pkthdr* pkthdr)
                    186: {
                    187:         uint8_t* packet = calloc(1, 1500);
                    188:         fail_if(packet == NULL);
                    189: 
                    190:         struct libnet_802_3_hdr* heth;
                    191:         struct libnet_arp_hdr* harp;
                    192: 
                    193:         // Set up ethernet header
                    194:         heth = (void*)packet;
                    195:         memcpy(heth->_802_3_dhost, "\x11\x22\x33\x44\x55\x66", 6);
                    196:         memcpy(heth->_802_3_shost, "\x77\x88\x99\xaa\xbb\xcc", 6);
                    197:         heth->_802_3_len = 0;  // FIXME: is this correct?
                    198: 
                    199:         // Set up ARP header.
                    200:         harp = (void*)((char*)heth + LIBNET_ETH_H);
                    201:         harp->ar_hln = 6;
                    202:         harp->ar_pln = 4;
                    203:         harp->ar_hrd = htons(ARPHRD_ETHER);
                    204:         harp->ar_op = htons(ARPOP_REPLY);
                    205:         harp->ar_pro = htons(ETHERTYPE_IP);
                    206: 
                    207:         memcpy((char*)harp + LIBNET_ARP_H, heth->_802_3_shost, 6);
                    208:         memcpy((char*)harp + LIBNET_ARP_H + harp->ar_hln, &dstip, 4);
                    209: 
                    210:         memcpy((char*)harp + LIBNET_ARP_H
                    211:                + harp->ar_hln
                    212:                + harp->ar_pln, heth->_802_3_dhost, 6);
                    213:         memcpy((char*)harp + LIBNET_ARP_H
                    214:                + harp->ar_hln
                    215:                + harp->ar_pln
                    216:                + harp->ar_hln, &srcip, 4);
                    217: 
                    218:         pkthdr->ts.tv_sec = time(NULL);
                    219:         pkthdr->ts.tv_usec = 0;
                    220:         pkthdr->len = 60;
                    221:         pkthdr->caplen = 60;
                    222: 
                    223:         return packet;
                    224: }
                    225: 
                    226: static void
                    227: dump_packet(uint8_t* packet, int len)
                    228: {
                    229:         int c;
                    230:         for (c = 0; c < len; c++) {
                    231:                 fprintf(stderr, "0x%.2x, ", (int)packet[c]);
                    232:                 if (!((c+1) % 10)) {
                    233:                         fprintf(stderr, "\n");
                    234:                 }
                    235:         }
                    236:         fprintf(stderr, "\n");
                    237: }
                    238: 
                    239: MYTEST(test_mkpacket)
                    240: {
                    241:         uint8_t correct_packet[] = {
                    242:                 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
                    243:                 0xbb, 0xcc, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
                    244:                 0x00, 0x02, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0x12, 0x34,
                    245:                 0x56, 0x78, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x87, 0x65,
                    246:                 0x43, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    247:                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    248:         };
                    249:         struct pcap_pkthdr pkthdr;
                    250:         dstip = htonl(0x12345678);
                    251:         srcip = htonl(0x87654321);
                    252: 
                    253:         uint8_t* packet = mkpacket(&pkthdr);
                    254:         fail_if(packet == NULL);
                    255:         fail_unless(pkthdr.caplen == 60);
                    256:         if (memcmp(packet, correct_packet, pkthdr.caplen)) {
                    257:                 dump_packet(packet, pkthdr.caplen);
                    258:         }
                    259:         fail_unless(!memcmp(packet, correct_packet, pkthdr.caplen));
                    260: } END_TEST
                    261: 
                    262: 
                    263: // Received uninteresting packet, should not record anything.
                    264: MYTEST(pingip_uninteresting_packet)
                    265: {
                    266:         struct pcap_pkthdr pkthdr;
                    267:         uint8_t* packet;
                    268:         struct libnet_802_3_hdr* heth;
                    269:         struct libnet_arp_hdr* harp;
                    270: 
                    271:         int prev_numrecvd = numrecvd;
                    272:         struct captured_output* sout;
                    273: 
                    274:         // Completely broken packet.
                    275:         packet = calloc(1, 1500);
                    276:         sout = capture(1);
                    277:         pingip_recv(NULL, &pkthdr, packet);
                    278:         stop_capture(sout);
                    279:         fail_unless(strlen(sout->buffer) == 0);
                    280:         fail_unless(prev_numrecvd == numrecvd);
                    281:         uncapture(sout);
                    282:         free(packet);
                    283: 
                    284:         // Not ETHERTYPE_IP.
                    285:         packet = mkpacket(&pkthdr);
                    286:         harp = (void*)((char*)packet + LIBNET_ETH_H);
                    287:         harp->ar_pro = 0;
                    288:         sout = capture(1);
                    289:         pingip_recv(NULL, &pkthdr, packet);
                    290:         stop_capture(sout);
                    291:         fail_unless(prev_numrecvd == numrecvd);
                    292:         fail_unless(strlen(sout->buffer) == 0);
                    293:         uncapture(sout);
                    294:         free(packet);
                    295: 
                    296:         // Not ARPHRD_ETHER
                    297:         packet = mkpacket(&pkthdr);
                    298:         harp = (void*)((char*)packet + LIBNET_ETH_H);
                    299:         harp->ar_hrd = 0;
                    300:         sout = capture(1);
                    301:         pingip_recv(NULL, &pkthdr, packet);
                    302:         stop_capture(sout);
                    303:         fail_unless(prev_numrecvd == numrecvd);
                    304:         fail_unless(strlen(sout->buffer) == 0);
                    305:         uncapture(sout);
                    306:         free(packet);
                    307: 
                    308:         // Wrong dstip
                    309:         if (0) {
                    310:                 uint32_t wrongip = 123;
                    311:                 packet = mkpacket(&pkthdr);
                    312:                 harp = (void*)((char*)packet + LIBNET_ETH_H);
                    313:                 memcpy((char*)harp + harp->ar_hln + LIBNET_ARP_H, &wrongip, 4);
                    314:                 sout = capture(1);
                    315:                 pingip_recv(NULL, &pkthdr, packet);
                    316:                 stop_capture(sout);
                    317:                 fail_unless(prev_numrecvd == numrecvd);
                    318:                 fail_unless(strlen(sout->buffer) == 0);
                    319:                 uncapture(sout);
                    320:                 free(packet);
                    321:         }
                    322: 
                    323:         // Short packet.
                    324:         packet = mkpacket(&pkthdr);
                    325:         pkthdr.caplen = pkthdr.len = 41;
                    326:         sout = capture(1);
                    327:         pingip_recv(NULL, &pkthdr, packet);
                    328:         stop_capture(sout);
                    329:         fail_unless(prev_numrecvd == numrecvd);
                    330:         fail_unless(strlen(sout->buffer) == 0);
                    331:         uncapture(sout);
                    332:         free(packet);
                    333: 
                    334:         // Short captured packet.
                    335:         packet = mkpacket(&pkthdr);
                    336:         pkthdr.caplen = 41;
                    337:         sout = capture(1);
                    338:         pingip_recv(NULL, &pkthdr, packet);
                    339:         stop_capture(sout);
                    340:         fail_unless(prev_numrecvd == numrecvd);
                    341:         fail_unless(strlen(sout->buffer) == 0);
                    342:         uncapture(sout);
                    343:         free(packet);
                    344: 
                    345:         // Wrong length of hardware address.
                    346:         {
                    347:                 uint8_t packet[] = {
                    348:                         0x11, 0x22, 0x33, 0x44, 0x55, 0x66, // dst
                    349:                         0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, // src
                    350:                         0x00, 0x00, // type
                    351:                         0x00, 0x01, // hardware
                    352:                         0x08, 0x00, // protocol
                    353:                         0x04, 0x04, // lengths (for this test length is wrong)
                    354:                         0x00, 0x02, // operator
                    355: 
                    356:                         0x77, 0x88, 0x99, 0xaa, // sender (wrong length for test)
                    357:                         0x12, 0x34, 0x56, 0x78, // sender protocol address
                    358: 
                    359:                         0x11, 0x22, 0x33, 0x44, // receiver (wrong length for test)
                    360:                         0x87, 0x65, 0x43, 0x21, // receiver protocol address
                    361: 
                    362:                         0x00, 0x00, 0x00, 0x00,
                    363:                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    364:                         0x00, 0x00, 0x00, 0x00,
                    365:                         0x00, 0x00, 0x00, 0x00,
                    366:                         0x00, 0x00, 0x00, 0x00,
                    367:                         0x6f, 0xa8, 0x58, 0x63,
                    368:         };
                    369:                 pkthdr.len = 60;
                    370:                 pkthdr.caplen = 60;
                    371:                 sout = capture(1);
                    372:                 pingip_recv(NULL, &pkthdr, packet);
                    373:                 stop_capture(sout);
                    374:                 fail_unless(strlen(sout->buffer) == 0, sout->buffer);
                    375:                 fail_unless(prev_numrecvd == numrecvd);
                    376:                 uncapture(sout);
                    377:         }
                    378: 
                    379:         // Wrong length of protocol address.
                    380:         packet = mkpacket(&pkthdr);
                    381:         ((struct libnet_arp_hdr*)((char*)packet + LIBNET_ETH_H))->ar_pln = 6;
                    382:         sout = capture(1);
                    383:         pingip_recv(NULL, &pkthdr, packet);
                    384:         stop_capture(sout);
                    385:         fail_unless(prev_numrecvd == numrecvd);
                    386:         fail_unless(strlen(sout->buffer) == 0);
                    387:         uncapture(sout);
                    388:         free(packet);
                    389: } END_TEST
                    390: 
                    391: // Received reply that actually matches. Things should happen.
                    392: MYTEST(pingip_interesting_packet)
                    393: {
                    394:         struct pcap_pkthdr pkthdr;
                    395:         extern uint8_t srcmac[ETH_ALEN];
                    396:         memcpy(srcmac, "\x11\x22\x33\x44\x55\x66", ETH_ALEN);
                    397:         uint8_t packet[] = {
                    398:                 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, // dst
                    399:                 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, // src
                    400:                 0x00, 0x00, // type
                    401:                 0x00, 0x01, // hardware
                    402:                 0x08, 0x00, // protocol
                    403:                 0x06, 0x04, // lengths
                    404:                 0x00, 0x02, // operator
                    405: 
                    406:                 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, // sender
                    407:                 0x12, 0x34, 0x56, 0x78, // sender protocol address
                    408: 
                    409:                 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, // receiver
                    410:                 0x87, 0x65, 0x43, 0x21, // receiver protocol address
                    411: 
                    412:                 0x00, 0x00, 0x00, 0x00,
                    413:                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    414:                 0x6f, 0xa8, 0x58, 0x63,
                    415:         };
                    416:         numrecvd = 0;
                    417:         int prev_numrecvd = numrecvd;
                    418: 
                    419:         dstip = htonl(0x12345678);
                    420: 
                    421:         pkthdr.ts.tv_sec = time(NULL);
                    422:         pkthdr.ts.tv_usec = 0;
                    423:         pkthdr.len = 60;
                    424:         pkthdr.caplen = 60;
                    425: 
                    426:         struct captured_output *sout;
                    427: 
                    428:         // First ping.
                    429:         const char* correct0 =
                    430:                         "60 bytes from 77:88:99:aa:bb:cc (18.52.86.120): "
                    431:                         "index=0 time=";
                    432:         sout = capture(1);
                    433:         pingip_recv(NULL, &pkthdr, packet);
                    434:         stop_capture(sout);
                    435: 
                    436:         char* emsg = NULL;
                    437:         fail_unless(0 < asprintf(&emsg, "Captured: <%s> (%zd), want   <%s> %zd\n",
                    438:                          sout->buffer, strlen(sout->buffer),
                    439:                                  correct0, strlen(correct0)));
                    440:         fail_unless(!strncmp(sout->buffer, correct0, strlen(correct0)), emsg);
                    441:         uncapture(sout);
                    442:         free(emsg);
                    443: 
                    444:         fail_unless(numrecvd == prev_numrecvd + 1,
                    445:                     "numrecvd not incremented");
                    446: 
                    447:         pingip_recv(NULL, &pkthdr, packet);
                    448:         fail_unless(numrecvd == prev_numrecvd + 2,
                    449:                     "numrecvd not incremented second time");
                    450: } END_TEST
                    451: 
                    452: MYTEST(strip_newline_test)
                    453: {
                    454:         const char *tests[][2] = {
                    455:                 {"", ""},
                    456:                 {"\n", ""},
                    457:                 {"\n\n\n", ""},
                    458:                 {"foo", "foo"},
                    459:                 {"foo\n", "foo"},
                    460:                 {"foo\n\n\n", "foo"},
                    461:                 {NULL, NULL},
                    462:         };
                    463:         int c;
                    464:         for (c = 0; tests[c][0]; c++){
                    465:                 char buf[128];
                    466:                 strcpy(buf, tests[c][0]);
                    467:                 strip_newline(buf);
                    468:                 fail_unless(!strcmp(buf, tests[c][1]));
                    469:         }
                    470: } END_TEST
                    471: 
                    472: MYTEST(get_mac_addr_success)
                    473: {
                    474:         const char *tests[][2] = {
                    475:                 // Null.
                    476:                 {"0000.0000.0000", "\x00\x00\x00\x00\x00\x00"},
                    477:                 {"00:00:00:00:00:00", "\x00\x00\x00\x00\x00\x00"},
                    478:                 {"00-00-00-00-00-00", "\x00\x00\x00\x00\x00\x00"},
                    479: 
                    480:                 // Broadcast.
                    481:                 {"FFFF.FFFF.FFFF", "\xFF\xFF\xFF\xFF\xFF\xFF"},
                    482:                 {"FF:FF:FF:FF:FF:FF", "\xFF\xFF\xFF\xFF\xFF\xFF"},
                    483:                 {"FF-FF-FF-FF-FF-FF", "\xFF\xFF\xFF\xFF\xFF\xFF"},
                    484: 
                    485:                 // Normal looking.
                    486:                 {"1122.3344.5566", "\x11\x22\x33\x44\x55\x66"},
                    487:                 {"11:22:33:44:55:66", "\x11\x22\x33\x44\x55\x66"},
                    488:                 {"11-22-33-44-55-66", "\x11\x22\x33\x44\x55\x66"},
                    489: 
                    490:                 // Has some zeroes.
                    491:                 {"1100.0000.5566", "\x11\x00\x00\x00\x55\x66"},
                    492:                 {"11:00:00:00:55:66", "\x11\x00\x00\x00\x55\x66"},
                    493:                 {"11-00-00-00-55-66", "\x11\x00\x00\x00\x55\x66"},
                    494:                 {NULL, NULL},
                    495:         };
                    496:         int c;
                    497:         for (c = 0; tests[c][0]; c++){
                    498:                 char buf[6];
                    499:                 fail_unless(get_mac_addr(tests[c][0], buf));
                    500:                 fail_unless(!memcmp(buf, tests[c][1], 6));
                    501:         }
                    502: } END_TEST
                    503: 
                    504: MYTEST(get_mac_addr_fail)
                    505: {
                    506:         const char *tests[] = {
                    507:                 "",
                    508:                 "blaha",
                    509:                 "11:22:33:44:55",
                    510:                 "11:22:33:44:55:zz",
                    511:                 NULL,
                    512:         };
                    513:         int c;
                    514:         for (c = 0; tests[c]; c++){
                    515:                 char buf[6];
                    516:                 fail_if(get_mac_addr(tests[c], buf));
                    517:         }
                    518: } END_TEST
                    519: 
                    520: MY_EXIT_TEST(libnet_init_bad_nolo)
                    521: {
                    522:         // It'll only try lo if named interface fails.
                    523:         // So by accepting lo, we make sure it doesn't try lo.
                    524:         mock_libnet_lo_ok = 1;
                    525:         do_libnet_init("bad", 0);
                    526: } END_TEST
                    527: 
                    528: MY_EXIT_TEST(libnet_init_null_nolo_nonull)
                    529: {
                    530:         mock_libnet_lo_ok = 0;
                    531:         mock_libnet_null_ok = 0;
                    532:         do_libnet_init(NULL, 0);
                    533: } END_TEST
                    534: 
                    535: MYTEST(libnet_init_good)
                    536: {
                    537:         mock_libnet_lo_ok = 0; // Don't even try falling back to lo.
                    538:         do_libnet_init("good", 0);
                    539:         fail_if(libnet == NULL);
                    540: } END_TEST
                    541: 
                    542: MYTEST(libnet_init_null_nolo)
                    543: {
                    544:         mock_libnet_lo_ok = 0;
                    545:         mock_libnet_null_ok = 1;
                    546:         do_libnet_init(NULL, 0);
                    547:         fail_if(libnet == NULL);
                    548: } END_TEST
                    549: 
                    550: static Suite*
                    551: arping_suite(void)
                    552: {
                    553:         int c;
                    554:         Suite* s = suite_create("Arping");
                    555: 
                    556:         //tcase_add_checked_fixture (tc_core, setup, teardown);
                    557:         for (c = 0; c < numtests; c++) {
                    558:                 TCase *tc_core = tcase_create(test_registry[c].name);
                    559:                 tcase_add_test(tc_core, test_registry[c].fn);
                    560:                 suite_add_tcase(s, tc_core);
                    561:         }
                    562:         for (c = 0; c < num_exit_tests; c++) {
                    563:                 TCase *tc_core = tcase_create(test_exit_registry[c].name);
                    564:                 tcase_add_exit_test(tc_core, test_exit_registry[c].fn, 1);
                    565:                 suite_add_tcase(s, tc_core);
                    566:         }
                    567:         return s;
                    568: }
                    569: 
                    570: int
                    571: main()
                    572: {
                    573:         int number_failed;
                    574:         Suite *s = arping_suite();
                    575:         SRunner *sr = srunner_create (s);
                    576:         srunner_run_all (sr, CK_NORMAL);
                    577:         number_failed = srunner_ntests_failed (sr);
                    578:         srunner_free (sr);
                    579:         return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
                    580: }
                    581: /* ---- Emacs Variables ----
                    582:  * Local Variables:
                    583:  * c-basic-offset: 8
                    584:  * indent-tabs-mode: nil
                    585:  * End:
                    586:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>