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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [net/] [tcpip/] [v2_0/] [src/] [ecos/] [support.c] - Blame information for rev 1773

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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