IPv6 in FreeBSD/Linux

Linux Daemon Dienste

radvd

Router Advertisement Daemon (radvd) (wenn die Clients automatisch konfiguriert werden sollen)
Wikipedia: Router Advertisement Daemon (radvd), implements link-local advertisements of IPv6 router addresses and IPv6 routing prefixes using the Neighbor Discovery Protocol (NDP) => stateless autoconfiguration

NAT64

Wikipedia: NAT64
TAYGA
NAT64 Kernel Module
github.com/fln/nat64

link local fe80::
global unicase 2001:

/proc/sys/net/ipv6/conf
all   default   eth0   eth1   lo

/proc/sys/net/ipv6/conf/all/forwarding => 1

well-known prefix, z.B.
NAT64   64:ff9b::/96
ALG     Application Layer Gateway
RR      Resource Record

FreeBSD Subversion

Subversion Mirror Sites

FreeBSD VLAN

FreeBSD VLAN Configuration
FreeBSD – Adding VLAN Tagged subinterface using ifconfig

struct  vlanreq {
    char    vlr_parent[IFNAMSIZ];
    u_short vlr_tag;
};
Step 1: create the vlan subinterface
# ifconfig vlan122 create

Step 2: assign it a vlan ID and vlan device:
# ifconfig vlan122 vlan 122 vlandev em0

Step 3: check the vlan subinterface:
# ifconfig vlan122
vlan122: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 00:07:e9:a5:9b:fa
        media: Ethernet autoselect (1000baseTX <full-duplex>)
        status: active
        vlan: 122 parent interface: em0

Step 4: assign ip address:
# ifconfig vlan122 10.1.122.1/24
# ifconfig vlan122 up
# ifconfig vlan122
vlan122: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 00:07:e9:a5:9b:fa
        inet 10.1.122.1 netmask 0xffffff00 broadcast 10.1.122.255
        media: Ethernet autoselect (1000baseTX <full-duplex>)
        status: active
        vlan: 122 parent interface: em0

Or edit rc.conf:
cloned_interfaces="vlan0"
ifconfig_vlan0="inet x.x.x.x netmask y.y.y.y vlan 2 vlandev em0"

FreeBSD Manual Pages

getifaddrs — get interface addresses
ether_ntohost — Ethernet address conversion and lookup routines

FreeBSD Implementation

DEC Direct Data Link Interface (DLI)
How to know ip address for interfaces in c
Polling interface names via SIOCGIFCONF in Linux
Broadcasting and Determining Network Configuration
FreeBSD: network interface information
lo0 not in ioctl( SIOCGIFCONF )
SOLVED: lo0 not in ioctl( SIOCGIFCONF )
How to get IPv6 address using getifaddrs and which version of glibc supports
How can I enumerate the list of network devices or interfaces in C or C++ in FreeBSD? [duplicate]
Re: ioctl programming probs

getifaddrs.c

Linux:
struct ifreq {
    char ifr_name[IFNAMSIZ]; /* Interface name */
    union {
        struct sockaddr ifr_addr;
        struct sockaddr ifr_dstaddr;
        struct sockaddr ifr_broadaddr;
        struct sockaddr ifr_netmask;
        struct sockaddr ifr_hwaddr;
        short           ifr_flags;
        int             ifr_ifindex;
        int             ifr_metric;
        int             ifr_mtu;
        struct ifmap    ifr_map;
        char            ifr_slave[IFNAMSIZ];
        char            ifr_newname[IFNAMSIZ];
        char           *ifr_data;
    };
};

struct ifconf {
    int                 ifc_len; /* size of buffer */
    union {
        char           *ifc_buf; /* buffer address */
        struct ifreq   *ifc_req; /* array of structures */
    };
};

FreeBSD:

/*
 * Length of interface external name, including terminating '\0'.
 * Note: this is the same size as a generic device's external name.
 */
#define         IF_NAMESIZE     16
#if __BSD_VISIBLE
#define         IFNAMSIZ        IF_NAMESIZE
#define         IF_MAXUNIT      0x7fff  /* historical value */
#endif
#if __BSD_VISIBLE

/*
 * Interface request structure used for socket
 * ioctl's.  All interface ioctl's must have parameter
 * definitions which begin with ifr_name.  The
 * remainder may be interface specific.
 */
struct  ifreq {
        char    ifr_name[IFNAMSIZ];             /* if name, e.g. "en0" */
        union {
                struct  sockaddr ifru_addr;
                struct  sockaddr ifru_dstaddr;
                struct  sockaddr ifru_broadaddr;
                struct  ifreq_buffer ifru_buffer;
                short   ifru_flags[2];
                short   ifru_index;
                int     ifru_jid;
                int     ifru_metric;
                int     ifru_mtu;
                int     ifru_phys;
                int     ifru_media;
                caddr_t ifru_data;
                int     ifru_cap[2];
                u_int   ifru_fib;
        } ifr_ifru;
#define ifr_addr        ifr_ifru.ifru_addr      /* address */
#define ifr_dstaddr     ifr_ifru.ifru_dstaddr   /* other end of p-to-p link */
#define ifr_broadaddr   ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_buffer      ifr_ifru.ifru_buffer    /* user supplied buffer with its length */
#define ifr_flags       ifr_ifru.ifru_flags[0]  /* flags (low 16 bits) */
#define ifr_flagshigh   ifr_ifru.ifru_flags[1]  /* flags (high 16 bits) */
#define ifr_jid         ifr_ifru.ifru_jid       /* jail/vnet */
#define ifr_metric      ifr_ifru.ifru_metric    /* metric */
#define ifr_mtu         ifr_ifru.ifru_mtu       /* mtu */
#define ifr_phys        ifr_ifru.ifru_phys      /* physical wire */
#define ifr_media       ifr_ifru.ifru_media     /* physical media */
#define ifr_data        ifr_ifru.ifru_data      /* for use by interface */
#define ifr_reqcap      ifr_ifru.ifru_cap[0]    /* requested capabilities */
#define ifr_curcap      ifr_ifru.ifru_cap[1]    /* current capabilities */
#define ifr_index       ifr_ifru.ifru_index     /* interface index */
#define ifr_fib         ifr_ifru.ifru_fib       /* interface fib */
};


/*
 * Structure used in SIOCGIFCONF request.
 * Used to retrieve interface configuration
 * for machine (useful for programs which
 * must know all networks accessible).
 */
struct  ifconf {
        int     ifc_len;                /* size of associated buffer */
        union {
                caddr_t ifcu_buf;
                struct  ifreq *ifcu_req;
        } ifc_ifcu;
#define ifc_buf ifc_ifcu.ifcu_buf       /* buffer address */
#define ifc_req ifc_ifcu.ifcu_req       /* array of structures returned */
};

/*-
 * Interface flags are of two types: network stack owned flags, and driver
 * owned flags.  Historically, these values were stored in the same ifnet
 * flags field, but with the advent of fine-grained locking, they have been
 * broken out such that the network stack is responsible for synchronizing
 * the stack-owned fields, and the device driver the device-owned fields.
 * Both halves can perform lockless reads of the other half's field, subject
 * to accepting the involved races.
 *
 * Both sets of flags come from the same number space, and should not be
 * permitted to conflict, as they are exposed to user space via a single
 * field.
 *
 * The following symbols identify read and write requirements for fields:
 *
 * (i) if_flags field set by device driver before attach, read-only there
 *     after.
 * (n) if_flags field written only by the network stack, read by either the
 *     stack or driver.
 * (d) if_drv_flags field written only by the device driver, read by either
 *     the stack or driver.
 */
#define IFF_UP          0x1             /* (n) interface is up */
#define IFF_BROADCAST   0x2             /* (i) broadcast address valid */
#define IFF_DEBUG       0x4             /* (n) turn on debugging */
#define IFF_LOOPBACK    0x8             /* (i) is a loopback net */
#define IFF_POINTOPOINT 0x10            /* (i) is a point-to-point link */
#define IFF_SMART       0x20            /* (i) interface manages own routes */
#define IFF_DRV_RUNNING 0x40            /* (d) resources allocated */
#define IFF_NOARP       0x80            /* (n) no address resolution protocol */
#define IFF_PROMISC     0x100           /* (n) receive all packets */
#define IFF_ALLMULTI    0x200           /* (n) receive all multicast packets */
#define IFF_DRV_OACTIVE 0x400           /* (d) tx hardware queue is full */
#define IFF_SIMPLEX     0x800           /* (i) can't hear own transmissions */
#define IFF_LINK0       0x1000          /* per link layer defined bit */
#define IFF_LINK1       0x2000          /* per link layer defined bit */
#define IFF_LINK2       0x4000          /* per link layer defined bit */
#define IFF_ALTPHYS     IFF_LINK2       /* use alternate physical connection */
#define IFF_MULTICAST   0x8000          /* (i) supports multicast */
#define IFF_CANTCONFIG  0x10000         /* (i) unconfigurable using ioctl(2) */
#define IFF_PPROMISC    0x20000         /* (n) user-requested promisc mode */
#define IFF_MONITOR     0x40000         /* (n) user-requested monitor mode */
#define IFF_STATICARP   0x80000         /* (n) static ARP */
#define IFF_DYING       0x200000        /* (n) interface is winding down */
#define IFF_RENAMING    0x400000        /* (n) interface is being renamed */
/* Throughout this file, IP addresses are expected to be in
 * the same byte order as in IP_PCB. */

/** must be the maximum of all used hardware address lengths
    across all types of interfaces in use */
#define NETIF_MAX_HWADDR_LEN 6U

/** Whether the network interface is 'up'. This is
 * a software flag used to control whether this network
 * interface is enabled and processes traffic.
 * It is set by the startup code (for static IP configuration) or
 * by dhcp/autoip when an address has been assigned.
 */
#define NETIF_FLAG_UP           0x01U
/** If set, the netif has broadcast capability.
 * Set by the netif driver in its init function. */
#define NETIF_FLAG_BROADCAST    0x02U
/** If set, the netif is one end of a point-to-point connection.
 * Set by the netif driver in its init function. */
#define NETIF_FLAG_POINTTOPOINT 0x04U
/** If set, the interface is configured using DHCP.
 * Set by the DHCP code when starting or stopping DHCP. */
#define NETIF_FLAG_DHCP         0x08U
/** If set, the interface has an active link
 *  (set by the network interface driver).
 * Either set by the netif driver in its init function (if the link
 * is up at that time) or at a later point once the link comes up
 * (if link detection is supported by the hardware). */
#define NETIF_FLAG_LINK_UP      0x10U
/** If set, the netif is an ethernet device using ARP.
 * Set by the netif driver in its init function.
 * Used to check input packet types and use of DHCP. */
#define NETIF_FLAG_ETHARP       0x20U
/** If set, the netif is an ethernet device. It might not use
 * ARP or TCP/IP if it is used for PPPoE only.
 */
#define NETIF_FLAG_ETHERNET     0x40U
/** If set, the netif has IGMP capability.
 * Set by the netif driver in its init function. */
#define NETIF_FLAG_IGMP         0x80U

/** Generic data structure used for all lwIP network interfaces.
 *  The following fields should be filled in by the initialization
 *  function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
struct netif {
    /** pointer to next in linked list */
    struct netif *next;
    
    /** IP address configuration in network byte order */
    ip_addr_t ip_addr;
    ip_addr_t netmask;
    ip_addr_t gw;
    
    /*** LWIP_IPV6 ***********************************************************/
    /** Array of IPv6 addresses for this netif. */
    ip6_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES];
    /** The state of each IPv6 address (Tentative, Preferred, etc).
     * @see ip6_addr.h */
    u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES];

    /** This function is called by the network device driver
     *  to pass a packet up the TCP/IP stack. */
    netif_input_fn input;
    /** This function is called by the IP module when it wants
     *  to send a packet on the interface. This function typically
     *  first resolves the hardware address, then sends the packet. */
    netif_output_fn output;
    /** This function is called by the ARP module when it wants
     *  to send a packet on the interface. This function outputs
     *  the pbuf as-is on the link medium. */
    netif_linkoutput_fn linkoutput;
    
    /*** LWIP_IPV6 ***********************************************************/
    /** This function is called by the IPv6 module when it wants
     *  to send a packet on the interface. This function typically
     *  first resolves the hardware address, then sends the packet. */
     netif_output_ip6_fn output_ip6;
    
    /*** LWIP_NETIF_STATUS_CALLBACK ******************************************/
    /** This function is called when the netif state is set to up or down */
    netif_status_callback_fn status_callback;
    
    /*** LWIP_NETIF_LINK_CALLBACK ********************************************/
    /** This function is called when the netif link is set to up or down */
    netif_status_callback_fn link_callback;
    
    /*** LWIP_NETIF_REMOVE_CALLBACK ******************************************/
    /** This function is called when the netif has been removed */
    netif_status_callback_fn remove_callback;
    
    /** This field can be set by the device driver and could point
     *  to state information for the device. */
    void *state;
    
    /*** LWIP_DHCP ***********************************************************/
    /** the DHCP client state information for this netif */
    struct dhcp *dhcp;
    
    /*** LWIP_AUTOIP *********************************************************/
    /** the AutoIP client state information for this netif */
    struct autoip *autoip;
    
    /*** LWIP_IPV6_AUTOCONFIG ************************************************/
    /** is this netif enabled for IPv6 autoconfiguration */
    u8_t ip6_autoconfig_enabled;
    
    /*** LWIP_IPV6_SEND_ROUTER_SOLICIT ***************************************/
    /** Number of Router Solicitation messages that remain to be sent. */
    u8_t rs_count;
    
    /*** LWIP_IPV6_DHCP6 *****************************************************/
    /** the DHCPv6 client state information for this netif */
    struct dhcp6 *dhcp6;
    
    /*** LWIP_NETIF_HOSTNAME *************************************************/
    /* the hostname for this netif, NULL is a valid value */
    char*  hostname;
    
    /** maximum transfer unit (in bytes) */
    u16_t mtu;
    /** number of bytes used in hwaddr */
    u8_t hwaddr_len;
    /** link level hardware address of this interface */
    u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
    /** flags (see NETIF_FLAG_ above) */
    u8_t flags;
    /** descriptive abbreviation */
    char name[2];
    /** number of this interface */
    u8_t num;
    
    /*** LWIP_SNMP ***********************************************************/
    /** link type (from "snmp_ifType" enum from snmp.h) */
    u8_t link_type;
    /** (estimate) link speed */
    u32_t link_speed;
    /** timestamp at last change made (up/down) */
    u32_t ts;
    /** counters */
    u32_t ifinoctets;
    u32_t ifinucastpkts;
    u32_t ifinnucastpkts;
    u32_t ifindiscards;
    u32_t ifoutoctets;
    u32_t ifoutucastpkts;
    u32_t ifoutnucastpkts;
    u32_t ifoutdiscards;
    
    /*** LWIP_IGMP ***********************************************************/
    /** This function could be called to add or delete a entry in the multicast
     *  filter table of the ethernet MAC.*/
    netif_igmp_mac_filter_fn igmp_mac_filter;
    
    /*** LWIP_IPV6 && LWIP_IPV6_MLD ******************************************/
    /** This function could be called to add or delete an entry in the IPv6 multicast
     *  filter table of the ethernet MAC. */
    netif_mld_mac_filter_fn mld_mac_filter;
    
    /*** LWIP_NETIF_HWADDRHINT ***********************************************/
    u8_t *addr_hint;
    
    /*** ENABLE_LOOPBACK *****************************************************/
    /* List of packets to be queued for ourselves. */
    struct pbuf *loop_first;
    struct pbuf *loop_last;
    
    u16_t loop_cnt_current;
};
#define SIOCSIFPHYADDR   _IOW('i', 70, struct ifaliasreq) /* set gif addres */
#define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq)    /* get gif psrc addr */
#define SIOCGIFPDSTADDR _IOWR('i', 72, struct ifreq)    /* get gif pdst addr */
struct nd_ifinfo {
    u_int32_t linkmtu;              /* LinkMTU */
    u_int32_t maxmtu;               /* Upper bound of LinkMTU */
    u_int32_t basereachable;        /* BaseReachableTime */
    u_int32_t reachable;            /* Reachable Time */
    u_int32_t retrans;              /* Retrans Timer */
    u_int32_t flags;                /* Flags */
    int recalctm;                   /* BaseReacable re-calculation timer */
    u_int8_t chlim;                 /* CurHopLimit */
    u_int8_t initialized;           /* Flag to see the entry is initialized */
    
    /* the following 3 members are for privacy extension for addrconf */
    u_int8_t randomseed0[8];        /* upper 64 bits of MD5 digest */
    u_int8_t randomseed1[8];        /* lower 64 bits (usually the EUI64 IFID) */
    u_int8_t randomid[8];           /* current random ID */
};

struct  in6_ndireq {
    char ifname[IFNAMSIZ];
    struct nd_ifinfo ndi;
};

struct in6_ndireq nd;

memset(&nd, 0, sizeof(nd));
strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname));
error = ioctl(s, SIOCGIFINFO_IN6, &nd);
/*
 * Structure of a Link-Level sockaddr:
 */
struct sockaddr_dl {
        u_char  sdl_len;        /* Total length of sockaddr */
        u_char  sdl_family;     /* AF_LINK */
        u_short sdl_index;      /* if != 0, system given index for interface */
        u_char  sdl_type;       /* interface type */
        u_char  sdl_nlen;       /* interface name length, no trailing 0 reqd. */
        u_char  sdl_alen;       /* link level address length */
        u_char  sdl_slen;       /* link layer selector length */
        char    sdl_data[46];   /* minimum work area, can be larger;
                                   contains both if name and ll address */
};
$2  = {sdl_len = 56 '8', sdl_family = 18 (AF_LINK), sdl_index = 1, sdl_type = 0x06 (IFT_ETHER), sdl_nlen = 3, sdl_alen = 6, sdl_slen = 0, sdl_data = "vr0", ...}
$13 = {sdl_len = 56 '8', sdl_family = 18 (AF_LINK), sdl_index = 2, sdl_type = 0x06 (IFT_ETHER), sdl_nlen = 3, sdl_alen = 6, sdl_slen = 0, sdl_data = "vr1", ...}
$14 = {sdl_len = 56 '8', sdl_family = 18 (AF_LINK), sdl_index = 3, sdl_type = 0x06 (IFT_ETHER), sdl_nlen = 3, sdl_alen = 6, sdl_slen = 0, sdl_data = "vr2", ...}
$15 = {sdl_len = 56 '8', sdl_family = 18 (AF_LINK), sdl_index = 4, sdl_type = 0x18 (IFT_LOOP),  sdl_nlen = 3, sdl_alen = 0, sdl_slen = 0, sdl_data = "lo0", ...}
$16 = {sdl_len = 56 '8', sdl_family = 18 (AF_LINK), sdl_index = 5, sdl_type = 0xf6 (IFT_PFLOG), sdl_nlen = 6, sdl_alen = 0, sdl_slen = 0, sdl_data = "pflog0", ...}

sdl->sdl_nlen   /* interface name length, no trailing 0 reqd. */
sdl->sdl_alen   /* link level address length */

sdl->sdl_type:
/usr/include/net/if_types.h
#define	IFT_ETHER	0x6		/* Ethernet CSMA/CD */
#define	IFT_LOOP	0x18		/* loopback */
#define	IFT_PFLOG	0xf6            /* PF firewall */
#define ETH_ALEN	6		/* Octets in one ethernet addr	 */
Linux:

#define ETHER_ADDR_LEN  ETH_ALEN                 /* size of ethernet addr */

/* This is a name for the 48 bit ethernet address available on many
   systems.  */
struct ether_addr
{
  u_int8_t ether_addr_octet[ETH_ALEN];
} __attribute__ ((__packed__));


FreeBSD:
/*
* The number of bytes in an	ethernet (MAC) address.
*/
#define ETHER_ADDR_LEN	   6

/*
* Structure	of a 48-bit Ethernet address.
*/
struct  ether_addr {
   u_char octet[ETHER_ADDR_LEN];
};

Do SIOCGIFNUM ioctl to find the number of interfaces

/*
 * Do SIOCGIFNUM ioctl to find the number of interfaces
 *
 * Allocate space for number of interfaces found
 *
 * Do SIOCGIFCONF with allocated buffer
 *
 */
if (ioctl(s, SIOCGIFNUM, (char *)&numifs) == -1) {
    numifs = MAXIFS;
}
bufsize = numifs * sizeof(struct ifreq);
reqbuf = (struct ifreq *) malloc(bufsize);
if (reqbuf == NULL) {
    fprintf(stderr, "out of memory\n");
    exit(1);
}
ifc.ifc_buf = (caddr_t)&reqbuf[0];
ifc.ifc_len = bufsize;
if (ioctl(s, SIOCGIFCONF, (char *)&ifc) == -1) {
    perror("ioctl(SIOCGIFCONF)");
    exit(1);
}

ioctl(sockfd, SIOCGIFCONF, &ifc)



					

Leave a Reply

Your email address will not be published. Required fields are marked *