uboot/include/net.h
<<
>>
Prefs
   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 */
  42typedef 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 */
  53typedef 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 */
  67typedef 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 */
  73typedef void    thand_f(void);
  74
  75enum eth_state_t {
  76        ETH_STATE_INIT,
  77        ETH_STATE_PASSIVE,
  78        ETH_STATE_ACTIVE
  79};
  80
  81struct 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
 100extern int eth_initialize(bd_t *bis);   /* Initialize network subsystem */
 101extern int eth_register(struct eth_device* dev);/* Register network device */
 102extern int eth_unregister(struct eth_device *dev);/* Remove network device */
 103extern void eth_try_another(int first_restart); /* Change the device */
 104extern void eth_set_current(void);              /* set nterface to ethcur var */
 105/* get the current device MAC */
 106static inline __attribute__((always_inline))
 107struct eth_device *eth_get_dev(void)
 108{
 109        extern struct eth_device *eth_current;
 110
 111        return eth_current;
 112}
 113extern struct eth_device *eth_get_dev_by_name(const char *devname);
 114extern struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */
 115extern int eth_get_dev_index(void);             /* get the device index */
 116extern void eth_parse_enetaddr(const char *addr, uchar *enetaddr);
 117extern int eth_getenv_enetaddr(char *name, uchar *enetaddr);
 118extern 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 */
 129extern 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 */
 146extern void eth_random_enetaddr(uchar *enetaddr);
 147#endif
 148
 149extern int usb_eth_initialize(bd_t *bi);
 150extern int eth_init(bd_t *bis);                 /* Initialize the device */
 151extern int eth_send(void *packet, int length);     /* Send a packet */
 152
 153#ifdef CONFIG_API
 154extern int eth_receive(void *packet, int length); /* Receive a packet*/
 155extern void (*push_packet)(void *packet, int length);
 156#endif
 157extern int eth_rx(void);                        /* Check for received packets */
 158extern void eth_halt(void);                     /* stop SCC */
 159extern char *eth_get_name(void);                /* get name of current device */
 160
 161/* Set active state */
 162static 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 */
 169static 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 */
 183int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
 184                     int eth_number);
 185
 186#ifdef CONFIG_MCAST_TFTP
 187int eth_mcast_join(IPaddr_t mcast_addr, u8 join);
 188u32 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
 201struct 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
 210struct 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 */
 229struct 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 */
 251struct 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 */
 275struct 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 */
 298struct 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
 348struct 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 **/
 406extern IPaddr_t NetOurGatewayIP;        /* Our gateway IP address */
 407extern IPaddr_t NetOurSubnetMask;       /* Our subnet mask (0 = unknown) */
 408extern IPaddr_t NetOurDNSIP;    /* Our Domain Name Server (0 = unknown) */
 409#if defined(CONFIG_BOOTP_DNS2)
 410extern IPaddr_t NetOurDNS2IP;   /* Our 2nd Domain Name Server (0 = unknown) */
 411#endif
 412extern char     NetOurNISDomain[32];    /* Our NIS domain */
 413extern char     NetOurHostName[32];     /* Our hostname */
 414extern char     NetOurRootPath[64];     /* Our root path */
 415extern ushort   NetBootFileSize;        /* Our boot file size in blocks */
 416/** END OF BOOTP EXTENTIONS **/
 417extern ulong            NetBootFileXferSize;    /* size of bootfile in bytes */
 418extern uchar            NetOurEther[6];         /* Our ethernet address */
 419extern uchar            NetServerEther[6];      /* Boot server enet address */
 420extern IPaddr_t         NetOurIP;       /* Our    IP addr (0 = unknown) */
 421extern IPaddr_t         NetServerIP;    /* Server IP addr (0 = unknown) */
 422extern uchar            *NetTxPacket;           /* THE transmit packet */
 423extern uchar            *NetRxPackets[PKTBUFSRX]; /* Receive packets */
 424extern uchar            *NetRxPacket;           /* Current receive packet */
 425extern int              NetRxPacketLen;         /* Current rx packet length */
 426extern unsigned         NetIPID;                /* IP ID (counting) */
 427extern uchar            NetBcastAddr[6];        /* Ethernet boardcast address */
 428extern uchar            NetEtherNullAddr[6];
 429
 430#define VLAN_NONE       4095                    /* untagged */
 431#define VLAN_IDMASK     0x0fff                  /* mask of valid vlan id */
 432extern ushort           NetOurVLAN;             /* Our VLAN */
 433extern ushort           NetOurNativeVLAN;       /* Our Native VLAN */
 434
 435extern int              NetRestartWrap;         /* Tried all network devices */
 436
 437enum 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 */
 443extern char     BootFile[128];                  /* Boot File name */
 444
 445#if defined(CONFIG_CMD_DNS)
 446extern char *NetDNSResolve;             /* The host to resolve  */
 447extern char *NetDNSenvvar;              /* the env var to put the ip into */
 448#endif
 449
 450#if defined(CONFIG_CMD_PING)
 451extern 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 */
 456extern ushort CDPNativeVLAN;            /* CDP returned native VLAN */
 457extern ushort CDPApplianceVLAN;         /* CDP returned appliance VLAN */
 458
 459/*
 460 * Check for a CDP packet by examining the received MAC address field
 461 */
 462static 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)
 471extern IPaddr_t NetNtpServerIP;                 /* the ip address to NTP */
 472extern int NetTimeOffset;                       /* offset time from UTC */
 473#endif
 474
 475#if defined(CONFIG_MCAST_TFTP)
 476extern IPaddr_t Mcast_addr;
 477#endif
 478
 479/* Initialize the network adapter */
 480extern void net_init(void);
 481extern int NetLoop(enum proto_t);
 482
 483/* Shutdown adapters and cleanup */
 484extern void     NetStop(void);
 485
 486/* Load failed.  Start again. */
 487extern void     NetStartAgain(void);
 488
 489/* Get size of the ethernet header when we send */
 490extern int      NetEthHdrSize(void);
 491
 492/* Set ethernet header; returns the size of the header */
 493extern int NetSetEther(uchar *, uchar *, uint);
 494extern int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot);
 495
 496/* Set IP header */
 497extern void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source);
 498extern void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport,
 499                                int sport, int len);
 500
 501/* Checksum */
 502extern int      NetCksumOk(uchar *, int);       /* Return true if cksum OK */
 503extern uint     NetCksum(uchar *, int);         /* Calculate the checksum */
 504
 505/* Callbacks */
 506extern rxhand_f *net_get_udp_handler(void);     /* Get UDP RX packet handler */
 507extern void net_set_udp_handler(rxhand_f *);    /* Set UDP RX packet handler */
 508extern rxhand_f *net_get_arp_handler(void);     /* Get ARP RX packet handler */
 509extern void net_set_arp_handler(rxhand_f *);    /* Set ARP RX packet handler */
 510extern void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
 511extern void     NetSetTimeout(ulong, thand_f *);/* Set timeout handler */
 512
 513/* Network loop state */
 514enum net_loop_state {
 515        NETLOOP_CONTINUE,
 516        NETLOOP_RESTART,
 517        NETLOOP_SUCCESS,
 518        NETLOOP_FAIL
 519};
 520static 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 */
 529static 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 */
 544extern int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport,
 545                        int sport, int payload_len);
 546
 547/* Processes a received packet */
 548extern void NetReceive(uchar *, int);
 549
 550#ifdef CONFIG_NETCONSOLE
 551void NcStart(void);
 552int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port,
 553        unsigned src_port, unsigned len);
 554#endif
 555
 556static inline __attribute__((always_inline)) int eth_is_on_demand_init(void)
 557{
 558#ifdef CONFIG_NETCONSOLE
 559        extern enum proto_t net_loop_last_protocol;
 560
 561        return net_loop_last_protocol != NETCONS;
 562#else
 563        return 1;
 564#endif
 565}
 566
 567static inline void eth_set_last_protocol(int protocol)
 568{
 569#ifdef CONFIG_NETCONSOLE
 570        extern enum proto_t net_loop_last_protocol;
 571
 572        net_loop_last_protocol = protocol;
 573#endif
 574}
 575
 576/*
 577 * Check if autoload is enabled. If so, use either NFS or TFTP to download
 578 * the boot file.
 579 */
 580void net_auto_load(void);
 581
 582/*
 583 * The following functions are a bit ugly, but necessary to deal with
 584 * alignment restrictions on ARM.
 585 *
 586 * We're using inline functions, which had the smallest memory
 587 * footprint in our tests.
 588 */
 589/* return IP *in network byteorder* */
 590static inline IPaddr_t NetReadIP(void *from)
 591{
 592        IPaddr_t ip;
 593
 594        memcpy((void *)&ip, (void *)from, sizeof(ip));
 595        return ip;
 596}
 597
 598/* return ulong *in network byteorder* */
 599static inline ulong NetReadLong(ulong *from)
 600{
 601        ulong l;
 602
 603        memcpy((void *)&l, (void *)from, sizeof(l));
 604        return l;
 605}
 606
 607/* write IP *in network byteorder* */
 608static inline void NetWriteIP(void *to, IPaddr_t ip)
 609{
 610        memcpy(to, (void *)&ip, sizeof(ip));
 611}
 612
 613/* copy IP */
 614static inline void NetCopyIP(void *to, void *from)
 615{
 616        memcpy((void *)to, from, sizeof(IPaddr_t));
 617}
 618
 619/* copy ulong */
 620static inline void NetCopyLong(ulong *to, ulong *from)
 621{
 622        memcpy((void *)to, (void *)from, sizeof(ulong));
 623}
 624
 625/**
 626 * is_zero_ether_addr - Determine if give Ethernet address is all zeros.
 627 * @addr: Pointer to a six-byte array containing the Ethernet address
 628 *
 629 * Return true if the address is all zeroes.
 630 */
 631static inline int is_zero_ether_addr(const u8 *addr)
 632{
 633        return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
 634}
 635
 636/**
 637 * is_multicast_ether_addr - Determine if the Ethernet address is a multicast.
 638 * @addr: Pointer to a six-byte array containing the Ethernet address
 639 *
 640 * Return true if the address is a multicast address.
 641 * By definition the broadcast address is also a multicast address.
 642 */
 643static inline int is_multicast_ether_addr(const u8 *addr)
 644{
 645        return 0x01 & addr[0];
 646}
 647
 648/*
 649 * is_broadcast_ether_addr - Determine if the Ethernet address is broadcast
 650 * @addr: Pointer to a six-byte array containing the Ethernet address
 651 *
 652 * Return true if the address is the broadcast address.
 653 */
 654static inline int is_broadcast_ether_addr(const u8 *addr)
 655{
 656        return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) ==
 657                0xff;
 658}
 659
 660/*
 661 * is_valid_ether_addr - Determine if the given Ethernet address is valid
 662 * @addr: Pointer to a six-byte array containing the Ethernet address
 663 *
 664 * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
 665 * a multicast address, and is not FF:FF:FF:FF:FF:FF.
 666 *
 667 * Return true if the address is valid.
 668 */
 669static inline int is_valid_ether_addr(const u8 *addr)
 670{
 671        /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
 672         * explicitly check for it here. */
 673        return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
 674}
 675
 676/* Convert an IP address to a string */
 677extern void ip_to_string(IPaddr_t x, char *s);
 678
 679/* Convert a string to ip address */
 680extern IPaddr_t string_to_ip(const char *s);
 681
 682/* Convert a VLAN id to a string */
 683extern void VLAN_to_string(ushort x, char *s);
 684
 685/* Convert a string to a vlan id */
 686extern ushort string_to_VLAN(const char *s);
 687
 688/* read a VLAN id from an environment variable */
 689extern ushort getenv_VLAN(char *);
 690
 691/* copy a filename (allow for "..." notation, limit length) */
 692extern void copy_filename(char *dst, const char *src, int size);
 693
 694/* get a random source port */
 695extern unsigned int random_port(void);
 696
 697/**********************************************************************/
 698
 699#endif /* __NET_H__ */
 700