OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [tcpip/] [current/] [src/] [ecos/] [support.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      ecos/support.c
4
//
5
//      eCos wrapper and support functions
6
//
7
//==========================================================================
8
// ####BSDALTCOPYRIGHTBEGIN####                                             
9
// -------------------------------------------                              
10
// Portions of this software may have been derived from OpenBSD             
11
// or other sources, and if so are covered by the appropriate copyright     
12
// and license included herein.                                             
13
// -------------------------------------------                              
14
// ####BSDALTCOPYRIGHTEND####                                               
15
//==========================================================================
16
//#####DESCRIPTIONBEGIN####
17
//
18
// Author(s):    gthomas, hmt
19
// Contributors: gthomas, hmt
20
// Date:         2000-01-10
21
// Purpose:      
22
// Description:  
23
//              
24
//
25
//####DESCRIPTIONEND####
26
//
27
//==========================================================================
28
 
29
 
30
// Support routines, etc., used by network code
31
 
32
#include <sys/param.h>
33
#include <sys/malloc.h>
34
#include <sys/mbuf.h>
35
#include <sys/kernel.h>
36
#include <sys/domain.h>
37
#include <sys/protosw.h>
38
#include <sys/sockio.h>
39
#include <sys/socket.h>
40
#include <sys/socketvar.h>
41
#include <net/if.h>
42
#include <net/route.h>
43
#include <net/netisr.h>
44
#include <netinet/in.h>
45
#include <netinet/in_var.h>
46
#include <arpa/inet.h>
47
 
48
#include <machine/cpu.h>
49
 
50
#include <pkgconf/net.h>
51
 
52
#include <cyg/infra/diag.h>
53
#include <cyg/hal/hal_intr.h>
54
#include <cyg/kernel/kapi.h>
55
 
56
#include <cyg/infra/cyg_ass.h>
57
 
58
#if !CYGPKG_NET_DRIVER_FRAMEWORK   // Interface
59
#error At least one network driver framework must be defined!
60
#else
61
#include <cyg/io/eth/netdev.h>
62
 
63
// Define table boundaries
64
CYG_HAL_TABLE_BEGIN( __NETDEVTAB__, netdev );
65
CYG_HAL_TABLE_END( __NETDEVTAB_END__, netdev );
66
 
67
// Used for system-wide "ticks per second"
68
int hz = 100;
69
int tick = 10000;  // usec per "tick"
70
 
71
volatile struct timeval mono_time;
72
volatile struct timeval ktime;
73
 
74
// Low-level network debugging
75
int net_debug = 0;
76
 
77
#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
78
static char netint_stack[STACK_SIZE];
79
static cyg_thread netint_thread_data;
80
static cyg_handle_t netint_thread_handle;
81
 
82
cyg_flag_t netint_flags;
83
#define NETISR_ANY 0xFFFFFFFF  // Any possible bit...
84
 
85
extern void cyg_test_exit(void);  // TEMP
86
void
87
cyg_panic(const char *msg, ...)
88
{
89
    cyg_uint32 old_ints;
90
    CYG_FAIL( msg );
91
    HAL_DISABLE_INTERRUPTS(old_ints);
92
    diag_printf("PANIC: %s\n", msg);
93
    cyg_test_exit();  // FIXME
94
}
95
 
96
 
97
// Round a number 'n' up to a multiple of 'm'
98
#define round(n,m) ((((n)+((m)-1))/(m))*(m))
99
 
100
#define NET_MEMPOOL_SIZE  round(CYGPKG_NET_MEM_USAGE/4,MSIZE)
101
#define NET_MBUFS_SIZE    round(CYGPKG_NET_MEM_USAGE/4,MSIZE)
102
#define NET_CLUSTERS_SIZE round(CYGPKG_NET_MEM_USAGE/2,MCLBYTES)
103
 
104
static unsigned char net_mempool_area[NET_MEMPOOL_SIZE];
105
static cyg_mempool_var net_mem_pool;
106
static cyg_handle_t    net_mem;
107
static unsigned char net_mbufs_area[NET_MBUFS_SIZE];
108
static cyg_mempool_fix net_mbufs_pool;
109
static cyg_handle_t    net_mbufs;
110
static unsigned char net_clusters_area[NET_CLUSTERS_SIZE];
111
static cyg_mempool_fix net_clusters_pool;
112
static cyg_handle_t    net_clusters;
113
static char            net_clusters_refcnt[(NET_CLUSTERS_SIZE/MCLBYTES)+1];
114
 
115
#ifdef CYGDBG_NET_TIMING_STATS
116
static struct net_stats  stats_malloc, stats_free,
117
    stats_memcpy, stats_memset,
118
    stats_mbuf_alloc, stats_mbuf_free, stats_cluster_alloc;
119
extern struct net_stats stats_in_cksum;
120
 
121
// Display a number of ticks as microseconds
122
// Note: for improved calculation significance, values are kept in ticks*1000
123
static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION;
124
static long ns_per_system_clock;
125
 
126
static void
127
show_ticks_in_us(cyg_uint32 ticks)
128
{
129
    long long ns;
130
    ns_per_system_clock = 1000000/rtc_resolution[1];
131
    ns = (ns_per_system_clock * ((long long)ticks * 1000)) /
132
        CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
133
    ns += 5;  // for rounding to .01us
134
    diag_printf("%7d.%02d", (int)(ns/1000), (int)((ns%1000)/10));
135
}
136
 
137
void
138
show_net_stats(struct net_stats *stats, const char *title)
139
{
140
    int ave;
141
    ave = stats->total_time / stats->count;
142
    diag_printf("%s:\n", title);
143
    diag_printf("  count: %6d", stats->count);
144
    diag_printf(", min: ");
145
    show_ticks_in_us(stats->min_time);
146
    diag_printf(", max: ");
147
    show_ticks_in_us(stats->max_time);
148
    diag_printf(", total: ");
149
    show_ticks_in_us(stats->total_time);
150
    diag_printf(", ave: ");
151
    show_ticks_in_us(ave);
152
    diag_printf("\n");
153
    // Reset stats
154
    memset(stats, 0, sizeof(*stats));
155
}
156
 
157
void
158
show_net_times(void)
159
{
160
    show_net_stats(&stats_malloc,        "Net malloc");
161
    show_net_stats(&stats_free,          "Net free");
162
    show_net_stats(&stats_mbuf_alloc,    "Mbuf alloc");
163
    show_net_stats(&stats_mbuf_free,     "Mbuf free");
164
    show_net_stats(&stats_cluster_alloc, "Cluster alloc");
165
    show_net_stats(&stats_in_cksum,      "Checksum");
166
    show_net_stats(&stats_memcpy,        "Net memcpy");
167
    show_net_stats(&stats_memset,        "Net memset");
168
}
169
#endif /* CYGDBG_NET_TIMING_STATS */ 
170
 
171
void *
172
cyg_net_malloc(u_long size, int type, int flags)
173
{
174
    void *res;
175
    START_STATS();
176
    if (flags & M_NOWAIT) {
177
        res = cyg_mempool_var_try_alloc(net_mem, size);
178
    } else {
179
        res = cyg_mempool_var_alloc(net_mem, size);
180
    }
181
    FINISH_STATS(stats_malloc);
182
    return (res);
183
}
184
 
185
void
186
cyg_net_free(caddr_t addr, int type)
187
{
188
    START_STATS();
189
    cyg_mempool_var_free(net_mem, addr);
190
    FINISH_STATS(stats_free);
191
}
192
 
193
void *
194
cyg_net_mbuf_alloc(int type, int flags)
195
{
196
    void *res;
197
    START_STATS();
198
    mbstat.m_mbufs++;
199
    if (flags & M_NOWAIT) {
200
        res = cyg_mempool_fix_try_alloc(net_mbufs);
201
    } else {
202
        res = cyg_mempool_fix_alloc(net_mbufs);
203
    }
204
    FINISH_STATS(stats_mbuf_alloc);
205
    // Check that this nastiness works OK
206
    CYG_ASSERT( dtom(res) == res, "dtom failed, base of mbuf" );
207
    CYG_ASSERT( dtom((char *)res + MSIZE/2) == res, "dtom failed, mid mbuf" );
208
    return (res);
209
}
210
 
211
void
212
cyg_net_mbuf_free(caddr_t addr, int type)
213
{
214
    START_STATS();
215
    mbstat.m_mbufs--;
216
    cyg_mempool_fix_free(net_mbufs, addr);
217
    FINISH_STATS(stats_mbuf_free);
218
}
219
 
220
void *
221
cyg_net_cluster_alloc(void)
222
{
223
    void *res;
224
    START_STATS();
225
    res = cyg_mempool_fix_try_alloc(net_clusters);
226
    FINISH_STATS(stats_cluster_alloc);
227
    return res;
228
}
229
 
230
static void
231
cyg_kmem_init(void)
232
{
233
    unsigned char *p;
234
#ifdef CYGPKG_NET_DEBUG
235
    diag_printf("Network stack using %d bytes for misc space\n", NET_MEMPOOL_SIZE);
236
    diag_printf("                    %d bytes for mbufs\n", NET_MBUFS_SIZE);
237
    diag_printf("                    %d bytes for mbuf clusters\n", NET_CLUSTERS_SIZE);
238
#endif
239
    cyg_mempool_var_create(&net_mempool_area,
240
                           NET_MEMPOOL_SIZE,
241
                           &net_mem,
242
                           &net_mem_pool);
243
    // Align the mbufs on MSIZE boudaries so that dtom() can work.
244
    p = (unsigned char *)(((long)(&net_mbufs_area) + MSIZE - 1) & ~(MSIZE-1));
245
    cyg_mempool_fix_create(p,
246
                           ((&(net_mbufs_area[NET_MBUFS_SIZE])) - p) & ~(MSIZE-1),
247
                           MSIZE,
248
                           &net_mbufs,
249
                           &net_mbufs_pool);
250
    cyg_mempool_fix_create(&net_clusters_area,
251
                           NET_CLUSTERS_SIZE,
252
                           MCLBYTES,
253
                           &net_clusters,
254
                           &net_clusters_pool);
255
    mbutl = (struct mbuf *)&net_clusters_area;
256
    mclrefcnt = net_clusters_refcnt;
257
}
258
 
259
void cyg_kmem_print_stats( void )
260
{
261
    cyg_mempool_info info;
262
 
263
    diag_printf( "Network stack mbuf stats:\n" );
264
    diag_printf( "   mbufs %d, clusters %d, free clusters %d\n",
265
                 mbstat.m_mbufs,        /* mbufs obtained from page pool */
266
                 mbstat.m_clusters,     /* clusters obtained from page pool */
267
                 /* mbstat.m_spare, */  /* spare field */
268
                 mbstat.m_clfree        /* free clusters */
269
        );
270
    diag_printf( "   Failed to get %d times\n"
271
                 "   Waited to get %d times\n"
272
                 "   Drained queues to get %d times\n",
273
                 mbstat.m_drops,        /* times failed to find space */
274
                 mbstat.m_wait,         /* times waited for space */
275
                 mbstat.m_drain         /* times drained protocols for space */
276
                 /* mbstat.m_mtypes[256]; type specific mbuf allocations */
277
        );
278
 
279
    cyg_mempool_var_get_info( net_mem, &info );
280
    diag_printf( "Misc mpool: total %7d, free %7d, max free block %d\n",
281
                 info.totalmem,
282
                 info.freemem,
283
                 info.maxfree
284
        );
285
 
286
    cyg_mempool_fix_get_info( net_mbufs, &info );
287
    diag_printf( "Mbufs pool: total %7d, free %7d, blocksize %4d\n",
288
                 info.totalmem,
289
                 info.freemem,
290
                 info.blocksize
291
        );
292
 
293
 
294
    cyg_mempool_fix_get_info( net_clusters, &info );
295
    diag_printf( "Clust pool: total %7d, free %7d, blocksize %4d\n",
296
                 info.totalmem,
297
                 info.freemem,
298
                 info.blocksize
299
        );
300
}
301
 
302
// This API is for our own automated network tests.  It's not in any header
303
// files because it's not at all supported.
304
int cyg_net_get_mem_stats( int which, cyg_mempool_info *p )
305
{
306
    CYG_CHECK_DATA_PTR( p, "Bad pointer to mempool_info" );
307
    CYG_ASSERT( 0 <= which, "Mempool selector underflow" );
308
    CYG_ASSERT( 2 >=which, "Mempool selector overflow" );
309
 
310
    if ( p )
311
        switch ( which ) {
312
        case 0:
313
            cyg_mempool_var_get_info( net_mem, p );
314
            break;
315
        case 1:
316
            cyg_mempool_fix_get_info( net_mbufs, p );
317
            break;
318
        case 2:
319
            cyg_mempool_fix_get_info( net_clusters, p );
320
            break;
321
        default:
322
            return 0;
323
        }
324
    return (int)p;
325
}
326
 
327
int
328
cyg_mtocl(u_long x)
329
{
330
    int res;
331
    res = (((u_long)(x) - (u_long)mbutl) >> MCLSHIFT);
332
    return res;
333
}
334
 
335
struct mbuf *
336
cyg_cltom(u_long x)
337
{
338
    struct mbuf *res;
339
    res = (struct mbuf *)((caddr_t)((u_long)mbutl + ((u_long)(x) << MCLSHIFT)));
340
    return res;
341
}
342
 
343
externC void
344
net_memcpy(void *d, void *s, int n)
345
{
346
    START_STATS();
347
    memcpy(d, s, n);
348
    FINISH_STATS(stats_memcpy);
349
}
350
 
351
externC void
352
net_memset(void *s, int v, int n)
353
{
354
    START_STATS();
355
    memset(s, v, n);
356
    FINISH_STATS(stats_memset);
357
}
358
 
359
// Rather than bring in the whole BSD 'random' code...
360
int
361
arc4random(void)
362
{
363
    cyg_uint32 res;
364
    static unsigned long seed = 0xDEADB00B;
365
    HAL_CLOCK_READ(&res);  // Not so bad... (but often 0..N where N is small)
366
    seed = ((seed & 0x007F00FF) << 7) ^
367
        ((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits
368
        (res << 13) ^ (res >> 9);    // using the clock too!
369
    return (int)seed;
370
}
371
 
372
void
373
get_random_bytes(void *buf, size_t len)
374
{
375
    unsigned long ranbuf, *lp;
376
    lp = (unsigned long *)buf;
377
    while (len > 0) {
378
        ranbuf = arc4random();
379
        *lp++ = ranbuf;
380
        len -= sizeof(ranbuf);
381
    }
382
}
383
 
384
void
385
microtime(struct timeval *tp)
386
{
387
    panic("microtime");
388
}
389
 
390
void
391
get_mono_time(void)
392
{
393
    panic("get_mono_time");
394
}
395
 
396
void
397
csignal(pid_t pgid, int signum, uid_t uid, uid_t euid)
398
{
399
    panic("csignal");
400
}
401
 
402
int
403
bcmp(const void *_p1, const void *_p2, size_t len)
404
{
405
    int res = 0;
406
    unsigned char *p1 = (unsigned char *)_p1;
407
    unsigned char *p2 = (unsigned char *)_p2;
408
    while (len-- > 0) {
409
        res = *p1++ - *p2++;
410
        if (res) break;
411
    }
412
    return res;
413
}
414
 
415
int
416
copyout(const void *s, void *d, size_t len)
417
{
418
    memcpy(d, s, len);
419
    return 0;
420
}
421
 
422
int
423
copyin(const void *s, void *d, size_t len)
424
{
425
    memcpy(d, s, len);
426
    return 0;
427
}
428
 
429
void
430
ovbcopy(const void *s, void *d, size_t len)
431
{
432
    memcpy(d, s, len);
433
}
434
 
435
// ------------------------------------------------------------------------
436
// THE NETWORK THREAD ITSELF
437
//
438
// Network software interrupt handler
439
//   This function is run as a separate thread to allow
440
// processing of network events (mostly incoming packets)
441
// at "user level" instead of at interrupt time.
442
//
443
static void
444
cyg_netint(cyg_addrword_t param)
445
{
446
    cyg_flag_value_t curisr;
447
    int spl;
448
    while (true) {
449
        curisr = cyg_flag_wait(&netint_flags, NETISR_ANY,
450
                               CYG_FLAG_WAITMODE_OR|CYG_FLAG_WAITMODE_CLR);
451
        spl = splsoftnet(); // Prevent any overlapping "stack" processing
452
#ifdef INET
453
        if (curisr & (1 << NETISR_ARP)) {
454
            // Pending ARP requests
455
            arpintr();
456
        }
457
        if (curisr & (1 << NETISR_IP)) {
458
            // Pending IPv4 input
459
            ipintr();
460
        }
461
#endif
462
#ifdef INET6
463
        if (curisr & (1 << NETISR_IPV6)) {
464
            // Pending IPv6 input
465
            ip6intr();
466
        }
467
#endif
468
#if NBRIDGE > 0
469
        if (curisr & (1 << NETISR_BRIDGE)) {
470
            // Pending bridge input
471
            bridgeintr();
472
        }
473
#endif
474
        splx(spl);
475
    }
476
}
477
 
478
 
479
// This just sets one of the pseudo-ISR bits used above.
480
void
481
setsoftnet(void)
482
{
483
    // This is called if we are out of MBUFs - it doesn't do anything, and
484
    // that situation is handled OK, so don't bother with the diagnostic:
485
 
486
    // diag_printf("setsoftnet\n");
487
 
488
    // No need to do this because it is ignored anyway:
489
    // schednetisr(NETISR_SOFTNET);
490
}
491
 
492
 
493
/* Update the kernel globel ktime. */
494
static void
495
cyg_ktime_func(cyg_handle_t alarm,cyg_addrword_t data)
496
{
497
    cyg_tick_count_t now = cyg_current_time();
498
 
499
    ktime.tv_usec = (now % hz) * tick;
500
    ktime.tv_sec = 1 + now / hz;
501
}
502
 
503
static void
504
cyg_ktime_init(void)
505
{
506
    cyg_handle_t ktime_alarm_handle;
507
    static cyg_alarm ktime_alarm;
508
    cyg_handle_t counter;
509
 
510
    // Do not start at 0 - net stack thinks 0 an invalid time;
511
    // Have a valid time available from right now:
512
    ktime.tv_usec = 0;
513
    ktime.tv_sec = 1;
514
 
515
    cyg_clock_to_counter(cyg_real_time_clock(),&counter);
516
    cyg_alarm_create(counter,
517
                     cyg_ktime_func,
518
                     0,
519
                     &ktime_alarm_handle,
520
                     &ktime_alarm);
521
 
522
    /* We want one alarm every 10ms. */
523
    cyg_alarm_initialize(ktime_alarm_handle,cyg_current_time()+1,1);
524
    cyg_alarm_enable(ktime_alarm_handle);
525
}
526
 
527
//
528
// Network initialization
529
//   This function is called during system initialization to setup the whole
530
// networking environment.
531
 
532
// Linker magic to execute this function as 'init'
533
extern void cyg_do_net_init(void);
534
 
535
extern void ifinit(void);
536
extern void loopattach(int);
537
extern void bridgeattach(int);
538
 
539
// Internal init functions:
540
extern void cyg_alarm_timeout_init(void);
541
extern void cyg_tsleep_init(void);
542
 
543
void
544
cyg_net_init(void)
545
{
546
    static int _init = false;
547
    cyg_netdevtab_entry_t *t;
548
 
549
    if (_init) return;
550
 
551
    cyg_do_net_init();  // Just forces linking in the initializer/constructor
552
    // Initialize interrupt "flags"
553
    cyg_flag_init(&netint_flags);
554
    // Initialize timeouts and net service thread (pseudo-DSRs)
555
    cyg_alarm_timeout_init();
556
    // Initialize tsleep/wakeup support
557
    cyg_tsleep_init();
558
    // Initialize network memory system
559
    cyg_kmem_init();
560
    mbinit();
561
    cyg_ktime_init();
562
 
563
    // Create network background thread
564
    cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY, // Priority
565
                      cyg_netint,               // entry
566
                      0,                        // entry parameter
567
                      "Network support",        // Name
568
                      &netint_stack[0],         // Stack
569
                      STACK_SIZE,               // Size
570
                      &netint_thread_handle,    // Handle
571
                      &netint_thread_data       // Thread data structure
572
        );
573
    cyg_thread_resume(netint_thread_handle);    // Start it
574
 
575
    // Initialize all network devices
576
    for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
577
//        diag_printf("Init device '%s'\n", t->name);
578
        if (t->init(t)) {
579
            t->status = CYG_NETDEVTAB_STATUS_AVAIL;
580
        } else {
581
            // What to do if device init fails?
582
            t->status = 0;  // Device not [currently] available
583
        }
584
    }
585
    // And attach the loopback interface
586
#ifdef CYGPKG_NET_NLOOP
587
#if 0 < CYGPKG_NET_NLOOP
588
    loopattach(0);
589
#endif
590
#endif
591
#if NBRIDGE > 0
592
    bridgeattach(0);
593
#endif
594
    // Start up the network processing
595
    ifinit();
596
    domaininit();
597
 
598
    // Done
599
    _init = true;
600
}
601
 
602
// Copyright (C) 2002 Gary Thomas
603
 
604
#include <net/if.h>
605
#include <net/route.h>
606
#include <net/netdb.h>
607
externC void if_indextoname(int indx, char *buf, int len);
608
 
609
typedef void pr_fun(char *fmt, ...);
610
 
611
static void
612
_mask(struct sockaddr *sa, char *buf, int _len)
613
{
614
    char *cp = ((char *)sa) + 4;
615
    int len = sa->sa_len - 4;
616
    int tot = 0;
617
 
618
    while (len-- > 0) {
619
        if (tot) *buf++ = '.';
620
        buf += diag_sprintf(buf, "%d", *cp++);
621
        tot++;
622
    }
623
 
624
    while (tot < 4) {
625
        if (tot) *buf++ = '.';
626
        buf += diag_sprintf(buf, "%d", 0);
627
        tot++;
628
    }
629
}
630
 
631
static void
632
_show_ifp(struct ifnet *ifp, pr_fun *pr)
633
{
634
    struct ifaddr *ifa;
635
    char addr[64], netmask[64], broadcast[64];
636
 
637
    (*pr)("%-8s", ifp->if_xname);
638
    TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
639
        if (ifa->ifa_addr->sa_family != AF_LINK) {
640
            getnameinfo (ifa->ifa_addr, ifa->ifa_addr->sa_len, addr, sizeof(addr), 0, 0, 0);
641
            getnameinfo (ifa->ifa_dstaddr, ifa->ifa_dstaddr->sa_len, broadcast, sizeof(broadcast), 0, 0, 0);
642
            _mask(ifa->ifa_netmask, netmask, 64);
643
            (*pr)("IP: %s, Broadcast: %s, Netmask: %s\n", addr, broadcast, netmask);
644
            (*pr)("        ");
645
            if ((ifp->if_flags & IFF_UP)) (*pr)("UP ");
646
            if ((ifp->if_flags & IFF_BROADCAST)) (*pr)("BROADCAST ");
647
            if ((ifp->if_flags & IFF_LOOPBACK)) (*pr)("LOOPBACK ");
648
            if ((ifp->if_flags & IFF_RUNNING)) (*pr)("RUNNING ");
649
            if ((ifp->if_flags & IFF_PROMISC)) (*pr)("PROMISC ");
650
            if ((ifp->if_flags & IFF_MULTICAST)) (*pr)("MULTICAST ");
651
            if ((ifp->if_flags & IFF_ALLMULTI)) (*pr)("ALLMULTI ");
652
            (*pr)("MTU: %d, Metric: %d\n", ifp->if_mtu, ifp->if_metric);
653
            (*pr)("        Rx - Packets: %d, Bytes: %d", ifp->if_data.ifi_ipackets, ifp->if_data.ifi_ibytes);
654
            (*pr)(", Tx - Packets: %d, Bytes: %d\n", ifp->if_data.ifi_opackets, ifp->if_data.ifi_obytes);
655
        }
656
    }
657
}
658
 
659
static int
660
_dumpentry(struct radix_node *rn, void *vw)
661
{
662
    struct rtentry *rt = (struct rtentry *)rn;
663
    struct sockaddr *dst, *gate, *netmask, *genmask;
664
    char addr[32], *cp;
665
    pr_fun *pr = (pr_fun *)vw;
666
 
667
    dst = rt_key(rt);
668
    gate = rt->rt_gateway;
669
    netmask = rt_mask(rt);
670
    genmask = rt->rt_genmask;
671
    if ((rt->rt_flags & (RTF_UP | RTF_LLINFO)) == RTF_UP) {
672
        if (netmask == NULL) {
673
            return 0;
674
        }
675
        _inet_ntop(dst, addr, sizeof(addr));
676
        (*pr)("%-15s ", addr);
677
        if (gate != NULL) {
678
            _inet_ntop(gate, addr, sizeof(addr));
679
            (*pr)("%-15s ", addr);
680
        } else {
681
            (*pr)("%-15s ", " ");
682
        }
683
        if (netmask != NULL) {
684
            _mask(netmask, addr, sizeof(addr));
685
            (*pr)("%-15s ", addr);
686
        } else {
687
            (*pr)("%-15s ", " ");
688
        }
689
        cp = addr;
690
        if ((rt->rt_flags & RTF_UP)) *cp++ = 'U';
691
        if ((rt->rt_flags & RTF_GATEWAY)) *cp++ = 'G';
692
        if ((rt->rt_flags & RTF_STATIC)) *cp++ = 'S';
693
        if ((rt->rt_flags & RTF_DYNAMIC)) *cp++ = 'D';
694
        *cp = '\0';
695
        (*pr)("%-8s ", addr);  // Flags
696
        if_indextoname(rt->rt_ifp->if_index, addr, 64);
697
        (*pr)("%-8s ", addr);
698
        (*pr)("\n");
699
    }
700
    return 0;
701
}
702
 
703
void
704
show_network_tables(pr_fun *pr)
705
{
706
    int i, error;
707
    struct radix_node_head *rnh;
708
    struct ifnet *ifp;
709
 
710
    cyg_scheduler_lock();
711
    (*pr)("Routing tables\n");
712
    (*pr)("Destination     Gateway         Mask            Flags    Interface\n");
713
    for (i = 1; i <= AF_MAX; i++) {
714
        if ((rnh = rt_tables[i]) != NULL) {
715
            error = rnh->rnh_walktree(rnh, _dumpentry, pr);
716
        }
717
    }
718
 
719
    (*pr)("Interface statistics\n");
720
    for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) {
721
        _show_ifp(ifp, pr);
722
    }
723
    cyg_scheduler_unlock();
724
}
725
 
726
#endif // CYGPKG_NET_DRIVER_FRAMEWORK
727
 
728
// EOF support.c

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.