1  /* Copyright (C) 1991-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #ifndef _NETINET_IP6_H
      19  #define _NETINET_IP6_H 1
      20  
      21  #include <inttypes.h>
      22  #include <netinet/in.h>
      23  
      24  struct ip6_hdr
      25    {
      26      union
      27        {
      28  	struct ip6_hdrctl
      29  	  {
      30  	    uint32_t ip6_un1_flow;   /* 4 bits version, 8 bits TC,
      31  					20 bits flow-ID */
      32  	    uint16_t ip6_un1_plen;   /* payload length */
      33  	    uint8_t  ip6_un1_nxt;    /* next header */
      34  	    uint8_t  ip6_un1_hlim;   /* hop limit */
      35  	  } ip6_un1;
      36  	uint8_t ip6_un2_vfc;       /* 4 bits version, top 4 bits tclass */
      37        } ip6_ctlun;
      38      struct in6_addr ip6_src;      /* source address */
      39      struct in6_addr ip6_dst;      /* destination address */
      40    };
      41  
      42  #define ip6_vfc   ip6_ctlun.ip6_un2_vfc
      43  #define ip6_flow  ip6_ctlun.ip6_un1.ip6_un1_flow
      44  #define ip6_plen  ip6_ctlun.ip6_un1.ip6_un1_plen
      45  #define ip6_nxt   ip6_ctlun.ip6_un1.ip6_un1_nxt
      46  #define ip6_hlim  ip6_ctlun.ip6_un1.ip6_un1_hlim
      47  #define ip6_hops  ip6_ctlun.ip6_un1.ip6_un1_hlim
      48  
      49  /* Generic extension header.  */
      50  struct ip6_ext
      51    {
      52      uint8_t  ip6e_nxt;		/* next header.  */
      53      uint8_t  ip6e_len;		/* length in units of 8 octets.  */
      54    };
      55  
      56  /* Hop-by-Hop options header.  */
      57  struct ip6_hbh
      58    {
      59      uint8_t  ip6h_nxt;		/* next header.  */
      60      uint8_t  ip6h_len;		/* length in units of 8 octets.  */
      61      /* followed by options */
      62    };
      63  
      64  /* Destination options header */
      65  struct ip6_dest
      66    {
      67      uint8_t  ip6d_nxt;		/* next header */
      68      uint8_t  ip6d_len;		/* length in units of 8 octets */
      69      /* followed by options */
      70    };
      71  
      72  /* Routing header */
      73  struct ip6_rthdr
      74    {
      75      uint8_t  ip6r_nxt;		/* next header */
      76      uint8_t  ip6r_len;		/* length in units of 8 octets */
      77      uint8_t  ip6r_type;		/* routing type */
      78      uint8_t  ip6r_segleft;	/* segments left */
      79      /* followed by routing type specific data */
      80    };
      81  
      82  /* Type 0 Routing header */
      83  struct ip6_rthdr0
      84    {
      85      uint8_t  ip6r0_nxt;		/* next header */
      86      uint8_t  ip6r0_len;		/* length in units of 8 octets */
      87      uint8_t  ip6r0_type;	/* always zero */
      88      uint8_t  ip6r0_segleft;	/* segments left */
      89      uint8_t  ip6r0_reserved;	/* reserved field */
      90      uint8_t  ip6r0_slmap[3];	/* strict/loose bit map */
      91      /* followed by up to 127 struct in6_addr */
      92      struct in6_addr ip6r0_addr[0];
      93    };
      94  
      95  /* Fragment header */
      96  struct ip6_frag
      97    {
      98      uint8_t   ip6f_nxt;		/* next header */
      99      uint8_t   ip6f_reserved;	/* reserved field */
     100      uint16_t  ip6f_offlg;	/* offset, reserved, and flag */
     101      uint32_t  ip6f_ident;	/* identification */
     102    };
     103  
     104  #if __BYTE_ORDER == __BIG_ENDIAN
     105  # define IP6F_OFF_MASK       0xfff8  /* mask out offset from _offlg */
     106  # define IP6F_RESERVED_MASK  0x0006  /* reserved bits in ip6f_offlg */
     107  # define IP6F_MORE_FRAG      0x0001  /* more-fragments flag */
     108  #else   /* __BYTE_ORDER == __LITTLE_ENDIAN */
     109  # define IP6F_OFF_MASK       0xf8ff  /* mask out offset from _offlg */
     110  # define IP6F_RESERVED_MASK  0x0600  /* reserved bits in ip6f_offlg */
     111  # define IP6F_MORE_FRAG      0x0100  /* more-fragments flag */
     112  #endif
     113  
     114  /* IPv6 options */
     115  struct ip6_opt
     116    {
     117      uint8_t  ip6o_type;
     118      uint8_t  ip6o_len;
     119    };
     120  
     121  /* The high-order 3 bits of the option type define the behavior
     122   * when processing an unknown option and whether or not the option
     123   * content changes in flight.
     124   */
     125  #define IP6OPT_TYPE(o)		((o) & 0xc0)
     126  #define IP6OPT_TYPE_SKIP	0x00
     127  #define IP6OPT_TYPE_DISCARD	0x40
     128  #define IP6OPT_TYPE_FORCEICMP	0x80
     129  #define IP6OPT_TYPE_ICMP	0xc0
     130  #define IP6OPT_TYPE_MUTABLE	0x20
     131  
     132  /* Special option types for padding.  */
     133  #define IP6OPT_PAD1	0
     134  #define IP6OPT_PADN	1
     135  
     136  #define IP6OPT_JUMBO		0xc2
     137  #define IP6OPT_NSAP_ADDR	0xc3
     138  #define IP6OPT_TUNNEL_LIMIT	0x04
     139  #define IP6OPT_ROUTER_ALERT	0x05
     140  
     141  /* Jumbo Payload Option */
     142  struct ip6_opt_jumbo
     143    {
     144      uint8_t  ip6oj_type;
     145      uint8_t  ip6oj_len;
     146      uint8_t  ip6oj_jumbo_len[4];
     147    };
     148  #define IP6OPT_JUMBO_LEN	6
     149  
     150  /* NSAP Address Option */
     151  struct ip6_opt_nsap
     152    {
     153      uint8_t  ip6on_type;
     154      uint8_t  ip6on_len;
     155      uint8_t  ip6on_src_nsap_len;
     156      uint8_t  ip6on_dst_nsap_len;
     157        /* followed by source NSAP */
     158        /* followed by destination NSAP */
     159    };
     160  
     161  /* Tunnel Limit Option */
     162  struct ip6_opt_tunnel
     163    {
     164      uint8_t  ip6ot_type;
     165      uint8_t  ip6ot_len;
     166      uint8_t  ip6ot_encap_limit;
     167    };
     168  
     169  /* Router Alert Option */
     170  struct ip6_opt_router
     171    {
     172      uint8_t  ip6or_type;
     173      uint8_t  ip6or_len;
     174      uint8_t  ip6or_value[2];
     175    };
     176  
     177  /* Router alert values (in network byte order) */
     178  #if __BYTE_ORDER == __BIG_ENDIAN
     179  # define IP6_ALERT_MLD	0x0000
     180  # define IP6_ALERT_RSVP	0x0001
     181  # define IP6_ALERT_AN	0x0002
     182  #else /* __BYTE_ORDER == __LITTLE_ENDIAN */
     183  # define IP6_ALERT_MLD	0x0000
     184  # define IP6_ALERT_RSVP	0x0100
     185  # define IP6_ALERT_AN	0x0200
     186  #endif
     187  
     188  #endif /* netinet/ip6.h */