]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - include/net.h
net: Improve the speed of netconsole
[karo-tx-uboot.git] / include / net.h
1 /*
2  *      LiMon Monitor (LiMon) - Network.
3  *
4  *      Copyright 1994 - 2000 Neil Russell.
5  *      (See License)
6  *
7  *
8  * History
9  *      9/16/00   bor  adapted to TQM823L/STK8xxL board, RARP/TFTP boot added
10  */
11
12 #ifndef __NET_H__
13 #define __NET_H__
14
15 #if defined(CONFIG_8xx)
16 #include <commproc.h>
17 #endif  /* CONFIG_8xx */
18
19 #include <asm/cache.h>
20 #include <asm/byteorder.h>      /* for nton* / ntoh* stuff */
21
22 #define DEBUG_LL_STATE 0        /* Link local state machine changes */
23 #define DEBUG_DEV_PKT 0         /* Packets or info directed to the device */
24 #define DEBUG_NET_PKT 0         /* Packets on info on the network at large */
25 #define DEBUG_INT_STATE 0       /* Internal network state changes */
26
27 /*
28  *      The number of receive packet buffers, and the required packet buffer
29  *      alignment in memory.
30  *
31  */
32
33 #ifdef CONFIG_SYS_RX_ETH_BUFFER
34 # define PKTBUFSRX      CONFIG_SYS_RX_ETH_BUFFER
35 #else
36 # define PKTBUFSRX      4
37 #endif
38
39 #define PKTALIGN        ARCH_DMA_MINALIGN
40
41 /* IPv4 addresses are always 32 bits in size */
42 typedef u32             IPaddr_t;
43
44
45 /**
46  * An incoming packet handler.
47  * @param pkt    pointer to the application packet
48  * @param dport  destination UDP port
49  * @param sip    source IP address
50  * @param sport  source UDP port
51  * @param len    packet length
52  */
53 typedef void rxhand_f(uchar *pkt, unsigned dport,
54                       IPaddr_t sip, unsigned sport,
55                       unsigned len);
56
57 /**
58  * An incoming ICMP packet handler.
59  * @param type  ICMP type
60  * @param code  ICMP code
61  * @param dport destination UDP port
62  * @param sip   source IP address
63  * @param sport source UDP port
64  * @param pkt   pointer to the ICMP packet data
65  * @param len   packet length
66  */
67 typedef void rxhand_icmp_f(unsigned type, unsigned code, unsigned dport,
68                 IPaddr_t sip, unsigned sport, uchar *pkt, unsigned len);
69
70 /*
71  *      A timeout handler.  Called after time interval has expired.
72  */
73 typedef void    thand_f(void);
74
75 enum eth_state_t {
76         ETH_STATE_INIT,
77         ETH_STATE_PASSIVE,
78         ETH_STATE_ACTIVE
79 };
80
81 struct eth_device {
82         char name[16];
83         unsigned char enetaddr[6];
84         int iobase;
85         int state;
86
87         int  (*init) (struct eth_device *, bd_t *);
88         int  (*send) (struct eth_device *, void *packet, int length);
89         int  (*recv) (struct eth_device *);
90         void (*halt) (struct eth_device *);
91 #ifdef CONFIG_MCAST_TFTP
92         int (*mcast) (struct eth_device *, u32 ip, u8 set);
93 #endif
94         int  (*write_hwaddr) (struct eth_device *);
95         struct eth_device *next;
96         int index;
97         void *priv;
98 };
99
100 extern int eth_initialize(bd_t *bis);   /* Initialize network subsystem */
101 extern int eth_register(struct eth_device* dev);/* Register network device */
102 extern int eth_unregister(struct eth_device *dev);/* Remove network device */
103 extern void eth_try_another(int first_restart); /* Change the device */
104 extern void eth_set_current(void);              /* set nterface to ethcur var */
105 /* get the current device MAC */
106 static inline __attribute__((always_inline))
107 struct eth_device *eth_get_dev(void)
108 {
109         extern struct eth_device *eth_current;
110
111         return eth_current;
112 }
113 extern struct eth_device *eth_get_dev_by_name(const char *devname);
114 extern struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */
115 extern int eth_get_dev_index(void);             /* get the device index */
116 extern void eth_parse_enetaddr(const char *addr, uchar *enetaddr);
117 extern int eth_getenv_enetaddr(char *name, uchar *enetaddr);
118 extern int eth_setenv_enetaddr(char *name, const uchar *enetaddr);
119
120 /*
121  * Get the hardware address for an ethernet interface .
122  * Args:
123  *      base_name - base name for device (normally "eth")
124  *      index - device index number (0 for first)
125  *      enetaddr - returns 6 byte hardware address
126  * Returns:
127  *      Return true if the address is valid.
128  */
129 extern int eth_getenv_enetaddr_by_index(const char *base_name, int index,
130                                         uchar *enetaddr);
131
132 #ifdef CONFIG_RANDOM_MACADDR
133 /*
134  * The u-boot policy does not allow hardcoded ethernet addresses. Under the
135  * following circumstances a random generated address is allowed:
136  *  - in emergency cases, where you need a working network connection to set
137  *    the ethernet address.
138  *    Eg. you want a rescue boot and don't have a serial port to access the
139  *    CLI to set environment variables.
140  *
141  * In these cases, we generate a random locally administered ethernet address.
142  *
143  * Args:
144  *  enetaddr - returns 6 byte hardware address
145  */
146 extern void eth_random_enetaddr(uchar *enetaddr);
147 #endif
148
149 extern int usb_eth_initialize(bd_t *bi);
150 extern int eth_init(bd_t *bis);                 /* Initialize the device */
151 extern int eth_send(void *packet, int length);     /* Send a packet */
152
153 #ifdef CONFIG_API
154 extern int eth_receive(void *packet, int length); /* Receive a packet*/
155 extern void (*push_packet)(void *packet, int length);
156 #endif
157 extern int eth_rx(void);                        /* Check for received packets */
158 extern void eth_halt(void);                     /* stop SCC */
159 extern char *eth_get_name(void);                /* get name of current device */
160
161 /* Set active state */
162 static inline __attribute__((always_inline)) int eth_init_state_only(bd_t *bis)
163 {
164         eth_get_dev()->state = ETH_STATE_ACTIVE;
165
166         return 0;
167 }
168 /* Set passive state */
169 static inline __attribute__((always_inline)) void eth_halt_state_only(void)
170 {
171         eth_get_dev()->state = ETH_STATE_PASSIVE;
172 }
173
174 /*
175  * Set the hardware address for an ethernet interface based on 'eth%daddr'
176  * environment variable (or just 'ethaddr' if eth_number is 0).
177  * Args:
178  *      base_name - base name for device (normally "eth")
179  *      eth_number - value of %d (0 for first device of this type)
180  * Returns:
181  *      0 is success, non-zero is error status from driver.
182  */
183 int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
184                      int eth_number);
185
186 #ifdef CONFIG_MCAST_TFTP
187 int eth_mcast_join(IPaddr_t mcast_addr, u8 join);
188 u32 ether_crc(size_t len, unsigned char const *p);
189 #endif
190
191
192 /**********************************************************************/
193 /*
194  *      Protocol headers.
195  */
196
197 /*
198  *      Ethernet header
199  */
200
201 struct ethernet_hdr {
202         uchar           et_dest[6];     /* Destination node             */
203         uchar           et_src[6];      /* Source node                  */
204         ushort          et_protlen;     /* Protocol or length           */
205 };
206
207 /* Ethernet header size */
208 #define ETHER_HDR_SIZE  (sizeof(struct ethernet_hdr))
209
210 struct e802_hdr {
211         uchar           et_dest[6];     /* Destination node             */
212         uchar           et_src[6];      /* Source node                  */
213         ushort          et_protlen;     /* Protocol or length           */
214         uchar           et_dsap;        /* 802 DSAP                     */
215         uchar           et_ssap;        /* 802 SSAP                     */
216         uchar           et_ctl;         /* 802 control                  */
217         uchar           et_snap1;       /* SNAP                         */
218         uchar           et_snap2;
219         uchar           et_snap3;
220         ushort          et_prot;        /* 802 protocol                 */
221 };
222
223 /* 802 + SNAP + ethernet header size */
224 #define E802_HDR_SIZE   (sizeof(struct e802_hdr))
225
226 /*
227  *      Virtual LAN Ethernet header
228  */
229 struct vlan_ethernet_hdr {
230         uchar           vet_dest[6];    /* Destination node             */
231         uchar           vet_src[6];     /* Source node                  */
232         ushort          vet_vlan_type;  /* PROT_VLAN                    */
233         ushort          vet_tag;        /* TAG of VLAN                  */
234         ushort          vet_type;       /* protocol type                */
235 };
236
237 /* VLAN Ethernet header size */
238 #define VLAN_ETHER_HDR_SIZE     (sizeof(struct vlan_ethernet_hdr))
239
240 #define PROT_IP         0x0800          /* IP protocol                  */
241 #define PROT_ARP        0x0806          /* IP ARP protocol              */
242 #define PROT_RARP       0x8035          /* IP ARP protocol              */
243 #define PROT_VLAN       0x8100          /* IEEE 802.1q protocol         */
244
245 #define IPPROTO_ICMP     1      /* Internet Control Message Protocol    */
246 #define IPPROTO_UDP     17      /* User Datagram Protocol               */
247
248 /*
249  *      Internet Protocol (IP) header.
250  */
251 struct ip_hdr {
252         uchar           ip_hl_v;        /* header length and version    */
253         uchar           ip_tos;         /* type of service              */
254         ushort          ip_len;         /* total length                 */
255         ushort          ip_id;          /* identification               */
256         ushort          ip_off;         /* fragment offset field        */
257         uchar           ip_ttl;         /* time to live                 */
258         uchar           ip_p;           /* protocol                     */
259         ushort          ip_sum;         /* checksum                     */
260         IPaddr_t        ip_src;         /* Source IP address            */
261         IPaddr_t        ip_dst;         /* Destination IP address       */
262 };
263
264 #define IP_OFFS         0x1fff /* ip offset *= 8 */
265 #define IP_FLAGS        0xe000 /* first 3 bits */
266 #define IP_FLAGS_RES    0x8000 /* reserved */
267 #define IP_FLAGS_DFRAG  0x4000 /* don't fragments */
268 #define IP_FLAGS_MFRAG  0x2000 /* more fragments */
269
270 #define IP_HDR_SIZE             (sizeof(struct ip_hdr))
271
272 /*
273  *      Internet Protocol (IP) + UDP header.
274  */
275 struct ip_udp_hdr {
276         uchar           ip_hl_v;        /* header length and version    */
277         uchar           ip_tos;         /* type of service              */
278         ushort          ip_len;         /* total length                 */
279         ushort          ip_id;          /* identification               */
280         ushort          ip_off;         /* fragment offset field        */
281         uchar           ip_ttl;         /* time to live                 */
282         uchar           ip_p;           /* protocol                     */
283         ushort          ip_sum;         /* checksum                     */
284         IPaddr_t        ip_src;         /* Source IP address            */
285         IPaddr_t        ip_dst;         /* Destination IP address       */
286         ushort          udp_src;        /* UDP source port              */
287         ushort          udp_dst;        /* UDP destination port         */
288         ushort          udp_len;        /* Length of UDP packet         */
289         ushort          udp_xsum;       /* Checksum                     */
290 };
291
292 #define IP_UDP_HDR_SIZE         (sizeof(struct ip_udp_hdr))
293 #define UDP_HDR_SIZE            (IP_UDP_HDR_SIZE - IP_HDR_SIZE)
294
295 /*
296  *      Address Resolution Protocol (ARP) header.
297  */
298 struct arp_hdr {
299         ushort          ar_hrd;         /* Format of hardware address   */
300 #   define ARP_ETHER        1           /* Ethernet  hardware address   */
301         ushort          ar_pro;         /* Format of protocol address   */
302         uchar           ar_hln;         /* Length of hardware address   */
303 #   define ARP_HLEN     6
304         uchar           ar_pln;         /* Length of protocol address   */
305 #   define ARP_PLEN     4
306         ushort          ar_op;          /* Operation                    */
307 #   define ARPOP_REQUEST    1           /* Request  to resolve  address */
308 #   define ARPOP_REPLY      2           /* Response to previous request */
309
310 #   define RARPOP_REQUEST   3           /* Request  to resolve  address */
311 #   define RARPOP_REPLY     4           /* Response to previous request */
312
313         /*
314          * The remaining fields are variable in size, according to
315          * the sizes above, and are defined as appropriate for
316          * specific hardware/protocol combinations.
317          */
318         uchar           ar_data[0];
319 #define ar_sha          ar_data[0]
320 #define ar_spa          ar_data[ARP_HLEN]
321 #define ar_tha          ar_data[ARP_HLEN + ARP_PLEN]
322 #define ar_tpa          ar_data[ARP_HLEN + ARP_PLEN + ARP_HLEN]
323 #if 0
324         uchar           ar_sha[];       /* Sender hardware address      */
325         uchar           ar_spa[];       /* Sender protocol address      */
326         uchar           ar_tha[];       /* Target hardware address      */
327         uchar           ar_tpa[];       /* Target protocol address      */
328 #endif /* 0 */
329 };
330
331 #define ARP_HDR_SIZE    (8+20)          /* Size assuming ethernet       */
332
333 /*
334  * ICMP stuff (just enough to handle (host) redirect messages)
335  */
336 #define ICMP_ECHO_REPLY         0       /* Echo reply                   */
337 #define ICMP_NOT_REACH          3       /* Detination unreachable       */
338 #define ICMP_REDIRECT           5       /* Redirect (change route)      */
339 #define ICMP_ECHO_REQUEST       8       /* Echo request                 */
340
341 /* Codes for REDIRECT. */
342 #define ICMP_REDIR_NET          0       /* Redirect Net                 */
343 #define ICMP_REDIR_HOST         1       /* Redirect Host                */
344
345 /* Codes for NOT_REACH */
346 #define ICMP_NOT_REACH_PORT     3       /* Port unreachable             */
347
348 struct icmp_hdr {
349         uchar           type;
350         uchar           code;
351         ushort          checksum;
352         union {
353                 struct {
354                         ushort  id;
355                         ushort  sequence;
356                 } echo;
357                 ulong   gateway;
358                 struct {
359                         ushort  __unused;
360                         ushort  mtu;
361                 } frag;
362                 uchar data[0];
363         } un;
364 };
365
366 #define ICMP_HDR_SIZE           (sizeof(struct icmp_hdr))
367 #define IP_ICMP_HDR_SIZE        (IP_HDR_SIZE + ICMP_HDR_SIZE)
368
369 /*
370  * Maximum packet size; used to allocate packet storage.
371  * TFTP packets can be 524 bytes + IP header + ethernet header.
372  * Lets be conservative, and go for 38 * 16.  (Must also be
373  * a multiple of 32 bytes).
374  */
375 /*
376  * AS.HARNOIS : Better to set PKTSIZE to maximum size because
377  * traffic type is not always controlled
378  * maximum packet size =  1518
379  * maximum packet size and multiple of 32 bytes =  1536
380  */
381 #define PKTSIZE                 1518
382 #define PKTSIZE_ALIGN           1536
383 /*#define PKTSIZE               608*/
384
385 /*
386  * Maximum receive ring size; that is, the number of packets
387  * we can buffer before overflow happens. Basically, this just
388  * needs to be enough to prevent a packet being discarded while
389  * we are processing the previous one.
390  */
391 #define RINGSZ          4
392 #define RINGSZ_LOG2     2
393
394 /**********************************************************************/
395 /*
396  *      Globals.
397  *
398  * Note:
399  *
400  * All variables of type IPaddr_t are stored in NETWORK byte order
401  * (big endian).
402  */
403
404 /* net.c */
405 /** BOOTP EXTENTIONS **/
406 extern IPaddr_t NetOurGatewayIP;        /* Our gateway IP address */
407 extern IPaddr_t NetOurSubnetMask;       /* Our subnet mask (0 = unknown) */
408 extern IPaddr_t NetOurDNSIP;    /* Our Domain Name Server (0 = unknown) */
409 #if defined(CONFIG_BOOTP_DNS2)
410 extern IPaddr_t NetOurDNS2IP;   /* Our 2nd Domain Name Server (0 = unknown) */
411 #endif
412 extern char     NetOurNISDomain[32];    /* Our NIS domain */
413 extern char     NetOurHostName[32];     /* Our hostname */
414 extern char     NetOurRootPath[64];     /* Our root path */
415 extern ushort   NetBootFileSize;        /* Our boot file size in blocks */
416 /** END OF BOOTP EXTENTIONS **/
417 extern ulong            NetBootFileXferSize;    /* size of bootfile in bytes */
418 extern uchar            NetOurEther[6];         /* Our ethernet address */
419 extern uchar            NetServerEther[6];      /* Boot server enet address */
420 extern IPaddr_t         NetOurIP;       /* Our    IP addr (0 = unknown) */
421 extern IPaddr_t         NetServerIP;    /* Server IP addr (0 = unknown) */
422 extern uchar            *NetTxPacket;           /* THE transmit packet */
423 extern uchar            *NetRxPackets[PKTBUFSRX]; /* Receive packets */
424 extern uchar            *NetRxPacket;           /* Current receive packet */
425 extern int              NetRxPacketLen;         /* Current rx packet length */
426 extern unsigned         NetIPID;                /* IP ID (counting) */
427 extern uchar            NetBcastAddr[6];        /* Ethernet boardcast address */
428 extern uchar            NetEtherNullAddr[6];
429
430 #define VLAN_NONE       4095                    /* untagged */
431 #define VLAN_IDMASK     0x0fff                  /* mask of valid vlan id */
432 extern ushort           NetOurVLAN;             /* Our VLAN */
433 extern ushort           NetOurNativeVLAN;       /* Our Native VLAN */
434
435 extern int              NetRestartWrap;         /* Tried all network devices */
436
437 enum proto_t {
438         BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
439         TFTPSRV, TFTPPUT, LINKLOCAL
440 };
441
442 /* from net/net.c */
443 extern char     BootFile[128];                  /* Boot File name */
444
445 #if defined(CONFIG_CMD_DNS)
446 extern char *NetDNSResolve;             /* The host to resolve  */
447 extern char *NetDNSenvvar;              /* the env var to put the ip into */
448 #endif
449
450 #if defined(CONFIG_CMD_PING)
451 extern IPaddr_t NetPingIP;                      /* the ip address to ping */
452 #endif
453
454 #if defined(CONFIG_CMD_CDP)
455 /* when CDP completes these hold the return values */
456 extern ushort CDPNativeVLAN;            /* CDP returned native VLAN */
457 extern ushort CDPApplianceVLAN;         /* CDP returned appliance VLAN */
458
459 /*
460  * Check for a CDP packet by examining the received MAC address field
461  */
462 static inline int is_cdp_packet(const uchar *et_addr)
463 {
464         extern const uchar NetCDPAddr[6];
465
466         return memcmp(et_addr, NetCDPAddr, 6) == 0;
467 }
468 #endif
469
470 #if defined(CONFIG_CMD_SNTP)
471 extern IPaddr_t NetNtpServerIP;                 /* the ip address to NTP */
472 extern int NetTimeOffset;                       /* offset time from UTC */
473 #endif
474
475 #if defined(CONFIG_MCAST_TFTP)
476 extern IPaddr_t Mcast_addr;
477 #endif
478
479 /* Initialize the network adapter */
480 extern void net_init(void);
481 extern int NetLoop(enum proto_t);
482
483 /* Shutdown adapters and cleanup */
484 extern void     NetStop(void);
485
486 /* Load failed.  Start again. */
487 extern void     NetStartAgain(void);
488
489 /* Get size of the ethernet header when we send */
490 extern int      NetEthHdrSize(void);
491
492 /* Set ethernet header; returns the size of the header */
493 extern int NetSetEther(uchar *, uchar *, uint);
494 extern int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot);
495
496 /* Set IP header */
497 extern void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source);
498 extern void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport,
499                                 int sport, int len);
500
501 /* Checksum */
502 extern int      NetCksumOk(uchar *, int);       /* Return true if cksum OK */
503 extern uint     NetCksum(uchar *, int);         /* Calculate the checksum */
504
505 /* Callbacks */
506 extern rxhand_f *net_get_udp_handler(void);     /* Get UDP RX packet handler */
507 extern void net_set_udp_handler(rxhand_f *);    /* Set UDP RX packet handler */
508 extern rxhand_f *net_get_arp_handler(void);     /* Get ARP RX packet handler */
509 extern void net_set_arp_handler(rxhand_f *);    /* Set ARP RX packet handler */
510 extern void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
511 extern void     NetSetTimeout(ulong, thand_f *);/* Set timeout handler */
512
513 /* Network loop state */
514 enum net_loop_state {
515         NETLOOP_CONTINUE,
516         NETLOOP_RESTART,
517         NETLOOP_SUCCESS,
518         NETLOOP_FAIL
519 };
520 static inline void net_set_state(enum net_loop_state state)
521 {
522         extern enum net_loop_state net_state;
523
524         debug_cond(DEBUG_INT_STATE, "--- NetState set to %d\n", state);
525         net_state = state;
526 }
527
528 /* Transmit a packet */
529 static inline void NetSendPacket(uchar *pkt, int len)
530 {
531         (void) eth_send(pkt, len);
532 }
533
534 /*
535  * Transmit "NetTxPacket" as UDP packet, performing ARP request if needed
536  *  (ether will be populated)
537  *
538  * @param ether Raw packet buffer
539  * @param dest IP address to send the datagram to
540  * @param dport Destination UDP port
541  * @param sport Source UDP port
542  * @param payload_len Length of data after the UDP header
543  */
544 extern int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport,
545                         int sport, int payload_len);
546
547 /* Processes a received packet */
548 extern void NetReceive(uchar *, int);
549
550 #ifdef CONFIG_NETCONSOLE
551 void NcStart(void);
552 int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len);
553 #endif
554
555 static inline __attribute__((always_inline)) int eth_is_on_demand_init(void)
556 {
557 #ifdef CONFIG_NETCONSOLE
558         extern enum proto_t net_loop_last_protocol;
559
560         return net_loop_last_protocol != NETCONS;
561 #else
562         return 1;
563 #endif
564 }
565
566 static inline void eth_set_last_protocol(int protocol)
567 {
568 #ifdef CONFIG_NETCONSOLE
569         extern enum proto_t net_loop_last_protocol;
570
571         net_loop_last_protocol = protocol;
572 #endif
573 }
574
575 /*
576  * Check if autoload is enabled. If so, use either NFS or TFTP to download
577  * the boot file.
578  */
579 void net_auto_load(void);
580
581 /*
582  * The following functions are a bit ugly, but necessary to deal with
583  * alignment restrictions on ARM.
584  *
585  * We're using inline functions, which had the smallest memory
586  * footprint in our tests.
587  */
588 /* return IP *in network byteorder* */
589 static inline IPaddr_t NetReadIP(void *from)
590 {
591         IPaddr_t ip;
592
593         memcpy((void *)&ip, (void *)from, sizeof(ip));
594         return ip;
595 }
596
597 /* return ulong *in network byteorder* */
598 static inline ulong NetReadLong(ulong *from)
599 {
600         ulong l;
601
602         memcpy((void *)&l, (void *)from, sizeof(l));
603         return l;
604 }
605
606 /* write IP *in network byteorder* */
607 static inline void NetWriteIP(void *to, IPaddr_t ip)
608 {
609         memcpy(to, (void *)&ip, sizeof(ip));
610 }
611
612 /* copy IP */
613 static inline void NetCopyIP(void *to, void *from)
614 {
615         memcpy((void *)to, from, sizeof(IPaddr_t));
616 }
617
618 /* copy ulong */
619 static inline void NetCopyLong(ulong *to, ulong *from)
620 {
621         memcpy((void *)to, (void *)from, sizeof(ulong));
622 }
623
624 /**
625  * is_zero_ether_addr - Determine if give Ethernet address is all zeros.
626  * @addr: Pointer to a six-byte array containing the Ethernet address
627  *
628  * Return true if the address is all zeroes.
629  */
630 static inline int is_zero_ether_addr(const u8 *addr)
631 {
632         return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
633 }
634
635 /**
636  * is_multicast_ether_addr - Determine if the Ethernet address is a multicast.
637  * @addr: Pointer to a six-byte array containing the Ethernet address
638  *
639  * Return true if the address is a multicast address.
640  * By definition the broadcast address is also a multicast address.
641  */
642 static inline int is_multicast_ether_addr(const u8 *addr)
643 {
644         return 0x01 & addr[0];
645 }
646
647 /*
648  * is_broadcast_ether_addr - Determine if the Ethernet address is broadcast
649  * @addr: Pointer to a six-byte array containing the Ethernet address
650  *
651  * Return true if the address is the broadcast address.
652  */
653 static inline int is_broadcast_ether_addr(const u8 *addr)
654 {
655         return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) ==
656                 0xff;
657 }
658
659 /*
660  * is_valid_ether_addr - Determine if the given Ethernet address is valid
661  * @addr: Pointer to a six-byte array containing the Ethernet address
662  *
663  * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
664  * a multicast address, and is not FF:FF:FF:FF:FF:FF.
665  *
666  * Return true if the address is valid.
667  */
668 static inline int is_valid_ether_addr(const u8 *addr)
669 {
670         /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
671          * explicitly check for it here. */
672         return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
673 }
674
675 /* Convert an IP address to a string */
676 extern void ip_to_string(IPaddr_t x, char *s);
677
678 /* Convert a string to ip address */
679 extern IPaddr_t string_to_ip(const char *s);
680
681 /* Convert a VLAN id to a string */
682 extern void VLAN_to_string(ushort x, char *s);
683
684 /* Convert a string to a vlan id */
685 extern ushort string_to_VLAN(const char *s);
686
687 /* read a VLAN id from an environment variable */
688 extern ushort getenv_VLAN(char *);
689
690 /* copy a filename (allow for "..." notation, limit length) */
691 extern void copy_filename(char *dst, const char *src, int size);
692
693 /* get a random source port */
694 extern unsigned int random_port(void);
695
696 /**********************************************************************/
697
698 #endif /* __NET_H__ */