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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [services/] [net.c] - Blame information for rev 566

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

Line No. Rev Author Line
1 2 marcus.erl
/*
2
 *      Copied from Linux Monitor (LiMon) - Networking.
3
 *
4
 *      Copyright 1994 - 2000 Neil Russell.
5
 *      (See License)
6
 *      Copyright 2000 Roland Borde
7
 *      Copyright 2000 Paolo Scaffardi
8
 *      Copyright 2000, 2001 Wolfgang Denk
9
 */
10
 
11
/*
12
 * General Desription:
13
 *
14
 * The user interface supports commands for BOOTP, RARP, and TFTP.
15
 * Also, we support ARP internally. Depending on available data,
16
 * these interact as follows:
17
 *
18
 * BOOTP:
19
 *
20
 *      Prerequisites:  - own ethernet address
21
 *      We want:        - own IP address
22
 *                      - TFTP server IP address
23
 *                      - name of bootfile
24
 *      Next step:      ARP
25
 *
26
 * RARP:
27
 *
28
 *      Prerequisites:  - own ethernet address
29
 *      We want:        - own IP address
30
 *                      - TFTP server IP address
31
 *      Next step:      ARP
32
 *
33
 * ARP:
34
 *
35
 *      Prerequisites:  - own ethernet address
36
 *                      - own IP address
37
 *                      - TFTP server IP address
38
 *      We want:        - TFTP server ethernet address
39
 *      Next step:      TFTP
40
 *
41
 * DHCP:
42
 *
43
 *     Prerequisites:   - own ethernet address
44
 *     We want:         - IP, Netmask, ServerIP, Gateway IP
45
 *                      - bootfilename, lease time
46
 *     Next step:       - TFTP
47
 *
48
 * TFTP:
49
 *
50
 *      Prerequisites:  - own ethernet address
51
 *                      - own IP address
52
 *                      - TFTP server IP address
53
 *                      - TFTP server ethernet address
54
 *                      - name of bootfile (if unknown, we use a default name
55
 *                        derived from our own IP address)
56
 *      We want:        - load the boot file
57
 *      Next step:      none
58
 */
59
 
60
#include "common.h"
61
#include "support.h"
62
#include "net.h"
63
#include "bootp.h"
64
#include "tftp.h"
65
#include "rarp.h"
66
#include "arp.h"
67
#if OC_LAN==1
68 140 julius
#include "eth.h"
69 406 julius
#else
70 246 julius
# if SMC91111_LAN==1
71
#  include "smc91111.h"
72
# endif
73 2 marcus.erl
#endif
74
 
75
#if 0
76
#define ET_DEBUG
77
#endif
78
 
79
/** BOOTP EXTENTIONS **/
80
 
81 406 julius
IPaddr_t NetOurSubnetMask = 0;   /* Our subnet mask (0=unknown)  */
82
IPaddr_t NetOurGatewayIP = 0;    /* Our gateways IP address      */
83
IPaddr_t NetOurDNSIP = 0;        /* Our DNS IP address           */
84
char NetOurNISDomain[32] = { 0, };       /* Our NIS domain               */
85
char NetOurHostName[32] = { 0, };        /* Our hostname                 */
86
char NetOurRootPath[64] = { 0, };        /* Our bootpath                 */
87 2 marcus.erl
 
88 406 julius
unsigned short NetBootFileSize = 0;      /* Our bootfile size in blocks  */
89
 
90 2 marcus.erl
/** END OF BOOTP EXTENTIONS **/
91
 
92 406 julius
unsigned long NetBootFileXferSize;      /* The actual transferred size
93
                                           of the bootfile (in bytes)   */
94
unsigned char NetOurEther[6];   /* Our ethernet address                 */
95
unsigned char NetServerEther[6] =       /* Boot server enet address     */
96
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
97 2 marcus.erl
 
98 406 julius
IPaddr_t NetOurIP;              /* Our IP addr (0 = unknown)            */
99
IPaddr_t NetServerIP;           /* Our IP addr (0 = unknown)            */
100
volatile unsigned char *NetRxPkt;       /* Current receive packet       */
101
int NetRxPktLen;                /* Current rx packet length             */
102
unsigned NetIPID;               /* IP packet ID                         */
103
unsigned char NetBcastAddr[6] = /* Ethernet bcast address               */
104
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
105 2 marcus.erl
 
106 406 julius
int NetState;                   /* Network loop state                   */
107 2 marcus.erl
 
108 406 julius
char BootFile[128];             /* Boot File name                       */
109 2 marcus.erl
 
110 406 julius
volatile unsigned char PktBuf[(PKTBUFSRX + 1) * PKTSIZE_ALIGN + PKTALIGN];
111 2 marcus.erl
 
112 406 julius
volatile unsigned char *NetRxPackets[PKTBUFSRX];      /* Receive packets*/
113 2 marcus.erl
 
114 406 julius
static rxhand_f *packetHandler; /* Current RX packet handler            */
115
static thand_f *timeHandler;    /* Current timeout handler              */
116
static unsigned long timeValue; /* Current timeout value                */
117
volatile unsigned char *NetTxPacket = 0; /* THE transmit packet  */
118
 
119
static int net_check_prereq(proto_t protocol);
120
 
121 2 marcus.erl
/**********************************************************************/
122
/*
123
 *      Main network processing loop.
124
 */
125 406 julius
int NetLoop(proto_t protocol)
126 2 marcus.erl
{
127 405 julius
 
128 406 julius
        if (!NetTxPacket) {
129
                int i;
130
                printf("NetTxPacket begin setup\n");
131
                /*
132
                 *  Setup packet buffers, aligned correctly.
133
                 */
134
                NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
135
                NetTxPacket -= (unsigned long)NetTxPacket % PKTALIGN;
136
                for (i = 0; i < PKTBUFSRX; i++) {
137
                        NetRxPackets[i] = NetTxPacket + (i + 1) * PKTSIZE_ALIGN;
138
                }
139
        }
140 2 marcus.erl
 
141 406 julius
        eth_halt();
142
        eth_init(NetReceive);
143 2 marcus.erl
 
144 406 julius
restart:
145 2 marcus.erl
 
146 406 julius
        NetCopyEther(NetOurEther, global.eth_add);
147 2 marcus.erl
 
148 406 julius
        NetState = NETLOOP_CONTINUE;
149 2 marcus.erl
 
150 406 julius
        /*
151
         *    Start the ball rolling with the given start function.  From
152
         *    here on, this code is a state machine driven by received
153
         *    packets and timer events.
154
         */
155 2 marcus.erl
 
156 406 julius
        if (protocol == TFTP) { /* TFTP */
157
                NetOurIP = global.ip;
158
                NetServerIP = global.srv_ip;
159
                NetOurGatewayIP = global.gw_ip;
160
                NetOurSubnetMask = global.mask;
161 2 marcus.erl
 
162 406 julius
                if (net_check_prereq(protocol) != 0) {
163
                        return 0;
164
                }
165 2 marcus.erl
 
166 406 julius
                /* always use ARP to get server ethernet address */
167
                ArpTry = 0;
168 2 marcus.erl
 
169 406 julius
                ArpRequest();
170 2 marcus.erl
 
171
#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
172 406 julius
        } else if (protocol == DHCP) {
173
                if (net_check_prereq(protocol) != 0) {
174
                        return 0;
175
                }
176 2 marcus.erl
 
177 406 julius
                /* Start with a clean slate... */
178
                NetOurIP = 0;
179
                NetServerIP = 0;
180
                DhcpRequest();  /* Basically same as BOOTP */
181 2 marcus.erl
 
182 406 julius
#endif /* CFG_CMD_DHCP */
183 2 marcus.erl
 
184 406 julius
        } else {                /* BOOTP or RARP */
185 2 marcus.erl
 
186 406 julius
                /*
187
                 * initialize our IP addr to 0 in order to accept ANY
188
                 * IP addr assigned to us by the BOOTP / RARP server
189
                 */
190
                NetOurIP = 0;
191
                NetServerIP = 0;
192 2 marcus.erl
 
193 406 julius
                if (net_check_prereq(protocol) != 0) {
194
                        return 0;
195
                }
196 2 marcus.erl
#ifdef BOOTP
197 406 julius
                if (protocol == BOOTP) {
198
                        BootpTry = 0;
199
                        BootpRequest();
200
                }
201 2 marcus.erl
#endif
202
#ifdef RARP
203 406 julius
                if {
204
                        RarpTry
205
                                = 0;
206
                        RarpRequest();
207
                }
208 2 marcus.erl
#endif
209 406 julius
        }
210 2 marcus.erl
 
211 406 julius
        NetBootFileXferSize = 0;
212 2 marcus.erl
 
213 406 julius
        /*
214
         *    Main packet reception loop.  Loop receiving packets until
215
         *    someone sets `NetQuit'.
216
         */
217
        for (;;) {
218
                //          WATCHDOG_RESET();
219
                /*
220
                 *  Check the ethernet for a new packet.  The ethernet
221
                 *  receive routine will process it.
222
                 */
223
                eth_rx();
224 2 marcus.erl
 
225 406 julius
                /*
226
                 *  Abort if ctrl-c was pressed.
227
                 */
228
                if (ctrlc()) {
229
                        eth_halt();
230
                        printf("\nAbort\n");
231
                        return 0;
232
                }
233 2 marcus.erl
 
234 406 julius
                /*
235
                 *  Check for a timeout, and run the timeout handler
236
                 *  if we have one.
237
                 */
238
                /*
239
                   if (timeHandler && (get_timer(0) > timeValue)) {
240
                   thand_f *x;
241 2 marcus.erl
 
242 406 julius
                   x = timeHandler;
243
                   timeHandler = (thand_f *)0;
244
                   (*x)();
245
                   }
246
                 */
247 2 marcus.erl
 
248 406 julius
                switch (NetState) {
249 2 marcus.erl
 
250 406 julius
                case NETLOOP_RESTART:
251
                        goto restart;
252 2 marcus.erl
 
253 406 julius
                case NETLOOP_SUCCESS:
254
                        if (NetBootFileXferSize > 0) {
255
                                printf("Bytes transferred = %ld (0x%lx)\n",
256
                                       NetBootFileXferSize,
257
                                       NetBootFileXferSize);
258 140 julius
#ifdef TFTP_CALC_CHKSUM
259 406 julius
                                printf("CHKSUM: 0x%lx\n", TFTP_CHKSUM);
260 140 julius
#endif
261 406 julius
                        }
262
                        eth_halt();
263
                        return NetBootFileXferSize;
264 2 marcus.erl
 
265 406 julius
                case NETLOOP_FAIL:
266
                        return 0;
267
                }
268
        }
269 405 julius
 
270 2 marcus.erl
}
271
 
272
/**********************************************************************/
273
 
274
#if 1
275 406 julius
void NetStartAgain(void)
276 2 marcus.erl
{
277 406 julius
        NetState = NETLOOP_RESTART;
278 2 marcus.erl
}
279
 
280
/**********************************************************************/
281
/*
282
 *      Miscelaneous bits.
283
 */
284
 
285 406 julius
void NetSetHandler(rxhand_f * f)
286 2 marcus.erl
{
287 406 julius
        packetHandler = f;
288 2 marcus.erl
}
289
 
290 406 julius
void NetSetTimeout(int iv, thand_f * f)
291 2 marcus.erl
{
292 406 julius
        if (iv == 0) {
293
                timeHandler = (thand_f *) 0;
294
        } else {
295
                timeHandler = f;
296
                timeValue = get_timer(0) + iv;
297
        }
298 2 marcus.erl
}
299
 
300 406 julius
void NetSendPacket(volatile unsigned char *pkt, int len)
301 2 marcus.erl
{
302
 
303
#if OC_LAN==1
304 406 julius
        unsigned char *p = (unsigned char *)0;
305
        while (p == (unsigned char *)0)
306
                p = eth_get_tx_buf();
307
 
308
        memcpy(p, (void *)pkt, len);
309
        eth_send(p, len);
310 246 julius
#else
311
# if  SMC91111_LAN==1
312 406 julius
        eth_send(pkt, len);
313 246 julius
# endif
314 2 marcus.erl
#endif
315
}
316
 
317 406 julius
void NetReceive(volatile unsigned char *pkt, int len)
318 2 marcus.erl
{
319 406 julius
        Ethernet_t *et;
320
        IP_t *ip;
321
        ARP_t *arp;
322
        int x;
323
        IPaddr_t ip_to_check;   // Used as a temp variable to check IP
324 2 marcus.erl
 
325 406 julius
        NetRxPkt = pkt;
326
        NetRxPktLen = len;
327
        et = (Ethernet_t *) pkt;
328 2 marcus.erl
 
329 406 julius
        x = SWAP16(et->et_protlen);
330 2 marcus.erl
 
331 406 julius
        if (x < 1514) {
332
                /*
333
                 *  Got a 802 packet.  Check the other protocol field.
334
                 */
335
                x = SWAP16(et->et_prot);
336
                ip = (IP_t *) (pkt + E802_HDR_SIZE);
337
                len -= E802_HDR_SIZE;
338
        } else {
339
                ip = (IP_t *) (pkt + ETHER_HDR_SIZE);
340
                len -= ETHER_HDR_SIZE;
341
        }
342 2 marcus.erl
 
343
#ifdef ET_DEBUG
344 406 julius
        printf("Receive from protocol 0x%x\n", x);
345 2 marcus.erl
#endif
346
 
347 406 julius
        switch (x) {
348 2 marcus.erl
 
349 406 julius
        case PROT_ARP:
350
                /*
351
                 * We have to deal with two types of ARP packets:
352
                 * - REQUEST packets will be answered by sending  our
353
                 *   IP address - if we know it.
354
                 * - REPLY packates are expected only after we asked
355
                 *   for the TFTP server's or the gateway's ethernet
356
                 *   address; so if we receive such a packet, we set
357
                 *   the server ethernet address
358
                 */
359 2 marcus.erl
#ifdef ET_DEBUG
360 406 julius
                printf("Got ARP\n");
361 2 marcus.erl
#endif
362 406 julius
                arp = (ARP_t *) ip;
363
                if (len < ARP_HDR_SIZE) {
364
                        printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
365
                        return;
366
                }
367
                if (SWAP16(arp->ar_hrd) != ARP_ETHER) {
368
                        return;
369
                }
370
                if (SWAP16(arp->ar_pro) != PROT_IP) {
371
                        return;
372
                }
373
                if (arp->ar_hln != 6) {
374
                        return;
375
                }
376
                if (arp->ar_pln != 4) {
377
                        return;
378
                }
379 2 marcus.erl
 
380 406 julius
                memcpy((void *)&ip_to_check, (void *)&arp->ar_data[16],
381
                       sizeof(IPaddr_t));
382
                if (NetOurIP == 0 || ip_to_check != NetOurIP) {
383
                        return;
384
                }
385
 
386
                switch (SWAP16(arp->ar_op)) {
387
                case ARPOP_REQUEST:     /* reply with our IP address  */
388 2 marcus.erl
#ifdef ET_DEBUG
389 406 julius
                        printf("Got ARP REQUEST, return our IP\n");
390 2 marcus.erl
#endif
391 406 julius
                        NetSetEther((unsigned char *)et, et->et_src, PROT_ARP);
392
                        arp->ar_op = SWAP16(ARPOP_REPLY);
393
                        NetCopyEther(&arp->ar_data[10], &arp->ar_data[0]);
394
                        NetCopyEther(&arp->ar_data[0], NetOurEther);
395
                        //*(IPaddr_t *)(&arp->ar_data[16]) = *(IPaddr_t *)(&arp->ar_data[6]);
396
                        memcpy((void *)&arp->ar_data[16],
397
                               (void *)&arp->ar_data[6], sizeof(IPaddr_t));
398
                        //*(IPaddr_t *)(&arp->ar_data[6]) = NetOurIP;
399
                        memcpy((void *)&arp->ar_data[6], (void *)&NetOurIP,
400
                               sizeof(IPaddr_t));
401
 
402
                        NetSendPacket((unsigned char *)et,
403
                                      ((unsigned char *)arp - pkt) +
404
                                      ARP_HDR_SIZE);
405
                        return;
406
                case ARPOP_REPLY:       /* set TFTP server eth addr     */
407 2 marcus.erl
#ifdef ET_DEBUG
408 406 julius
                        printf("Got ARP REPLY, set server/gtwy eth addr\n");
409 2 marcus.erl
#endif
410 406 julius
                        NetCopyEther(NetServerEther, &arp->ar_data[0]);
411
                        (*packetHandler) (0, 0, 0, 0);      /* start TFTP */
412
                        return;
413
                default:
414 2 marcus.erl
#ifdef ET_DEBUG
415 406 julius
                        printf("Unexpected ARP opcode 0x%x\n",
416
                               SWAP16(arp->ar_op));
417 2 marcus.erl
#endif
418 406 julius
                        return;
419
                }
420 2 marcus.erl
 
421 406 julius
        case PROT_RARP:
422 2 marcus.erl
#ifdef ET_DEBUG
423 406 julius
                printf("Got RARP\n");
424 2 marcus.erl
#endif
425 406 julius
                arp = (ARP_t *) ip;
426
                if (len < ARP_HDR_SIZE) {
427
                        printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
428
                        return;
429
                }
430 2 marcus.erl
 
431 406 julius
                if ((SWAP16(arp->ar_op) != RARPOP_REPLY) ||
432
                    (SWAP16(arp->ar_hrd) != ARP_ETHER) ||
433
                    (SWAP16(arp->ar_pro) != PROT_IP) ||
434
                    (arp->ar_hln != 6) || (arp->ar_pln != 4)) {
435 2 marcus.erl
 
436 406 julius
                        printf("invalid RARP header\n");
437
                } else {
438
                        //NetOurIP = *((IPaddr_t *)&arp->ar_data[16]);
439
                        memcpy((void *)&NetOurIP, (void *)&arp->ar_data[16],
440
                               sizeof(IPaddr_t));
441
                        //NetServerIP = *((IPaddr_t *)&arp->ar_data[6]);
442
                        memcpy((void *)&NetServerIP, (void *)&arp->ar_data[6],
443
                               sizeof(IPaddr_t));
444 2 marcus.erl
 
445 406 julius
                        NetCopyEther(NetServerEther, &arp->ar_data[0]);
446 2 marcus.erl
 
447 406 julius
                        (*packetHandler) (0, 0, 0, 0);
448
                }
449
                break;
450 140 julius
 
451 406 julius
        case PROT_IP:
452 2 marcus.erl
#ifdef ET_DEBUG
453 406 julius
                printf("Got IP\n");
454 2 marcus.erl
#endif
455 406 julius
                if (len < IP_HDR_SIZE) {
456
                        debug("ip header len bad %d < %d\n", len, IP_HDR_SIZE);
457
                        return;
458
                }
459
                if (len < SWAP16(ip->ip_len)) {
460
                        printf("ip header (swap) len bad %d < %d\n", len,
461
                               SWAP16(ip->ip_len));
462
                        return;
463
                }
464
                len = SWAP16(ip->ip_len);
465 2 marcus.erl
#ifdef ET_DEBUG
466 406 julius
                printf("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff);
467 2 marcus.erl
#endif
468 406 julius
                if ((ip->ip_hl_v & 0xf0) != 0x40) {
469
                        return;
470
                }
471
                if (ip->ip_off & SWAP16c(0x1fff)) {     /* Can't deal w/ fragments */
472
                        return;
473
                }
474
                if (!NetCksumOk((unsigned char *)ip, IP_HDR_SIZE_NO_UDP / 2)) {
475
                        //printf("checksum bad\n");
476
                        return;
477
                }
478 2 marcus.erl
 
479 406 julius
                memcpy((void *)&ip_to_check, (void *)&ip->ip_dst,
480
                       sizeof(IPaddr_t));
481 2 marcus.erl
 
482 406 julius
                if (NetOurIP &&
483
                    ip_to_check != NetOurIP && ip_to_check != 0xFFFFFFFF) {
484
                        return;
485
                }
486
                /*
487
                 * watch for ICMP host redirects
488
                 *
489
                 * There is no real handler code (yet). We just watch
490
                 * for ICMP host redirect messages. In case anybody
491
                 * sees these messages: please contact me
492
                 * (wd@denx.de), or - even better - send me the
493
                 * necessary fixes :-)
494
                 *
495
                 * Note: in all cases where I have seen this so far
496
                 * it was a problem with the router configuration,
497
                 * for instance when a router was configured in the
498
                 * BOOTP reply, but the TFTP server was on the same
499
                 * subnet. So this is probably a warning that your
500
                 * configuration might be wrong. But I'm not really
501
                 * sure if there aren't any other situations.
502
                 */
503
                if (ip->ip_p == IPPROTO_ICMP) {
504
                        ICMP_t *icmph = (ICMP_t *) & (ip->udp_src);
505 2 marcus.erl
 
506 406 julius
                        if (icmph->type != ICMP_REDIRECT)
507
                                return;
508
                        if (icmph->code != ICMP_REDIR_HOST)
509
                                return;
510
                        printf(" ICMP Host Redirect to ");
511
                        print_IPaddr(icmph->un.gateway);
512
                        putc(' ');
513
                } else if (ip->ip_p != IPPROTO_UDP) {   /* Only UDP packets */
514
                        return;
515
                }
516 140 julius
 
517 406 julius
                /*
518
                 *  IP header OK.  Pass the packet to the current handler.
519
                 */
520
                (*packetHandler) ((unsigned char *)ip + IP_HDR_SIZE,
521
                                  SWAP16(ip->udp_dst),
522
                                  SWAP16(ip->udp_src), SWAP16(ip->udp_len) - 8);
523 140 julius
 
524 406 julius
                break;
525
        }
526 2 marcus.erl
}
527
 
528
/**********************************************************************/
529
 
530 406 julius
static int net_check_prereq(proto_t protocol)
531 2 marcus.erl
{
532 406 julius
        switch (protocol) {
533
        case ARP:               /* nothing to do */
534
                break;
535 2 marcus.erl
 
536 406 julius
        case TFTP:
537
                if (NetServerIP == 0) {
538
                        printf("*** ERROR: `serverip' not set\n");
539
                        return (1);
540
                }
541 2 marcus.erl
 
542 406 julius
                if (NetOurIP == 0) {
543
                        printf("*** ERROR: `ipaddr' not set\n");
544
                        return (1);
545
                }
546
                /* Fall through */
547 2 marcus.erl
 
548 406 julius
        case DHCP:
549
        case RARP:
550
        case BOOTP:
551
                if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) {
552
                        printf("*** ERROR: `ethaddr' not set\n");
553
                        return (1);
554
                }
555
                /* Fall through */
556
        }
557
        return (0);              /* OK */
558 2 marcus.erl
}
559 406 julius
 
560 2 marcus.erl
/**********************************************************************/
561
 
562 406 julius
int NetCksumOk(unsigned char *ptr, int len)
563 2 marcus.erl
{
564 406 julius
        return !((NetCksum(ptr, len) + 1) & 0xfffe);
565 2 marcus.erl
}
566
 
567 406 julius
unsigned NetCksum(unsigned char *ptr, int len)
568 2 marcus.erl
{
569 406 julius
        unsigned long xsum;
570 2 marcus.erl
 
571 406 julius
        xsum = 0;
572
        while (len-- > 0) {
573
                xsum += (*((unsigned short *)ptr));
574
                ptr += sizeof(short);
575
        }
576
 
577
        xsum = (xsum & 0xffff) + (xsum >> 16);
578
        xsum = (xsum & 0xffff) + (xsum >> 16);
579
        return (xsum & 0xffff);
580 2 marcus.erl
}
581
 
582 406 julius
void NetCopyEther(volatile unsigned char *to, unsigned char *from)
583 2 marcus.erl
{
584 406 julius
        int i;
585 2 marcus.erl
 
586 406 julius
        for (i = 0; i < 6; i++)
587
                *to++ = *from++;
588 2 marcus.erl
}
589
 
590
void
591 406 julius
NetSetEther(volatile unsigned char *xet, unsigned char *addr,
592
            unsigned long prot)
593 2 marcus.erl
{
594 406 julius
        volatile Ethernet_t *et = (Ethernet_t *) xet;
595 2 marcus.erl
 
596 406 julius
        NetCopyEther(et->et_dest, addr);
597
        NetCopyEther(et->et_src, NetOurEther);
598
        et->et_protlen = SWAP16(prot);
599 2 marcus.erl
}
600
 
601
void
602 406 julius
NetSetIP(volatile unsigned char *xip, IPaddr_t dest, int dport, int sport,
603
         int len)
604 2 marcus.erl
{
605 406 julius
        volatile IP_t *ip = (IP_t *) xip;
606 2 marcus.erl
 
607 406 julius
        /*
608
         *    If the data is an odd number of bytes, zero the
609
         *    byte after the last byte so that the checksum
610
         *    will work.
611
         */
612
        if (len & 1)
613
                xip[IP_HDR_SIZE + len] = 0;
614 2 marcus.erl
 
615 406 julius
        /*
616
         *    Construct an IP and UDP header.
617
         (need to set no fragment bit - XXX)
618
         */
619
        ip->ip_hl_v = 0x45;     /* IP_HDR_SIZE / 4 (not including UDP) */
620
        ip->ip_tos = 0;
621
        ip->ip_len = SWAP16(IP_HDR_SIZE + len);
622
        ip->ip_id = SWAP16(NetIPID++);
623
        ip->ip_off = SWAP16c(0x4000);   /* No fragmentation */
624
        ip->ip_ttl = 255;
625
        ip->ip_p = 17;          /* UDP */
626
        ip->ip_sum = 0;
627
        //ip->ip_src   = NetOurIP;
628
        memcpy((void *)&ip->ip_src, (void *)&NetOurIP, sizeof(IPaddr_t));
629
        //ip->ip_dst   = dest;
630
        memcpy((void *)&ip->ip_dst, (void *)&dest, sizeof(IPaddr_t));
631
        ip->udp_src = SWAP16(sport);
632
        ip->udp_dst = SWAP16(dport);
633
        ip->udp_len = SWAP16(8 + len);
634
        ip->udp_xsum = 0;
635
        ip->ip_sum = ~NetCksum((unsigned char *)ip, IP_HDR_SIZE_NO_UDP / 2);
636 2 marcus.erl
}
637
 
638 406 julius
void copy_filename(unsigned char *dst, unsigned char *src, int size)
639 2 marcus.erl
{
640 406 julius
        if (*src && (*src == '"')) {
641
                ++src;
642
                --size;
643
        }
644 2 marcus.erl
 
645 406 julius
        while ((--size > 0) && *src && (*src != '"')) {
646
                *dst++ = *src++;
647
        }
648
        *dst = '\0';
649 2 marcus.erl
}
650
 
651 406 julius
void ip_to_string(IPaddr_t x, char *s)
652 2 marcus.erl
{
653 406 julius
        char num[] = "0123456789ABCDEF";
654
        int i;
655 2 marcus.erl
 
656 406 julius
        x = SWAP32(x);
657
 
658
        for (i = 28; i >= 0; i -= 4)
659
                *s++ = num[((x >> i) & 0x0f)];
660
        *s = 0;
661 2 marcus.erl
}
662
 
663 406 julius
void print_IPaddr(IPaddr_t x)
664 2 marcus.erl
{
665 406 julius
        char tmp[12];
666 2 marcus.erl
 
667 406 julius
        ip_to_string(x, tmp);
668 2 marcus.erl
 
669 406 julius
        printf(tmp);
670 2 marcus.erl
}
671
 
672 406 julius
static unsigned int i2a(char *dest, unsigned int x)
673
{
674
        register unsigned int tmp = x;
675
        register unsigned int len = 0;
676
        if (x >= 100) {
677
                *dest++ = tmp / 100 + '0';
678
                tmp = tmp % 100;
679
                ++len;
680
        }
681
        if (x >= 10) {
682
                *dest++ = tmp / 10 + '0';
683
                tmp = tmp % 10;
684
                ++len;
685
        }
686
        *dest++ = tmp + '0';
687
        return len + 1;
688 2 marcus.erl
}
689
 
690 406 julius
char *inet_ntoa(unsigned long in)
691
{
692
        static char buf[20];
693
        unsigned int len;
694
        unsigned char *ip = (unsigned char *)&in;
695 2 marcus.erl
 
696 406 julius
        len = i2a(buf, ip[0]);
697
        buf[len] = '.';
698
        ++len;
699
        len += i2a(buf + len, ip[1]);
700
        buf[len] = '.';
701
        ++len;
702
        len += i2a(buf + len, ip[2]);
703
        buf[len] = '.';
704
        ++len;
705
        len += i2a(buf + len, ip[3]);
706
        buf[len] = 0;
707
        return buf;
708 2 marcus.erl
}
709
 
710
unsigned long inet_aton(const char *cp)
711
{
712 406 julius
        unsigned long a[4];
713
        unsigned long ret;
714
        char *p = (char *)cp;
715
        int i, d;
716
        if (strcmp(cp, "255.255.255.255") == 0)
717
                return -1;
718 2 marcus.erl
 
719 406 julius
        for (i = 0; i < 4; i++) {
720
                a[i] = strtoul(p, 0, 0);
721
                for (d = 1; (p[d] != '.') && (i < 3); d++) ;
722
                p = &p[d + 1];
723
        }
724
 
725
        ret = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3];
726
        return ret;
727 2 marcus.erl
}
728
 
729
#endif

powered by: WebSVN 2.1.0

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