am b8175727: am 9a330512: Merge "Add time-to-live (TTL) support to resolver cache"
* commit 'b8175727c7a165076311f18c29f09bdc27d7be10':
Add time-to-live (TTL) support to resolver cache
diff --git a/libc/bionic/md5.c b/libc/bionic/md5.c
index 087786f..1117c3b 100644
--- a/libc/bionic/md5.c
+++ b/libc/bionic/md5.c
@@ -237,7 +237,7 @@
void
MD5_Final (void *res, struct md5 *m)
{
- static unsigned char zeros[72];
+ unsigned char zeros[72];
unsigned offset = (m->sz[0] / 8) % 64;
unsigned int dstart = (120 - offset - 1) % 64 + 1;
diff --git a/libc/include/netinet/icmp6.h b/libc/include/netinet/icmp6.h
new file mode 100644
index 0000000..fbc8234
--- /dev/null
+++ b/libc/include/netinet/icmp6.h
@@ -0,0 +1,730 @@
+/* $NetBSD: icmp6.h,v 1.40 2009/10/31 22:32:17 christos Exp $ */
+/* $KAME: icmp6.h,v 1.84 2003/04/23 10:26:51 itojun Exp $ */
+
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_ICMP6_H_
+#define _NETINET_ICMP6_H_
+
+#define ICMPV6_PLD_MAXLEN 1232 /* IPV6_MMTU - sizeof(struct ip6_hdr)
+ - sizeof(struct icmp6_hdr) */
+
+struct icmp6_hdr {
+ u_int8_t icmp6_type; /* type field */
+ u_int8_t icmp6_code; /* code field */
+ u_int16_t icmp6_cksum; /* checksum field */
+ union {
+ u_int32_t icmp6_un_data32[1]; /* type-specific field */
+ u_int16_t icmp6_un_data16[2]; /* type-specific field */
+ u_int8_t icmp6_un_data8[4]; /* type-specific field */
+ } icmp6_dataun;
+} __packed;
+
+#define icmp6_data32 icmp6_dataun.icmp6_un_data32
+#define icmp6_data16 icmp6_dataun.icmp6_un_data16
+#define icmp6_data8 icmp6_dataun.icmp6_un_data8
+#define icmp6_pptr icmp6_data32[0] /* parameter prob */
+#define icmp6_mtu icmp6_data32[0] /* packet too big */
+#define icmp6_id icmp6_data16[0] /* echo request/reply */
+#define icmp6_seq icmp6_data16[1] /* echo request/reply */
+#define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */
+
+#define ICMP6_DST_UNREACH 1 /* dest unreachable, codes: */
+#define ICMP6_PACKET_TOO_BIG 2 /* packet too big */
+#define ICMP6_TIME_EXCEEDED 3 /* time exceeded, code: */
+#define ICMP6_PARAM_PROB 4 /* ip6 header bad */
+
+#define ICMP6_ECHO_REQUEST 128 /* echo service */
+#define ICMP6_ECHO_REPLY 129 /* echo reply */
+#define MLD_LISTENER_QUERY 130 /* multicast listener query */
+#define MLD_LISTENER_REPORT 131 /* multicast listener report */
+#define MLD_LISTENER_DONE 132 /* multicast listener done */
+
+/* RFC2292 decls */
+#define ICMP6_MEMBERSHIP_QUERY 130 /* group membership query */
+#define ICMP6_MEMBERSHIP_REPORT 131 /* group membership report */
+#define ICMP6_MEMBERSHIP_REDUCTION 132 /* group membership termination */
+
+#ifndef _KERNEL
+/* the followings are for backward compatibility to old KAME apps. */
+#define MLD6_LISTENER_QUERY MLD_LISTENER_QUERY
+#define MLD6_LISTENER_REPORT MLD_LISTENER_REPORT
+#define MLD6_LISTENER_DONE MLD_LISTENER_DONE
+#endif
+
+#define ND_ROUTER_SOLICIT 133 /* router solicitation */
+#define ND_ROUTER_ADVERT 134 /* router advertisement */
+#define ND_NEIGHBOR_SOLICIT 135 /* neighbor solicitation */
+#define ND_NEIGHBOR_ADVERT 136 /* neighbor advertisement */
+#define ND_REDIRECT 137 /* redirect */
+
+#define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */
+
+#define ICMP6_WRUREQUEST 139 /* who are you request */
+#define ICMP6_WRUREPLY 140 /* who are you reply */
+#define ICMP6_FQDN_QUERY 139 /* FQDN query */
+#define ICMP6_FQDN_REPLY 140 /* FQDN reply */
+#define ICMP6_NI_QUERY 139 /* node information request */
+#define ICMP6_NI_REPLY 140 /* node information reply */
+
+/* The definitions below are experimental. TBA */
+#define MLD_MTRACE_RESP 200 /* mtrace response(to sender) */
+#define MLD_MTRACE 201 /* mtrace messages */
+
+#ifndef _KERNEL
+/* the followings are for backward compatibility to old KAME apps. */
+#define MLD6_MTRACE_RESP MLD_MTRACE_RESP
+#define MLD6_MTRACE MLD_MTRACE
+#endif
+
+#define ICMP6_MAXTYPE 201
+
+#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */
+#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */
+#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */
+#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */
+#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */
+#define ICMP6_DST_UNREACH_NOPORT 4 /* port unreachable */
+
+#define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */
+#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */
+
+#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */
+#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */
+#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */
+
+#define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */
+
+#define ICMP6_NI_SUBJ_IPV6 0 /* Query Subject is an IPv6 address */
+#define ICMP6_NI_SUBJ_FQDN 1 /* Query Subject is a Domain name */
+#define ICMP6_NI_SUBJ_IPV4 2 /* Query Subject is an IPv4 address */
+
+#define ICMP6_NI_SUCCESS 0 /* node information successful reply */
+#define ICMP6_NI_REFUSED 1 /* node information request is refused */
+#define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */
+
+#define ICMP6_ROUTER_RENUMBERING_COMMAND 0 /* rr command */
+#define ICMP6_ROUTER_RENUMBERING_RESULT 1 /* rr result */
+#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 /* rr seq num reset */
+
+/* Used in kernel only */
+#define ND_REDIRECT_ONLINK 0 /* redirect to an on-link node */
+#define ND_REDIRECT_ROUTER 1 /* redirect to a better router */
+
+/*
+ * Multicast Listener Discovery
+ */
+struct mld_hdr {
+ struct icmp6_hdr mld_icmp6_hdr;
+ struct in6_addr mld_addr; /* multicast address */
+} __packed;
+
+/* definitions to provide backward compatibility to old KAME applications */
+#ifndef _KERNEL
+#define mld6_hdr mld_hdr
+#define mld6_type mld_type
+#define mld6_code mld_code
+#define mld6_cksum mld_cksum
+#define mld6_maxdelay mld_maxdelay
+#define mld6_reserved mld_reserved
+#define mld6_addr mld_addr
+#endif
+
+/* shortcut macro definitions */
+#define mld_type mld_icmp6_hdr.icmp6_type
+#define mld_code mld_icmp6_hdr.icmp6_code
+#define mld_cksum mld_icmp6_hdr.icmp6_cksum
+#define mld_maxdelay mld_icmp6_hdr.icmp6_data16[0]
+#define mld_reserved mld_icmp6_hdr.icmp6_data16[1]
+
+#define MLD_MINLEN 24
+
+/*
+ * Neighbor Discovery
+ */
+
+struct nd_router_solicit { /* router solicitation */
+ struct icmp6_hdr nd_rs_hdr;
+ /* could be followed by options */
+} __packed;
+
+#define nd_rs_type nd_rs_hdr.icmp6_type
+#define nd_rs_code nd_rs_hdr.icmp6_code
+#define nd_rs_cksum nd_rs_hdr.icmp6_cksum
+#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0]
+
+struct nd_router_advert { /* router advertisement */
+ struct icmp6_hdr nd_ra_hdr;
+ u_int32_t nd_ra_reachable; /* reachable time */
+ u_int32_t nd_ra_retransmit; /* retransmit timer */
+ /* could be followed by options */
+} __packed;
+
+#define nd_ra_type nd_ra_hdr.icmp6_type
+#define nd_ra_code nd_ra_hdr.icmp6_code
+#define nd_ra_cksum nd_ra_hdr.icmp6_cksum
+#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0]
+#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1]
+#define ND_RA_FLAG_MANAGED 0x80
+#define ND_RA_FLAG_OTHER 0x40
+#define ND_RA_FLAG_HOME_AGENT 0x20
+
+/*
+ * Router preference values based on RFC4199.
+ */
+#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */
+
+#define ND_RA_FLAG_RTPREF_HIGH 0x08 /* 00001000 */
+#define ND_RA_FLAG_RTPREF_MEDIUM 0x00 /* 00000000 */
+#define ND_RA_FLAG_RTPREF_LOW 0x18 /* 00011000 */
+#define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */
+
+#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1]
+
+struct nd_neighbor_solicit { /* neighbor solicitation */
+ struct icmp6_hdr nd_ns_hdr;
+ struct in6_addr nd_ns_target; /*target address */
+ /* could be followed by options */
+} __packed;
+
+#define nd_ns_type nd_ns_hdr.icmp6_type
+#define nd_ns_code nd_ns_hdr.icmp6_code
+#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
+#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
+
+struct nd_neighbor_advert { /* neighbor advertisement */
+ struct icmp6_hdr nd_na_hdr;
+ struct in6_addr nd_na_target; /* target address */
+ /* could be followed by options */
+} __packed;
+
+#define nd_na_type nd_na_hdr.icmp6_type
+#define nd_na_code nd_na_hdr.icmp6_code
+#define nd_na_cksum nd_na_hdr.icmp6_cksum
+#define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0]
+#if BYTE_ORDER == BIG_ENDIAN
+#define ND_NA_FLAG_ROUTER 0x80000000
+#define ND_NA_FLAG_SOLICITED 0x40000000
+#define ND_NA_FLAG_OVERRIDE 0x20000000
+#else
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define ND_NA_FLAG_ROUTER 0x80
+#define ND_NA_FLAG_SOLICITED 0x40
+#define ND_NA_FLAG_OVERRIDE 0x20
+#endif
+#endif
+
+struct nd_redirect { /* redirect */
+ struct icmp6_hdr nd_rd_hdr;
+ struct in6_addr nd_rd_target; /* target address */
+ struct in6_addr nd_rd_dst; /* destination address */
+ /* could be followed by options */
+} __packed;
+
+#define nd_rd_type nd_rd_hdr.icmp6_type
+#define nd_rd_code nd_rd_hdr.icmp6_code
+#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
+#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
+
+struct nd_opt_hdr { /* Neighbor discovery option header */
+ u_int8_t nd_opt_type;
+ u_int8_t nd_opt_len;
+ /* followed by option specific data*/
+} __packed;
+
+#define ND_OPT_SOURCE_LINKADDR 1
+#define ND_OPT_TARGET_LINKADDR 2
+#define ND_OPT_PREFIX_INFORMATION 3
+#define ND_OPT_REDIRECTED_HEADER 4
+#define ND_OPT_MTU 5
+#define ND_OPT_ADVINTERVAL 7
+#define ND_OPT_HOMEAGENT_INFO 8
+#define ND_OPT_SOURCE_ADDRLIST 9
+#define ND_OPT_TARGET_ADDRLIST 10
+#define ND_OPT_RDNSS 25
+/* draft-ietf-ipngwg-router-preference, not officially assigned yet */
+#define ND_OPT_ROUTE_INFO 200
+/* draft-ietf-mobileip-hmipv6, not officially assigned yet */
+#define ND_OPT_MAP 201
+
+struct nd_opt_route_info { /* route info */
+ u_int8_t nd_opt_rti_type;
+ u_int8_t nd_opt_rti_len;
+ u_int8_t nd_opt_rti_prefixlen;
+ u_int8_t nd_opt_rti_flags;
+ u_int32_t nd_opt_rti_lifetime;
+ /* prefix follows */
+};
+
+struct nd_opt_prefix_info { /* prefix information */
+ u_int8_t nd_opt_pi_type;
+ u_int8_t nd_opt_pi_len;
+ u_int8_t nd_opt_pi_prefix_len;
+ u_int8_t nd_opt_pi_flags_reserved;
+ u_int32_t nd_opt_pi_valid_time;
+ u_int32_t nd_opt_pi_preferred_time;
+ u_int32_t nd_opt_pi_reserved2;
+ struct in6_addr nd_opt_pi_prefix;
+} __packed;
+
+#define ND_OPT_PI_FLAG_ONLINK 0x80
+#define ND_OPT_PI_FLAG_AUTO 0x40
+
+struct nd_opt_rd_hdr { /* redirected header */
+ u_int8_t nd_opt_rh_type;
+ u_int8_t nd_opt_rh_len;
+ u_int16_t nd_opt_rh_reserved1;
+ u_int32_t nd_opt_rh_reserved2;
+ /* followed by IP header and data */
+} __packed;
+
+struct nd_opt_mtu { /* MTU option */
+ u_int8_t nd_opt_mtu_type;
+ u_int8_t nd_opt_mtu_len;
+ u_int16_t nd_opt_mtu_reserved;
+ u_int32_t nd_opt_mtu_mtu;
+} __packed;
+
+struct nd_opt_rdnss { /* RDNSS option RFC 5006 */
+ u_int8_t nd_opt_rdnss_type;
+ u_int8_t nd_opt_rdnss_len;
+ u_int16_t nd_opt_rdnss_reserved;
+ u_int32_t nd_opt_rdnss_lifetime;
+ /* followed by list of IP prefixes */
+} __packed;
+
+/*
+ * icmp6 namelookup
+ */
+
+struct icmp6_namelookup {
+ struct icmp6_hdr icmp6_nl_hdr;
+ u_int8_t icmp6_nl_nonce[8];
+ int32_t icmp6_nl_ttl;
+#if 0
+ u_int8_t icmp6_nl_len;
+ u_int8_t icmp6_nl_name[3];
+#endif
+ /* could be followed by options */
+} __packed;
+
+/*
+ * icmp6 node information
+ */
+struct icmp6_nodeinfo {
+ struct icmp6_hdr icmp6_ni_hdr;
+ u_int8_t icmp6_ni_nonce[8];
+ /* could be followed by reply data */
+} __packed;
+
+#define ni_type icmp6_ni_hdr.icmp6_type
+#define ni_code icmp6_ni_hdr.icmp6_code
+#define ni_cksum icmp6_ni_hdr.icmp6_cksum
+#define ni_qtype icmp6_ni_hdr.icmp6_data16[0]
+#define ni_flags icmp6_ni_hdr.icmp6_data16[1]
+
+#define NI_QTYPE_NOOP 0 /* NOOP */
+#define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes */
+#define NI_QTYPE_FQDN 2 /* FQDN (draft 04) */
+#define NI_QTYPE_DNSNAME 2 /* DNS Name */
+#define NI_QTYPE_NODEADDR 3 /* Node Addresses */
+#define NI_QTYPE_IPV4ADDR 4 /* IPv4 Addresses */
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define NI_SUPTYPE_FLAG_COMPRESS 0x1
+#define NI_FQDN_FLAG_VALIDTTL 0x1
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define NI_SUPTYPE_FLAG_COMPRESS 0x0100
+#define NI_FQDN_FLAG_VALIDTTL 0x0100
+#endif
+
+#ifdef NAME_LOOKUPS_04
+#if BYTE_ORDER == BIG_ENDIAN
+#define NI_NODEADDR_FLAG_LINKLOCAL 0x1
+#define NI_NODEADDR_FLAG_SITELOCAL 0x2
+#define NI_NODEADDR_FLAG_GLOBAL 0x4
+#define NI_NODEADDR_FLAG_ALL 0x8
+#define NI_NODEADDR_FLAG_TRUNCATE 0x10
+#define NI_NODEADDR_FLAG_ANYCAST 0x20 /* just experimental. not in spec */
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define NI_NODEADDR_FLAG_LINKLOCAL 0x0100
+#define NI_NODEADDR_FLAG_SITELOCAL 0x0200
+#define NI_NODEADDR_FLAG_GLOBAL 0x0400
+#define NI_NODEADDR_FLAG_ALL 0x0800
+#define NI_NODEADDR_FLAG_TRUNCATE 0x1000
+#define NI_NODEADDR_FLAG_ANYCAST 0x2000 /* just experimental. not in spec */
+#endif
+#else /* draft-ietf-ipngwg-icmp-name-lookups-05 (and later?) */
+#if BYTE_ORDER == BIG_ENDIAN
+#define NI_NODEADDR_FLAG_TRUNCATE 0x1
+#define NI_NODEADDR_FLAG_ALL 0x2
+#define NI_NODEADDR_FLAG_COMPAT 0x4
+#define NI_NODEADDR_FLAG_LINKLOCAL 0x8
+#define NI_NODEADDR_FLAG_SITELOCAL 0x10
+#define NI_NODEADDR_FLAG_GLOBAL 0x20
+#define NI_NODEADDR_FLAG_ANYCAST 0x40 /* just experimental. not in spec */
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define NI_NODEADDR_FLAG_TRUNCATE 0x0100
+#define NI_NODEADDR_FLAG_ALL 0x0200
+#define NI_NODEADDR_FLAG_COMPAT 0x0400
+#define NI_NODEADDR_FLAG_LINKLOCAL 0x0800
+#define NI_NODEADDR_FLAG_SITELOCAL 0x1000
+#define NI_NODEADDR_FLAG_GLOBAL 0x2000
+#define NI_NODEADDR_FLAG_ANYCAST 0x4000 /* just experimental. not in spec */
+#endif
+#endif
+
+struct ni_reply_fqdn {
+ u_int32_t ni_fqdn_ttl; /* TTL */
+ u_int8_t ni_fqdn_namelen; /* length in octets of the FQDN */
+ u_int8_t ni_fqdn_name[3]; /* XXX: alignment */
+} __packed;
+
+/*
+ * Router Renumbering. as router-renum-08.txt
+ */
+struct icmp6_router_renum { /* router renumbering header */
+ struct icmp6_hdr rr_hdr;
+ u_int8_t rr_segnum;
+ u_int8_t rr_flags;
+ u_int16_t rr_maxdelay;
+ u_int32_t rr_reserved;
+} __packed;
+
+#define ICMP6_RR_FLAGS_TEST 0x80
+#define ICMP6_RR_FLAGS_REQRESULT 0x40
+#define ICMP6_RR_FLAGS_FORCEAPPLY 0x20
+#define ICMP6_RR_FLAGS_SPECSITE 0x10
+#define ICMP6_RR_FLAGS_PREVDONE 0x08
+
+#define rr_type rr_hdr.icmp6_type
+#define rr_code rr_hdr.icmp6_code
+#define rr_cksum rr_hdr.icmp6_cksum
+#define rr_seqnum rr_hdr.icmp6_data32[0]
+
+struct rr_pco_match { /* match prefix part */
+ u_int8_t rpm_code;
+ u_int8_t rpm_len;
+ u_int8_t rpm_ordinal;
+ u_int8_t rpm_matchlen;
+ u_int8_t rpm_minlen;
+ u_int8_t rpm_maxlen;
+ u_int16_t rpm_reserved;
+ struct in6_addr rpm_prefix;
+} __packed;
+
+#define RPM_PCO_ADD 1
+#define RPM_PCO_CHANGE 2
+#define RPM_PCO_SETGLOBAL 3
+#define RPM_PCO_MAX 4
+
+struct rr_pco_use { /* use prefix part */
+ u_int8_t rpu_uselen;
+ u_int8_t rpu_keeplen;
+ u_int8_t rpu_ramask;
+ u_int8_t rpu_raflags;
+ u_int32_t rpu_vltime;
+ u_int32_t rpu_pltime;
+ u_int32_t rpu_flags;
+ struct in6_addr rpu_prefix;
+} __packed;
+#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x80
+#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x40
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40
+#endif
+
+struct rr_result { /* router renumbering result message */
+ u_int16_t rrr_flags;
+ u_int8_t rrr_ordinal;
+ u_int8_t rrr_matchedlen;
+ u_int32_t rrr_ifid;
+ struct in6_addr rrr_prefix;
+} __packed;
+#if BYTE_ORDER == BIG_ENDIAN
+#define ICMP6_RR_RESULT_FLAGS_OOB 0x0002
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define ICMP6_RR_RESULT_FLAGS_OOB 0x0200
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100
+#endif
+
+/*
+ * icmp6 filter structures.
+ */
+
+struct icmp6_filter {
+ u_int32_t icmp6_filt[8];
+};
+
+#define ICMP6_FILTER_SETPASSALL(filterp) \
+ (void)memset(filterp, 0xff, sizeof(struct icmp6_filter))
+#define ICMP6_FILTER_SETBLOCKALL(filterp) \
+ (void)memset(filterp, 0x00, sizeof(struct icmp6_filter))
+#define ICMP6_FILTER_SETPASS(type, filterp) \
+ (((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31)))
+#define ICMP6_FILTER_SETBLOCK(type, filterp) \
+ (((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31)))
+#define ICMP6_FILTER_WILLPASS(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
+#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
+
+/*
+ * Variables related to this implementation
+ * of the internet control message protocol version 6.
+ */
+
+/*
+ * IPv6 ICMP statistics.
+ * Each counter is an unsigned 64-bit value.
+ */
+#define ICMP6_STAT_ERROR 0 /* # of calls to icmp6_error */
+#define ICMP6_STAT_CANTERROR 1 /* no error (old was icmp) */
+#define ICMP6_STAT_TOOFREQ 2 /* no error (rate limitation) */
+#define ICMP6_STAT_OUTHIST 3 /* # of output messages */
+ /* space for 256 counters */
+#define ICMP6_STAT_BADCODE 259 /* icmp6_code out of range */
+#define ICMP6_STAT_TOOSHORT 260 /* packet < sizeof(struct icmp6_hdr) */
+#define ICMP6_STAT_CHECKSUM 261 /* bad checksum */
+#define ICMP6_STAT_BADLEN 262 /* calculated bound mismatch */
+ /*
+ * number of responses; this member is inherited from the netinet code,
+ * but for netinet6 code, it is already available in outhist[].
+ */
+#define ICMP6_STAT_REFLECT 263
+#define ICMP6_STAT_INHIST 264 /* # of input messages */
+ /* space for 256 counters */
+#define ICMP6_STAT_ND_TOOMANYOPT 520 /* too many ND options */
+#define ICMP6_STAT_OUTERRHIST 521
+ /* space for 13 counters */
+#define ICMP6_STAT_PMTUCHG 534 /* path MTU changes */
+#define ICMP6_STAT_ND_BADOPT 535 /* bad ND options */
+#define ICMP6_STAT_BADNS 536 /* bad neighbor solicititation */
+#define ICMP6_STAT_BADNA 537 /* bad neighbor advertisement */
+#define ICMP6_STAT_BADRS 538 /* bad router solicitiation */
+#define ICMP6_STAT_BADRA 539 /* bad router advertisement */
+#define ICMP6_STAT_BADREDIRECT 540 /* bad redirect message */
+
+#define ICMP6_NSTATS 541
+
+#define ICMP6_ERRSTAT_DST_UNREACH_NOROUTE 0
+#define ICMP6_ERRSTAT_DST_UNREACH_ADMIN 1
+#define ICMP6_ERRSTAT_DST_UNREACH_BEYONDSCOPE 2
+#define ICMP6_ERRSTAT_DST_UNREACH_ADDR 3
+#define ICMP6_ERRSTAT_DST_UNREACH_NOPORT 4
+#define ICMP6_ERRSTAT_PACKET_TOO_BIG 5
+#define ICMP6_ERRSTAT_TIME_EXCEED_TRANSIT 6
+#define ICMP6_ERRSTAT_TIME_EXCEED_REASSEMBLY 7
+#define ICMP6_ERRSTAT_PARAMPROB_HEADER 8
+#define ICMP6_ERRSTAT_PARAMPROB_NEXTHEADER 9
+#define ICMP6_ERRSTAT_PARAMPROB_OPTION 10
+#define ICMP6_ERRSTAT_REDIRECT 11
+#define ICMP6_ERRSTAT_UNKNOWN 12
+
+/*
+ * Names for ICMP sysctl objects
+ */
+#define ICMPV6CTL_STATS 1
+#define ICMPV6CTL_REDIRACCEPT 2 /* accept/process redirects */
+#define ICMPV6CTL_REDIRTIMEOUT 3 /* redirect cache time */
+#if 0 /*obsoleted*/
+#define ICMPV6CTL_ERRRATELIMIT 5 /* ICMPv6 error rate limitation */
+#endif
+#define ICMPV6CTL_ND6_PRUNE 6
+#define ICMPV6CTL_ND6_DELAY 8
+#define ICMPV6CTL_ND6_UMAXTRIES 9
+#define ICMPV6CTL_ND6_MMAXTRIES 10
+#define ICMPV6CTL_ND6_USELOOPBACK 11
+/*#define ICMPV6CTL_ND6_PROXYALL 12 obsoleted, do not reuse here */
+#define ICMPV6CTL_NODEINFO 13
+#define ICMPV6CTL_ERRPPSLIMIT 14 /* ICMPv6 error pps limitation */
+#define ICMPV6CTL_ND6_MAXNUDHINT 15
+#define ICMPV6CTL_MTUDISC_HIWAT 16
+#define ICMPV6CTL_MTUDISC_LOWAT 17
+#define ICMPV6CTL_ND6_DEBUG 18
+#define ICMPV6CTL_ND6_DRLIST 19
+#define ICMPV6CTL_ND6_PRLIST 20
+#define ICMPV6CTL_ND6_MAXQLEN 24
+#define ICMPV6CTL_MAXID 25
+
+#define ICMPV6CTL_NAMES { \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "rediraccept", CTLTYPE_INT }, \
+ { "redirtimeout", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "nd6_prune", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { "nd6_delay", CTLTYPE_INT }, \
+ { "nd6_umaxtries", CTLTYPE_INT }, \
+ { "nd6_mmaxtries", CTLTYPE_INT }, \
+ { "nd6_useloopback", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { "nodeinfo", CTLTYPE_INT }, \
+ { "errppslimit", CTLTYPE_INT }, \
+ { "nd6_maxnudhint", CTLTYPE_INT }, \
+ { "mtudisc_hiwat", CTLTYPE_INT }, \
+ { "mtudisc_lowat", CTLTYPE_INT }, \
+ { "nd6_debug", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "nd6_maxqueuelen", CTLTYPE_INT }, \
+}
+
+#define RTF_PROBEMTU RTF_PROTO1
+
+#ifdef _KERNEL
+struct rtentry;
+struct rttimer;
+struct in6_multi;
+
+void icmp6_init(void);
+void icmp6_paramerror(struct mbuf *, int);
+void icmp6_error(struct mbuf *, int, int, int);
+void icmp6_error2(struct mbuf *, int, int, int, struct ifnet *);
+int icmp6_input(struct mbuf **, int *, int);
+void icmp6_fasttimo(void);
+void icmp6_reflect(struct mbuf *, size_t);
+void icmp6_prepare(struct mbuf *);
+void icmp6_redirect_input(struct mbuf *, int);
+void icmp6_redirect_output(struct mbuf *, struct rtentry *);
+int icmp6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+
+void icmp6_statinc(u_int);
+
+struct ip6ctlparam;
+void icmp6_mtudisc_update(struct ip6ctlparam *, int);
+void icmp6_mtudisc_callback_register(void (*)(struct in6_addr *));
+
+/* XXX: is this the right place for these macros? */
+#define icmp6_ifstat_inc(ifp, tag) \
+do { \
+ if (ifp) \
+ ((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->icmp6_ifstat->tag++; \
+} while (/*CONSTCOND*/ 0)
+
+#define icmp6_ifoutstat_inc(ifp, type, code) \
+do { \
+ icmp6_ifstat_inc(ifp, ifs6_out_msg); \
+ switch(type) { \
+ case ICMP6_DST_UNREACH: \
+ icmp6_ifstat_inc(ifp, ifs6_out_dstunreach); \
+ if (code == ICMP6_DST_UNREACH_ADMIN) \
+ icmp6_ifstat_inc(ifp, ifs6_out_adminprohib); \
+ break; \
+ case ICMP6_PACKET_TOO_BIG: \
+ icmp6_ifstat_inc(ifp, ifs6_out_pkttoobig); \
+ break; \
+ case ICMP6_TIME_EXCEEDED: \
+ icmp6_ifstat_inc(ifp, ifs6_out_timeexceed); \
+ break; \
+ case ICMP6_PARAM_PROB: \
+ icmp6_ifstat_inc(ifp, ifs6_out_paramprob); \
+ break; \
+ case ICMP6_ECHO_REQUEST: \
+ icmp6_ifstat_inc(ifp, ifs6_out_echo); \
+ break; \
+ case ICMP6_ECHO_REPLY: \
+ icmp6_ifstat_inc(ifp, ifs6_out_echoreply); \
+ break; \
+ case MLD_LISTENER_QUERY: \
+ icmp6_ifstat_inc(ifp, ifs6_out_mldquery); \
+ break; \
+ case MLD_LISTENER_REPORT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_mldreport); \
+ break; \
+ case MLD_LISTENER_DONE: \
+ icmp6_ifstat_inc(ifp, ifs6_out_mlddone); \
+ break; \
+ case ND_ROUTER_SOLICIT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_routersolicit); \
+ break; \
+ case ND_ROUTER_ADVERT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_routeradvert); \
+ break; \
+ case ND_NEIGHBOR_SOLICIT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit); \
+ break; \
+ case ND_NEIGHBOR_ADVERT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert); \
+ break; \
+ case ND_REDIRECT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_redirect); \
+ break; \
+ } \
+} while (/*CONSTCOND*/ 0)
+
+extern int icmp6_rediraccept; /* accept/process redirects */
+extern int icmp6_redirtimeout; /* cache time for redirect routes */
+#endif /* _KERNEL */
+
+#endif /* !_NETINET_ICMP6_H_ */
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index 7a4b6c7..01bf58e 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -32,6 +32,7 @@
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/in6.h>
+#include <linux/ipv6.h>
#include <netinet/in6.h>
__BEGIN_DECLS
diff --git a/libc/include/netinet/in6.h b/libc/include/netinet/in6.h
index 580a510..7f3286a 100644
--- a/libc/include/netinet/in6.h
+++ b/libc/include/netinet/in6.h
@@ -103,6 +103,7 @@
#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
#define IN6ADDR_ANY_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}
+#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}}
#define ipv6mr_interface ipv6mr_ifindex
diff --git a/libc/include/netinet/ip6.h b/libc/include/netinet/ip6.h
new file mode 100644
index 0000000..aa816c2
--- /dev/null
+++ b/libc/include/netinet/ip6.h
@@ -0,0 +1,319 @@
+/* $NetBSD: ip6.h,v 1.23 2007/12/25 18:33:46 perry Exp $ */
+/* $KAME: ip6.h,v 1.45 2003/06/05 04:46:38 keiichi Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ip.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IP6_H_
+#define _NETINET_IP6_H_
+
+/*
+ * Definition for internet protocol version 6.
+ * RFC 2460
+ */
+
+struct ip6_hdr {
+ union {
+ struct ip6_hdrctl {
+ u_int32_t ip6_un1_flow; /* 20 bits of flow-ID */
+ u_int16_t ip6_un1_plen; /* payload length */
+ u_int8_t ip6_un1_nxt; /* next header */
+ u_int8_t ip6_un1_hlim; /* hop limit */
+ } ip6_un1;
+ u_int8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */
+ } ip6_ctlun;
+ struct in6_addr ip6_src; /* source address */
+ struct in6_addr ip6_dst; /* destination address */
+} __packed;
+
+#define ip6_vfc ip6_ctlun.ip6_un2_vfc
+#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
+#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
+#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
+#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
+#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
+
+#define IPV6_VERSION 0x60
+#define IPV6_VERSION_MASK 0xf0
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define IPV6_FLOWINFO_MASK 0x0fffffff /* flow info (28 bits) */
+#define IPV6_FLOWLABEL_MASK 0x000fffff /* flow label (20 bits) */
+#else
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define IPV6_FLOWINFO_MASK 0xffffff0f /* flow info (28 bits) */
+#define IPV6_FLOWLABEL_MASK 0xffff0f00 /* flow label (20 bits) */
+#endif /* LITTLE_ENDIAN */
+#endif
+#if 1
+/* ECN bits proposed by Sally Floyd */
+#define IP6TOS_CE 0x01 /* congestion experienced */
+#define IP6TOS_ECT 0x02 /* ECN-capable transport */
+#endif
+
+#ifdef _KERNEL
+/*
+ * for IPv6 pseudo header checksum
+ * XXX nonstandard
+ */
+struct ip6_hdr_pseudo {
+ struct in6_addr ip6ph_src;
+ struct in6_addr ip6ph_dst;
+ u_int32_t ip6ph_len;
+ u_int8_t ip6ph_zero[3];
+ u_int8_t ip6ph_nxt;
+} __packed;
+#endif
+
+/*
+ * Extension Headers
+ */
+
+struct ip6_ext {
+ u_int8_t ip6e_nxt;
+ u_int8_t ip6e_len;
+} __packed;
+
+/* Hop-by-Hop options header */
+/* XXX should we pad it to force alignment on an 8-byte boundary? */
+struct ip6_hbh {
+ u_int8_t ip6h_nxt; /* next header */
+ u_int8_t ip6h_len; /* length in units of 8 octets */
+ /* followed by options */
+} __packed;
+
+/* Destination options header */
+/* XXX should we pad it to force alignment on an 8-byte boundary? */
+struct ip6_dest {
+ u_int8_t ip6d_nxt; /* next header */
+ u_int8_t ip6d_len; /* length in units of 8 octets */
+ /* followed by options */
+} __packed;
+
+/* Option types and related macros */
+#define IP6OPT_PAD1 0x00 /* 00 0 00000 */
+#define IP6OPT_PADN 0x01 /* 00 0 00001 */
+#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
+#define IP6OPT_NSAP_ADDR 0xC3 /* 11 0 00011 */
+#define IP6OPT_TUNNEL_LIMIT 0x04 /* 00 0 00100 */
+#define IP6OPT_RTALERT 0x05 /* 00 0 00101 (KAME definition) */
+#define IP6OPT_ROUTER_ALERT 0x05 /* (RFC3542 def, recommended) */
+
+#define IP6OPT_RTALERT_LEN 4
+#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
+#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
+#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
+#define IP6OPT_MINLEN 2
+
+#define IP6OPT_TYPE(o) ((o) & 0xC0)
+#define IP6OPT_TYPE_SKIP 0x00
+#define IP6OPT_TYPE_DISCARD 0x40
+#define IP6OPT_TYPE_FORCEICMP 0x80
+#define IP6OPT_TYPE_ICMP 0xC0
+
+#define IP6OPT_MUTABLE 0x20
+
+/* IPv6 options: common part */
+struct ip6_opt {
+ u_int8_t ip6o_type;
+ u_int8_t ip6o_len;
+} __packed;
+
+/* Jumbo Payload Option */
+struct ip6_opt_jumbo {
+ u_int8_t ip6oj_type;
+ u_int8_t ip6oj_len;
+ u_int8_t ip6oj_jumbo_len[4];
+} __packed;
+#define IP6OPT_JUMBO_LEN 6
+
+/* NSAP Address Option */
+struct ip6_opt_nsap {
+ u_int8_t ip6on_type;
+ u_int8_t ip6on_len;
+ u_int8_t ip6on_src_nsap_len;
+ u_int8_t ip6on_dst_nsap_len;
+ /* followed by source NSAP */
+ /* followed by destination NSAP */
+} __packed;
+
+/* Tunnel Limit Option */
+struct ip6_opt_tunnel {
+ u_int8_t ip6ot_type;
+ u_int8_t ip6ot_len;
+ u_int8_t ip6ot_encap_limit;
+} __packed;
+
+/* Router Alert Option */
+struct ip6_opt_router {
+ u_int8_t ip6or_type;
+ u_int8_t ip6or_len;
+ u_int8_t ip6or_value[2];
+} __packed;
+/* Router alert values (in network byte order) */
+#if BYTE_ORDER == BIG_ENDIAN
+#define IP6_ALERT_MLD 0x0000
+#define IP6_ALERT_RSVP 0x0001
+#define IP6_ALERT_AN 0x0002
+#else
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define IP6_ALERT_MLD 0x0000
+#define IP6_ALERT_RSVP 0x0100
+#define IP6_ALERT_AN 0x0200
+#endif /* LITTLE_ENDIAN */
+#endif
+
+/* Routing header */
+struct ip6_rthdr {
+ u_int8_t ip6r_nxt; /* next header */
+ u_int8_t ip6r_len; /* length in units of 8 octets */
+ u_int8_t ip6r_type; /* routing type */
+ u_int8_t ip6r_segleft; /* segments left */
+ /* followed by routing type specific data */
+} __packed;
+
+/* Type 0 Routing header */
+struct ip6_rthdr0 {
+ u_int8_t ip6r0_nxt; /* next header */
+ u_int8_t ip6r0_len; /* length in units of 8 octets */
+ u_int8_t ip6r0_type; /* always zero */
+ u_int8_t ip6r0_segleft; /* segments left */
+ u_int32_t ip6r0_reserved; /* reserved field */
+} __packed;
+
+/* Fragment header */
+struct ip6_frag {
+ u_int8_t ip6f_nxt; /* next header */
+ u_int8_t ip6f_reserved; /* reserved field */
+ u_int16_t ip6f_offlg; /* offset, reserved, and flag */
+ u_int32_t ip6f_ident; /* identification */
+} __packed;
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define IP6F_OFF_MASK 0xfff8 /* mask out offset from _offlg */
+#define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */
+#define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+#define IP6F_OFF_MASK 0xf8ff /* mask out offset from _offlg */
+#define IP6F_RESERVED_MASK 0x0600 /* reserved bits in ip6f_offlg */
+#define IP6F_MORE_FRAG 0x0100 /* more-fragments flag */
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+/*
+ * Internet implementation parameters.
+ */
+#define IPV6_MAXHLIM 255 /* maximum hoplimit */
+#define IPV6_DEFHLIM 64 /* default hlim */
+#define IPV6_FRAGTTL 120 /* ttl for fragment packets, in slowtimo tick */
+#define IPV6_HLIMDEC 1 /* subtracted when forwarding */
+
+#define IPV6_MMTU 1280 /* minimal MTU and reassembly. 1024 + 256 */
+#define IPV6_MAXPACKET 65535 /* ip6 max packet size without Jumbo payload*/
+
+#ifdef _KERNEL
+/*
+ * IP6_EXTHDR_GET ensures that intermediate protocol header (from "off" to
+ * "len") is located in single mbuf, on contiguous memory region.
+ * The pointer to the region will be returned to pointer variable "val",
+ * with type "typ".
+ * IP6_EXTHDR_GET0 does the same, except that it aligns the structure at the
+ * very top of mbuf. GET0 is likely to make memory copy than GET.
+ *
+ * XXX we're now testing this, needs m_pulldown()
+ */
+#define IP6_EXTHDR_GET(val, typ, m, off, len) \
+do { \
+ struct mbuf *_t; \
+ int _tmp; \
+ if ((m)->m_len >= (off) + (len)) \
+ (val) = (typ)(mtod((m), char *) + (off)); \
+ else { \
+ _t = m_pulldown((m), (off), (len), &_tmp); \
+ if (_t) { \
+ if (_t->m_len < _tmp + (len)) \
+ panic("m_pulldown malfunction"); \
+ (val) = (typ)(mtod(_t, char *) + _tmp); \
+ } else { \
+ (val) = (typ)NULL; \
+ (m) = NULL; \
+ } \
+ } \
+} while (/*CONSTCOND*/ 0)
+
+#define IP6_EXTHDR_GET0(val, typ, m, off, len) \
+do { \
+ struct mbuf *_t; \
+ if ((off) == 0 && (m)->m_len >= len) \
+ (val) = (typ)mtod((m), void *); \
+ else { \
+ _t = m_pulldown((m), (off), (len), NULL); \
+ if (_t) { \
+ if (_t->m_len < (len)) \
+ panic("m_pulldown malfunction"); \
+ (val) = (typ)mtod(_t, void *); \
+ } else { \
+ (val) = (typ)NULL; \
+ (m) = NULL; \
+ } \
+ } \
+} while (/*CONSTCOND*/ 0)
+#endif /*_KERNEL*/
+
+#endif /* !_NETINET_IP6_H_ */
diff --git a/libc/kernel/arch-arm/asm/ptrace.h b/libc/kernel/arch-arm/asm/ptrace.h
index 3faf738..a04eec3 100644
--- a/libc/kernel/arch-arm/asm/ptrace.h
+++ b/libc/kernel/arch-arm/asm/ptrace.h
@@ -64,12 +64,7 @@
#ifndef __ASSEMBLY__
struct pt_regs {
- long uregs[18];
-};
-
-struct user_vfp {
- unsigned long long fpregs[32];
- unsigned long fpscr;
+ long uregs[18];
};
#define ARM_cpsr uregs[16]
diff --git a/libc/kernel/arch-arm/asm/user.h b/libc/kernel/arch-arm/asm/user.h
index 5f25850..d0baecd 100644
--- a/libc/kernel/arch-arm/asm/user.h
+++ b/libc/kernel/arch-arm/asm/user.h
@@ -58,4 +58,15 @@
#define HOST_TEXT_START_ADDR (u.start_code)
#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+struct user_vfp {
+ unsigned long long fpregs[32];
+ unsigned long fpscr;
+};
+
+struct user_vfp_exc {
+ unsigned long fpexc;
+ unsigned long fpinst;
+ unsigned long fpinst2;
+};
+
#endif
diff --git a/libc/kernel/common/linux/icmpv6.h b/libc/kernel/common/linux/icmpv6.h
new file mode 100644
index 0000000..d1be8cd
--- /dev/null
+++ b/libc/kernel/common/linux/icmpv6.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ICMPV6_H
+#define _LINUX_ICMPV6_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+struct icmp6hdr {
+
+ __u8 icmp6_type;
+ __u8 icmp6_code;
+ __sum16 icmp6_cksum;
+
+ union {
+ __be32 un_data32[1];
+ __be16 un_data16[2];
+ __u8 un_data8[4];
+
+ struct icmpv6_echo {
+ __be16 identifier;
+ __be16 sequence;
+ } u_echo;
+
+ struct icmpv6_nd_advt {
+#ifdef __LITTLE_ENDIAN_BITFIELD
+ __u32 reserved:5,
+ override:1,
+ solicited:1,
+ router:1,
+ reserved2:24;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u32 router:1,
+ solicited:1,
+ override:1,
+ reserved:29;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ } u_nd_advt;
+
+ struct icmpv6_nd_ra {
+ __u8 hop_limit;
+#ifdef __LITTLE_ENDIAN_BITFIELD
+ __u8 reserved:3,
+ router_pref:2,
+ home_agent:1,
+ other:1,
+ managed:1;
+
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 managed:1,
+ other:1,
+ home_agent:1,
+ router_pref:2,
+ reserved:3;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __be16 rt_lifetime;
+ } u_nd_ra;
+
+ } icmp6_dataun;
+
+#define icmp6_identifier icmp6_dataun.u_echo.identifier
+#define icmp6_sequence icmp6_dataun.u_echo.sequence
+#define icmp6_pointer icmp6_dataun.un_data32[0]
+#define icmp6_mtu icmp6_dataun.un_data32[0]
+#define icmp6_unused icmp6_dataun.un_data32[0]
+#define icmp6_maxdelay icmp6_dataun.un_data16[0]
+#define icmp6_router icmp6_dataun.u_nd_advt.router
+#define icmp6_solicited icmp6_dataun.u_nd_advt.solicited
+#define icmp6_override icmp6_dataun.u_nd_advt.override
+#define icmp6_ndiscreserved icmp6_dataun.u_nd_advt.reserved
+#define icmp6_hop_limit icmp6_dataun.u_nd_ra.hop_limit
+#define icmp6_addrconf_managed icmp6_dataun.u_nd_ra.managed
+#define icmp6_addrconf_other icmp6_dataun.u_nd_ra.other
+#define icmp6_rt_lifetime icmp6_dataun.u_nd_ra.rt_lifetime
+#define icmp6_router_pref icmp6_dataun.u_nd_ra.router_pref
+};
+
+#define ICMPV6_ROUTER_PREF_LOW 0x3
+#define ICMPV6_ROUTER_PREF_MEDIUM 0x0
+#define ICMPV6_ROUTER_PREF_HIGH 0x1
+#define ICMPV6_ROUTER_PREF_INVALID 0x2
+
+#define ICMPV6_DEST_UNREACH 1
+#define ICMPV6_PKT_TOOBIG 2
+#define ICMPV6_TIME_EXCEED 3
+#define ICMPV6_PARAMPROB 4
+
+#define ICMPV6_INFOMSG_MASK 0x80
+
+#define ICMPV6_ECHO_REQUEST 128
+#define ICMPV6_ECHO_REPLY 129
+#define ICMPV6_MGM_QUERY 130
+#define ICMPV6_MGM_REPORT 131
+#define ICMPV6_MGM_REDUCTION 132
+
+#define ICMPV6_NI_QUERY 139
+#define ICMPV6_NI_REPLY 140
+
+#define ICMPV6_MLD2_REPORT 143
+
+#define ICMPV6_DHAAD_REQUEST 144
+#define ICMPV6_DHAAD_REPLY 145
+#define ICMPV6_MOBILE_PREFIX_SOL 146
+#define ICMPV6_MOBILE_PREFIX_ADV 147
+
+#define ICMPV6_NOROUTE 0
+#define ICMPV6_ADM_PROHIBITED 1
+#define ICMPV6_NOT_NEIGHBOUR 2
+#define ICMPV6_ADDR_UNREACH 3
+#define ICMPV6_PORT_UNREACH 4
+
+#define ICMPV6_EXC_HOPLIMIT 0
+#define ICMPV6_EXC_FRAGTIME 1
+
+#define ICMPV6_HDR_FIELD 0
+#define ICMPV6_UNK_NEXTHDR 1
+#define ICMPV6_UNK_OPTION 2
+
+#define ICMPV6_FILTER 1
+
+#define ICMPV6_FILTER_BLOCK 1
+#define ICMPV6_FILTER_PASS 2
+#define ICMPV6_FILTER_BLOCKOTHERS 3
+#define ICMPV6_FILTER_PASSONLY 4
+
+struct icmp6_filter {
+ __u32 data[8];
+};
+
+#define MLD2_MODE_IS_INCLUDE 1
+#define MLD2_MODE_IS_EXCLUDE 2
+#define MLD2_CHANGE_TO_INCLUDE 3
+#define MLD2_CHANGE_TO_EXCLUDE 4
+#define MLD2_ALLOW_NEW_SOURCES 5
+#define MLD2_BLOCK_OLD_SOURCES 6
+
+#define MLD2_ALL_MCR_INIT { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x16 } } }
+
+#endif
diff --git a/libc/kernel/common/linux/if_arp.h b/libc/kernel/common/linux/if_arp.h
index a3df6c8..d8a4001 100644
--- a/libc/kernel/common/linux/if_arp.h
+++ b/libc/kernel/common/linux/if_arp.h
@@ -77,6 +77,7 @@
#define ARPHRD_PHONET 820
#define ARPHRD_PHONET_PIPE 821
+#define ARPHRD_CAIF 822
#define ARPHRD_VOID 0xFFFF
#define ARPHRD_NONE 0xFFFE
@@ -111,8 +112,7 @@
#define ATF_NETMASK 0x20
#define ATF_DONTPUB 0x40
-struct arphdr
-{
+struct arphdr {
__be16 ar_hrd;
__be16 ar_pro;
unsigned char ar_hln;
@@ -122,3 +122,4 @@
};
#endif
+
diff --git a/libc/kernel/common/linux/if_link.h b/libc/kernel/common/linux/if_link.h
index e9d77d4..4b83760 100644
--- a/libc/kernel/common/linux/if_link.h
+++ b/libc/kernel/common/linux/if_link.h
@@ -15,8 +15,7 @@
#include <linux/types.h>
#include <linux/netlink.h>
-struct rtnl_link_stats
-{
+struct rtnl_link_stats {
__u32 rx_packets;
__u32 tx_packets;
__u32 rx_bytes;
@@ -45,8 +44,36 @@
__u32 tx_compressed;
};
-struct rtnl_link_ifmap
-{
+struct rtnl_link_stats64 {
+ __u64 rx_packets;
+ __u64 tx_packets;
+ __u64 rx_bytes;
+ __u64 tx_bytes;
+ __u64 rx_errors;
+ __u64 tx_errors;
+ __u64 rx_dropped;
+ __u64 tx_dropped;
+ __u64 multicast;
+ __u64 collisions;
+
+ __u64 rx_length_errors;
+ __u64 rx_over_errors;
+ __u64 rx_crc_errors;
+ __u64 rx_frame_errors;
+ __u64 rx_fifo_errors;
+ __u64 rx_missed_errors;
+
+ __u64 tx_aborted_errors;
+ __u64 tx_carrier_errors;
+ __u64 tx_fifo_errors;
+ __u64 tx_heartbeat_errors;
+ __u64 tx_window_errors;
+
+ __u64 rx_compressed;
+ __u64 tx_compressed;
+};
+
+struct rtnl_link_ifmap {
__u64 mem_start;
__u64 mem_end;
__u64 base_addr;
@@ -55,8 +82,7 @@
__u8 port;
};
-enum
-{
+enum {
IFLA_UNSPEC,
IFLA_ADDRESS,
IFLA_BROADCAST,
@@ -87,6 +113,11 @@
#define IFLA_LINKINFO IFLA_LINKINFO
IFLA_NET_NS_PID,
IFLA_IFALIAS,
+ IFLA_NUM_VF,
+ IFLA_VFINFO_LIST,
+ IFLA_STATS64,
+ IFLA_VF_PORTS,
+ IFLA_PORT_SELF,
__IFLA_MAX
};
@@ -95,8 +126,7 @@
#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
-enum
-{
+enum {
IFLA_INET6_UNSPEC,
IFLA_INET6_FLAGS,
IFLA_INET6_CONF,
@@ -109,16 +139,14 @@
#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
-struct ifla_cacheinfo
-{
+struct ifla_cacheinfo {
__u32 max_reasm_len;
__u32 tstamp;
__u32 reachable_time;
__u32 retrans_time;
};
-enum
-{
+enum {
IFLA_INFO_UNSPEC,
IFLA_INFO_KIND,
IFLA_INFO_DATA,
@@ -128,8 +156,7 @@
#define IFLA_INFO_MAX (__IFLA_INFO_MAX - 1)
-enum
-{
+enum {
IFLA_VLAN_UNSPEC,
IFLA_VLAN_ID,
IFLA_VLAN_FLAGS,
@@ -145,8 +172,7 @@
__u32 mask;
};
-enum
-{
+enum {
IFLA_VLAN_QOS_UNSPEC,
IFLA_VLAN_QOS_MAPPING,
__IFLA_VLAN_QOS_MAX
@@ -154,10 +180,123 @@
#define IFLA_VLAN_QOS_MAX (__IFLA_VLAN_QOS_MAX - 1)
-struct ifla_vlan_qos_mapping
-{
+struct ifla_vlan_qos_mapping {
__u32 from;
__u32 to;
};
+enum {
+ IFLA_MACVLAN_UNSPEC,
+ IFLA_MACVLAN_MODE,
+ __IFLA_MACVLAN_MAX,
+};
+
+#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
+
+enum macvlan_mode {
+ MACVLAN_MODE_PRIVATE = 1,
+ MACVLAN_MODE_VEPA = 2,
+ MACVLAN_MODE_BRIDGE = 4,
+};
+
+enum {
+ IFLA_VF_INFO_UNSPEC,
+ IFLA_VF_INFO,
+ __IFLA_VF_INFO_MAX,
+};
+
+#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
+
+enum {
+ IFLA_VF_UNSPEC,
+ IFLA_VF_MAC,
+ IFLA_VF_VLAN,
+ IFLA_VF_TX_RATE,
+ __IFLA_VF_MAX,
+};
+
+#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
+
+struct ifla_vf_mac {
+ __u32 vf;
+ __u8 mac[32];
+};
+
+struct ifla_vf_vlan {
+ __u32 vf;
+ __u32 vlan;
+ __u32 qos;
+};
+
+struct ifla_vf_tx_rate {
+ __u32 vf;
+ __u32 rate;
+};
+
+struct ifla_vf_info {
+ __u32 vf;
+ __u8 mac[32];
+ __u32 vlan;
+ __u32 qos;
+ __u32 tx_rate;
+};
+
+enum {
+ IFLA_VF_PORT_UNSPEC,
+ IFLA_VF_PORT,
+ __IFLA_VF_PORT_MAX,
+};
+
+#define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1)
+
+enum {
+ IFLA_PORT_UNSPEC,
+ IFLA_PORT_VF,
+ IFLA_PORT_PROFILE,
+ IFLA_PORT_VSI_TYPE,
+ IFLA_PORT_INSTANCE_UUID,
+ IFLA_PORT_HOST_UUID,
+ IFLA_PORT_REQUEST,
+ IFLA_PORT_RESPONSE,
+ __IFLA_PORT_MAX,
+};
+
+#define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1)
+
+#define PORT_PROFILE_MAX 40
+#define PORT_UUID_MAX 16
+#define PORT_SELF_VF -1
+
+enum {
+ PORT_REQUEST_PREASSOCIATE = 0,
+ PORT_REQUEST_PREASSOCIATE_RR,
+ PORT_REQUEST_ASSOCIATE,
+ PORT_REQUEST_DISASSOCIATE,
+};
+
+enum {
+ PORT_VDP_RESPONSE_SUCCESS = 0,
+ PORT_VDP_RESPONSE_INVALID_FORMAT,
+ PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES,
+ PORT_VDP_RESPONSE_UNUSED_VTID,
+ PORT_VDP_RESPONSE_VTID_VIOLATION,
+ PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION,
+ PORT_VDP_RESPONSE_OUT_OF_SYNC,
+
+ PORT_PROFILE_RESPONSE_SUCCESS = 0x100,
+ PORT_PROFILE_RESPONSE_INPROGRESS,
+ PORT_PROFILE_RESPONSE_INVALID,
+ PORT_PROFILE_RESPONSE_BADSTATE,
+ PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES,
+ PORT_PROFILE_RESPONSE_ERROR,
+};
+
+struct ifla_port_vsi {
+ __u8 vsi_mgr_id;
+ __u8 vsi_type_id[3];
+ __u8 vsi_type_version;
+ __u8 pad[3];
+};
+
#endif
+
diff --git a/libc/kernel/common/linux/if_tun.h b/libc/kernel/common/linux/if_tun.h
index c5db4e0..9ed49f1 100644
--- a/libc/kernel/common/linux/if_tun.h
+++ b/libc/kernel/common/linux/if_tun.h
@@ -12,6 +12,10 @@
#ifndef __IF_TUN_H
#define __IF_TUN_H
+#include <linux/types.h>
+#include <linux/if_ether.h>
+#include <linux/filter.h>
+
#define TUN_READQ_SIZE 500
#define TUN_TUN_DEV 0x0001
@@ -23,6 +27,7 @@
#define TUN_NO_PI 0x0040
#define TUN_ONE_QUEUE 0x0080
#define TUN_PERSIST 0x0100
+#define TUN_VNET_HDR 0x0200
#define TUNSETNOCSUM _IOW('T', 200, int)
#define TUNSETDEBUG _IOW('T', 201, int)
@@ -30,16 +35,43 @@
#define TUNSETPERSIST _IOW('T', 203, int)
#define TUNSETOWNER _IOW('T', 204, int)
#define TUNSETLINK _IOW('T', 205, int)
+#define TUNSETGROUP _IOW('T', 206, int)
+#define TUNGETFEATURES _IOR('T', 207, unsigned int)
+#define TUNSETOFFLOAD _IOW('T', 208, unsigned int)
+#define TUNSETTXFILTER _IOW('T', 209, unsigned int)
+#define TUNGETIFF _IOR('T', 210, unsigned int)
+#define TUNGETSNDBUF _IOR('T', 211, int)
+#define TUNSETSNDBUF _IOW('T', 212, int)
+#define TUNATTACHFILTER _IOW('T', 213, struct sock_fprog)
+#define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog)
+#define TUNGETVNETHDRSZ _IOR('T', 215, int)
+#define TUNSETVNETHDRSZ _IOW('T', 216, int)
#define IFF_TUN 0x0001
#define IFF_TAP 0x0002
#define IFF_NO_PI 0x1000
#define IFF_ONE_QUEUE 0x2000
+#define IFF_VNET_HDR 0x4000
+#define IFF_TUN_EXCL 0x8000
-struct tun_pi {
- unsigned short flags;
- unsigned short proto;
-};
+#define TUN_F_CSUM 0x01
+#define TUN_F_TSO4 0x02
+#define TUN_F_TSO6 0x04
+#define TUN_F_TSO_ECN 0x08
+#define TUN_F_UFO 0x10
+
#define TUN_PKT_STRIP 0x0001
+struct tun_pi {
+ __u16 flags;
+ __be16 proto;
+};
+
+#define TUN_FLT_ALLMULTI 0x0001
+struct tun_filter {
+ __u16 flags;
+ __u16 count;
+ __u8 addr[0][ETH_ALEN];
+};
#endif
+
diff --git a/libc/kernel/common/linux/in6.h b/libc/kernel/common/linux/in6.h
index ceaeb7d..d148dfd 100644
--- a/libc/kernel/common/linux/in6.h
+++ b/libc/kernel/common/linux/in6.h
@@ -14,25 +14,21 @@
#include <linux/types.h>
-struct in6_addr
-{
- union
- {
+struct in6_addr {
+ union {
__u8 u6_addr8[16];
- __u16 u6_addr16[8];
- __u32 u6_addr32[4];
+ __be16 u6_addr16[8];
+ __be32 u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
};
-#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
-
struct sockaddr_in6 {
unsigned short int sin6_family;
- __u16 sin6_port;
- __u32 sin6_flowinfo;
+ __be16 sin6_port;
+ __be32 sin6_flowinfo;
struct in6_addr sin6_addr;
__u32 sin6_scope_id;
};
@@ -46,10 +42,9 @@
#define ipv6mr_acaddr ipv6mr_multiaddr
-struct in6_flowlabel_req
-{
+struct in6_flowlabel_req {
struct in6_addr flr_dst;
- __u32 flr_label;
+ __be32 flr_label;
__u8 flr_action;
__u8 flr_share;
__u16 flr_flags;
@@ -98,11 +93,13 @@
#define IPPROTO_ICMPV6 58
#define IPPROTO_NONE 59
#define IPPROTO_DSTOPTS 60
+#define IPPROTO_MH 135
#define IPV6_TLV_PAD0 0
#define IPV6_TLV_PADN 1
#define IPV6_TLV_ROUTERALERT 5
#define IPV6_TLV_JUMBO 194
+#define IPV6_TLV_HAO 201
#define IPV6_ADDRFORM 1
#define IPV6_2292PKTINFO 2
@@ -133,6 +130,7 @@
#define IPV6_PMTUDISC_DONT 0
#define IPV6_PMTUDISC_WANT 1
#define IPV6_PMTUDISC_DO 2
+#define IPV6_PMTUDISC_PROBE 3
#define IPV6_FLOWLABEL_MGR 32
#define IPV6_FLOWINFO_SEND 33
@@ -151,8 +149,27 @@
#define IPV6_RTHDR 57
#define IPV6_RECVDSTOPTS 58
#define IPV6_DSTOPTS 59
+#define IPV6_RECVPATHMTU 60
+#define IPV6_PATHMTU 61
+#define IPV6_DONTFRAG 62
#define IPV6_RECVTCLASS 66
#define IPV6_TCLASS 67
+#define IPV6_ADDR_PREFERENCES 72
+
+#define IPV6_PREFER_SRC_TMP 0x0001
+#define IPV6_PREFER_SRC_PUBLIC 0x0002
+#define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100
+#define IPV6_PREFER_SRC_COA 0x0004
+#define IPV6_PREFER_SRC_HOME 0x0400
+#define IPV6_PREFER_SRC_CGA 0x0008
+#define IPV6_PREFER_SRC_NONCGA 0x0800
+
+#define IPV6_MINHOPCOUNT 73
+
+#define IPV6_ORIGDSTADDR 74
+#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR
+#define IPV6_TRANSPARENT 75
+
#endif
diff --git a/libc/kernel/common/linux/ipv6.h b/libc/kernel/common/linux/ipv6.h
new file mode 100644
index 0000000..f4ee9a1
--- /dev/null
+++ b/libc/kernel/common/linux/ipv6.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPV6_H
+#define _IPV6_H
+
+#include <linux/types.h>
+#include <linux/in6.h>
+#include <asm/byteorder.h>
+
+#define IPV6_MIN_MTU 1280
+
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr;
+ int ipi6_ifindex;
+};
+
+struct ip6_mtuinfo {
+ struct sockaddr_in6 ip6m_addr;
+ __u32 ip6m_mtu;
+};
+
+struct in6_ifreq {
+ struct in6_addr ifr6_addr;
+ __u32 ifr6_prefixlen;
+ int ifr6_ifindex;
+};
+
+#define IPV6_SRCRT_STRICT 0x01
+#define IPV6_SRCRT_TYPE_0 0
+#define IPV6_SRCRT_TYPE_2 2
+
+struct ipv6_rt_hdr {
+ __u8 nexthdr;
+ __u8 hdrlen;
+ __u8 type;
+ __u8 segments_left;
+
+};
+
+struct ipv6_opt_hdr {
+ __u8 nexthdr;
+ __u8 hdrlen;
+
+} __attribute__((packed));
+
+#define ipv6_destopt_hdr ipv6_opt_hdr
+#define ipv6_hopopt_hdr ipv6_opt_hdr
+
+struct rt0_hdr {
+ struct ipv6_rt_hdr rt_hdr;
+ __u32 reserved;
+ struct in6_addr addr[0];
+
+#define rt0_type rt_hdr.type
+};
+
+struct rt2_hdr {
+ struct ipv6_rt_hdr rt_hdr;
+ __u32 reserved;
+ struct in6_addr addr;
+
+#define rt2_type rt_hdr.type
+};
+
+struct ipv6_destopt_hao {
+ __u8 type;
+ __u8 length;
+ struct in6_addr addr;
+} __attribute__((packed));
+
+struct ipv6hdr {
+#ifdef __LITTLE_ENDIAN_BITFIELD
+ __u8 priority:4,
+ version:4;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 version:4,
+ priority:4;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __u8 flow_lbl[3];
+
+ __be16 payload_len;
+ __u8 nexthdr;
+ __u8 hop_limit;
+
+ struct in6_addr saddr;
+ struct in6_addr daddr;
+};
+
+enum {
+ DEVCONF_FORWARDING = 0,
+ DEVCONF_HOPLIMIT,
+ DEVCONF_MTU6,
+ DEVCONF_ACCEPT_RA,
+ DEVCONF_ACCEPT_REDIRECTS,
+ DEVCONF_AUTOCONF,
+ DEVCONF_DAD_TRANSMITS,
+ DEVCONF_RTR_SOLICITS,
+ DEVCONF_RTR_SOLICIT_INTERVAL,
+ DEVCONF_RTR_SOLICIT_DELAY,
+ DEVCONF_USE_TEMPADDR,
+ DEVCONF_TEMP_VALID_LFT,
+ DEVCONF_TEMP_PREFERED_LFT,
+ DEVCONF_REGEN_MAX_RETRY,
+ DEVCONF_MAX_DESYNC_FACTOR,
+ DEVCONF_MAX_ADDRESSES,
+ DEVCONF_FORCE_MLD_VERSION,
+ DEVCONF_ACCEPT_RA_DEFRTR,
+ DEVCONF_ACCEPT_RA_PINFO,
+ DEVCONF_ACCEPT_RA_RTR_PREF,
+ DEVCONF_RTR_PROBE_INTERVAL,
+ DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
+ DEVCONF_PROXY_NDP,
+ DEVCONF_OPTIMISTIC_DAD,
+ DEVCONF_ACCEPT_SOURCE_ROUTE,
+ DEVCONF_MC_FORWARDING,
+ DEVCONF_DISABLE_IPV6,
+ DEVCONF_ACCEPT_DAD,
+ DEVCONF_FORCE_TLLAO,
+ DEVCONF_MAX
+};
+
+#endif
diff --git a/libc/kernel/common/linux/mroute6.h b/libc/kernel/common/linux/mroute6.h
new file mode 100644
index 0000000..2b151b9
--- /dev/null
+++ b/libc/kernel/common/linux/mroute6.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_MROUTE6_H
+#define __LINUX_MROUTE6_H
+
+#include <linux/types.h>
+#include <linux/sockios.h>
+
+#define MRT6_BASE 200
+#define MRT6_INIT (MRT6_BASE)
+#define MRT6_DONE (MRT6_BASE+1)
+#define MRT6_ADD_MIF (MRT6_BASE+2)
+#define MRT6_DEL_MIF (MRT6_BASE+3)
+#define MRT6_ADD_MFC (MRT6_BASE+4)
+#define MRT6_DEL_MFC (MRT6_BASE+5)
+#define MRT6_VERSION (MRT6_BASE+6)
+#define MRT6_ASSERT (MRT6_BASE+7)
+#define MRT6_PIM (MRT6_BASE+8)
+#define MRT6_TABLE (MRT6_BASE+9)
+
+#define SIOCGETMIFCNT_IN6 SIOCPROTOPRIVATE
+#define SIOCGETSGCNT_IN6 (SIOCPROTOPRIVATE+1)
+#define SIOCGETRPF (SIOCPROTOPRIVATE+2)
+
+#define MAXMIFS 32
+typedef unsigned long mifbitmap_t;
+typedef unsigned short mifi_t;
+#define ALL_MIFS ((mifi_t)(-1))
+
+#ifndef IF_SETSIZE
+#define IF_SETSIZE 256
+#endif
+
+typedef __u32 if_mask;
+#define NIFBITS (sizeof(if_mask) * 8)
+
+#ifndef DIV_ROUND_UP
+#define DIV_ROUND_UP(x,y) (((x) + ((y) - 1)) / (y))
+#endif
+
+typedef struct if_set {
+ if_mask ifs_bits[DIV_ROUND_UP(IF_SETSIZE, NIFBITS)];
+} if_set;
+
+#define IF_SET(n, p) ((p)->ifs_bits[(n)/NIFBITS] |= (1 << ((n) % NIFBITS)))
+#define IF_CLR(n, p) ((p)->ifs_bits[(n)/NIFBITS] &= ~(1 << ((n) % NIFBITS)))
+#define IF_ISSET(n, p) ((p)->ifs_bits[(n)/NIFBITS] & (1 << ((n) % NIFBITS)))
+#define IF_COPY(f, t) bcopy(f, t, sizeof(*(f)))
+#define IF_ZERO(p) bzero(p, sizeof(*(p)))
+
+struct mif6ctl {
+ mifi_t mif6c_mifi;
+ unsigned char mif6c_flags;
+ unsigned char vifc_threshold;
+ __u16 mif6c_pifi;
+ unsigned int vifc_rate_limit;
+};
+
+#define MIFF_REGISTER 0x1
+
+struct mf6cctl {
+ struct sockaddr_in6 mf6cc_origin;
+ struct sockaddr_in6 mf6cc_mcastgrp;
+ mifi_t mf6cc_parent;
+ struct if_set mf6cc_ifset;
+};
+
+struct sioc_sg_req6 {
+ struct sockaddr_in6 src;
+ struct sockaddr_in6 grp;
+ unsigned long pktcnt;
+ unsigned long bytecnt;
+ unsigned long wrong_if;
+};
+
+struct sioc_mif_req6 {
+ mifi_t mifi;
+ unsigned long icount;
+ unsigned long ocount;
+ unsigned long ibytes;
+ unsigned long obytes;
+};
+
+struct mrt6msg {
+#define MRT6MSG_NOCACHE 1
+#define MRT6MSG_WRONGMIF 2
+#define MRT6MSG_WHOLEPKT 3
+ __u8 im6_mbz;
+ __u8 im6_msgtype;
+ __u16 im6_mif;
+ __u32 im6_pad;
+ struct in6_addr im6_src, im6_dst;
+};
+
+#endif
diff --git a/libc/kernel/common/linux/netfilter_ipv6.h b/libc/kernel/common/linux/netfilter_ipv6.h
index 0d68cd9..ce2f12c 100644
--- a/libc/kernel/common/linux/netfilter_ipv6.h
+++ b/libc/kernel/common/linux/netfilter_ipv6.h
@@ -52,13 +52,13 @@
enum nf_ip6_hook_priorities {
NF_IP6_PRI_FIRST = INT_MIN,
NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
+ NF_IP6_PRI_RAW = -300,
NF_IP6_PRI_SELINUX_FIRST = -225,
NF_IP6_PRI_CONNTRACK = -200,
- NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
NF_IP6_PRI_MANGLE = -150,
NF_IP6_PRI_NAT_DST = -100,
- NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
NF_IP6_PRI_FILTER = 0,
+ NF_IP6_PRI_SECURITY = 50,
NF_IP6_PRI_NAT_SRC = 100,
NF_IP6_PRI_SELINUX_LAST = 225,
NF_IP6_PRI_LAST = INT_MAX,
diff --git a/libc/kernel/common/linux/rtnetlink.h b/libc/kernel/common/linux/rtnetlink.h
index e305505..bbd991a 100644
--- a/libc/kernel/common/linux/rtnetlink.h
+++ b/libc/kernel/common/linux/rtnetlink.h
@@ -18,6 +18,10 @@
#include <linux/if_addr.h>
#include <linux/neighbour.h>
+#define RTNL_FAMILY_IPMR 128
+#define RTNL_FAMILY_IP6MR 129
+#define RTNL_FAMILY_MAX 129
+
enum {
RTM_BASE = 16,
#define RTM_BASE RTM_BASE
@@ -126,8 +130,7 @@
#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
-struct rtattr
-{
+struct rtattr {
unsigned short rta_len;
unsigned short rta_type;
};
@@ -141,8 +144,7 @@
#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
-struct rtmsg
-{
+struct rtmsg {
unsigned char rtm_family;
unsigned char rtm_dst_len;
unsigned char rtm_src_len;
@@ -156,8 +158,7 @@
unsigned rtm_flags;
};
-enum
-{
+enum {
RTN_UNSPEC,
RTN_UNICAST,
RTN_LOCAL,
@@ -191,8 +192,7 @@
#define RTPROT_NTK 15
#define RTPROT_DHCP 16
-enum rt_scope_t
-{
+enum rt_scope_t {
RT_SCOPE_UNIVERSE=0,
RT_SCOPE_SITE=200,
@@ -206,8 +206,7 @@
#define RTM_F_EQUALIZE 0x400
#define RTM_F_PREFIX 0x800
-enum rt_class_t
-{
+enum rt_class_t {
RT_TABLE_UNSPEC=0,
RT_TABLE_COMPAT=252,
@@ -217,8 +216,7 @@
RT_TABLE_MAX=0xFFFFFFFF
};
-enum rtattr_type_t
-{
+enum rtattr_type_t {
RTA_UNSPEC,
RTA_DST,
RTA_SRC,
@@ -235,6 +233,7 @@
RTA_SESSION,
RTA_MP_ALGO,
RTA_TABLE,
+ RTA_MARK,
__RTA_MAX
};
@@ -243,8 +242,7 @@
#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
-struct rtnexthop
-{
+struct rtnexthop {
unsigned short rtnh_len;
unsigned char rtnh_flags;
unsigned char rtnh_hops;
@@ -263,8 +261,7 @@
#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
-struct rta_cacheinfo
-{
+struct rta_cacheinfo {
__u32 rta_clntref;
__u32 rta_lastuse;
__s32 rta_expires;
@@ -277,8 +274,7 @@
__u32 rta_tsage;
};
-enum
-{
+enum {
RTAX_UNSPEC,
#define RTAX_UNSPEC RTAX_UNSPEC
RTAX_LOCK,
@@ -307,6 +303,8 @@
#define RTAX_FEATURES RTAX_FEATURES
RTAX_RTO_MIN,
#define RTAX_RTO_MIN RTAX_RTO_MIN
+ RTAX_INITRWND,
+#define RTAX_INITRWND RTAX_INITRWND
__RTAX_MAX
};
@@ -317,8 +315,7 @@
#define RTAX_FEATURE_TIMESTAMP 0x00000004
#define RTAX_FEATURE_ALLFRAG 0x00000008
-struct rta_session
-{
+struct rta_session {
__u8 proto;
__u8 pad1;
__u16 pad2;
@@ -339,13 +336,11 @@
} u;
};
-struct rtgenmsg
-{
+struct rtgenmsg {
unsigned char rtgen_family;
};
-struct ifinfomsg
-{
+struct ifinfomsg {
unsigned char ifi_family;
unsigned char __ifi_pad;
unsigned short ifi_type;
@@ -354,8 +349,7 @@
unsigned ifi_change;
};
-struct prefixmsg
-{
+struct prefixmsg {
unsigned char prefix_family;
unsigned char prefix_pad1;
unsigned short prefix_pad2;
@@ -376,14 +370,12 @@
#define PREFIX_MAX (__PREFIX_MAX - 1)
-struct prefix_cacheinfo
-{
+struct prefix_cacheinfo {
__u32 preferred_time;
__u32 valid_time;
};
-struct tcmsg
-{
+struct tcmsg {
unsigned char tcm_family;
unsigned char tcm__pad1;
unsigned short tcm__pad2;
@@ -393,8 +385,7 @@
__u32 tcm_info;
};
-enum
-{
+enum {
TCA_UNSPEC,
TCA_KIND,
TCA_OPTIONS,
@@ -412,8 +403,7 @@
#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
-struct nduseroptmsg
-{
+struct nduseroptmsg {
unsigned char nduseropt_family;
unsigned char nduseropt_pad1;
unsigned short nduseropt_opts_len;
@@ -425,8 +415,7 @@
};
-enum
-{
+enum {
NDUSEROPT_UNSPEC,
NDUSEROPT_SRCADDR,
__NDUSEROPT_MAX
@@ -503,8 +492,7 @@
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
-struct tcamsg
-{
+struct tcamsg {
unsigned char tca_family;
unsigned char tca__pad1;
unsigned short tca__pad2;
@@ -515,3 +503,4 @@
#define TCAA_MAX 1
#endif
+
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index ca7e6bb..5e9d6770 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -45,7 +45,7 @@
# Replace tokens in the output according to this mapping
kernel_token_replacements = {
- {"asm": "__asm__"},
+ "asm": "__asm__",
}
# this is the set of known static inline functions that we want to keep
diff --git a/libc/stdio/fvwrite.c b/libc/stdio/fvwrite.c
index 57a57e6..39d0604 100644
--- a/libc/stdio/fvwrite.c
+++ b/libc/stdio/fvwrite.c
@@ -48,7 +48,7 @@
__sfvwrite(FILE *fp, struct __suio *uio)
{
size_t len;
- char *p;
+ const char *p;
struct __siov *iov;
int w, s;
char *nl;
diff --git a/libc/stdio/fvwrite.h b/libc/stdio/fvwrite.h
index 2344e42..96f65de 100644
--- a/libc/stdio/fvwrite.h
+++ b/libc/stdio/fvwrite.h
@@ -36,7 +36,7 @@
* I/O descriptors for __sfvwrite().
*/
struct __siov {
- void *iov_base;
+ const void *iov_base;
size_t iov_len;
};
struct __suio {
diff --git a/libc/stdio/vfprintf.c b/libc/stdio/vfprintf.c
index 2ce0361..9c36b79 100644
--- a/libc/stdio/vfprintf.c
+++ b/libc/stdio/vfprintf.c
@@ -203,9 +203,9 @@
* below longer.
*/
#define PADSIZE 16 /* pad chunk size */
- static char blanks[PADSIZE] =
+ static const char blanks[PADSIZE] =
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
- static char zeroes[PADSIZE] =
+ static const char zeroes[PADSIZE] =
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
/*
@@ -1219,7 +1219,6 @@
{
int mode, dsgn;
char *digits, *bp, *rve;
- static char temp[64];
if (ch == 'f') {
mode = 3; /* ndigits after the decimal point */
diff --git a/libc/stdlib/strtod.c b/libc/stdlib/strtod.c
index 2851506..ab637a1 100644
--- a/libc/stdlib/strtod.c
+++ b/libc/stdlib/strtod.c
@@ -754,6 +754,7 @@
}
static Bigint *p5s;
+ static pthread_mutex_t p5s_mutex = PTHREAD_MUTEX_INITIALIZER;
static Bigint *
pow5mult
@@ -775,11 +776,13 @@
if (!(k = (unsigned int) k >> 2))
return b;
+ mutex_lock(&p5s_mutex);
if (!(p5 = p5s)) {
/* first time */
p5 = i2b(625);
if (p5 == BIGINT_INVALID) {
Bfree(b);
+ mutex_unlock(&p5s_mutex);
return p5;
}
p5s = p5;
@@ -797,6 +800,7 @@
p51 = mult(p5,p5);
if (p51 == BIGINT_INVALID) {
Bfree(b);
+ mutex_unlock(&p5s_mutex);
return p51;
}
p5->next = p51;
@@ -804,6 +808,7 @@
}
p5 = p51;
}
+ mutex_unlock(&p5s_mutex);
return b;
}
diff --git a/libc/tzcode/strptime.c b/libc/tzcode/strptime.c
index 1f481c9..0567aa4 100644
--- a/libc/tzcode/strptime.c
+++ b/libc/tzcode/strptime.c
@@ -89,29 +89,31 @@
#define _LEGAL_ALT(x) { if (alt_format & ~(x)) return (0); }
+struct century_relyear {
+ int century;
+ int relyear;
+};
static int _conv_num(const unsigned char **, int *, int, int);
-static unsigned char *_strptime(const unsigned char *, const char *, struct tm *, int);
+static unsigned char *_strptime(const unsigned char *, const char *, struct tm *,
+ struct century_relyear *);
char *
strptime(const char *buf, const char *fmt, struct tm *tm)
{
- return (char*)(_strptime((const unsigned char*)buf, fmt, tm, 1));
+ struct century_relyear cr;
+ cr.century = TM_YEAR_BASE;
+ cr.relyear = -1;
+ return (char*)(_strptime((const unsigned char*)buf, fmt, tm, &cr));
}
static unsigned char *
-_strptime(const unsigned char *buf, const char *fmt, struct tm *tm, int initialize)
+_strptime(const unsigned char *buf, const char *fmt, struct tm *tm, struct century_relyear *cr)
{
unsigned char c;
const unsigned char *bp;
size_t len = 0;
int alt_format, i;
- static int century, relyear;
-
- if (initialize) {
- century = TM_YEAR_BASE;
- relyear = -1;
- }
bp = (unsigned char *)buf;
while ((c = *fmt) != '\0') {
@@ -158,43 +160,43 @@
*/
case 'c': /* Date and time, using the locale's format. */
_LEGAL_ALT(_ALT_E);
- if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, 0)))
+ if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, cr)))
return (NULL);
break;
case 'D': /* The date as "%m/%d/%y". */
_LEGAL_ALT(0);
- if (!(bp = _strptime(bp, "%m/%d/%y", tm, 0)))
+ if (!(bp = _strptime(bp, "%m/%d/%y", tm, cr)))
return (NULL);
break;
case 'R': /* The time as "%H:%M". */
_LEGAL_ALT(0);
- if (!(bp = _strptime(bp, "%H:%M", tm, 0)))
+ if (!(bp = _strptime(bp, "%H:%M", tm, cr)))
return (NULL);
break;
case 'r': /* The time as "%I:%M:%S %p". */
_LEGAL_ALT(0);
- if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, 0)))
+ if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, cr)))
return (NULL);
break;
case 'T': /* The time as "%H:%M:%S". */
_LEGAL_ALT(0);
- if (!(bp = _strptime(bp, "%H:%M:%S", tm, 0)))
+ if (!(bp = _strptime(bp, "%H:%M:%S", tm, cr)))
return (NULL);
break;
case 'X': /* The time, using the locale's format. */
_LEGAL_ALT(_ALT_E);
- if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, 0)))
+ if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, cr)))
return (NULL);
break;
case 'x': /* The date, using the locale's format. */
_LEGAL_ALT(_ALT_E);
- if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, 0)))
+ if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, cr)))
return (NULL);
break;
@@ -253,7 +255,7 @@
if (!(_conv_num(&bp, &i, 0, 99)))
return (NULL);
- century = i * 100;
+ cr->century = i * 100;
break;
case 'd': /* The day of month. */
@@ -359,13 +361,13 @@
if (!(_conv_num(&bp, &i, 0, 9999)))
return (NULL);
- relyear = -1;
+ cr->relyear = -1;
tm->tm_year = i - TM_YEAR_BASE;
break;
case 'y': /* The year within the century (2 digits). */
_LEGAL_ALT(_ALT_E | _ALT_O);
- if (!(_conv_num(&bp, &relyear, 0, 99)))
+ if (!(_conv_num(&bp, &cr->relyear, 0, 99)))
return (NULL);
break;
@@ -391,14 +393,14 @@
* We need to evaluate the two digit year spec (%y)
* last as we can get a century spec (%C) at any time.
*/
- if (relyear != -1) {
- if (century == TM_YEAR_BASE) {
- if (relyear <= 68)
- tm->tm_year = relyear + 2000 - TM_YEAR_BASE;
+ if (cr->relyear != -1) {
+ if (cr->century == TM_YEAR_BASE) {
+ if (cr->relyear <= 68)
+ tm->tm_year = cr->relyear + 2000 - TM_YEAR_BASE;
else
- tm->tm_year = relyear + 1900 - TM_YEAR_BASE;
+ tm->tm_year = cr->relyear + 1900 - TM_YEAR_BASE;
} else {
- tm->tm_year = relyear + century - TM_YEAR_BASE;
+ tm->tm_year = cr->relyear + cr->century - TM_YEAR_BASE;
}
}
diff --git a/libc/unistd/time.c b/libc/unistd/time.c
index 13d7366..4b51675 100644
--- a/libc/unistd/time.c
+++ b/libc/unistd/time.c
@@ -42,21 +42,29 @@
return (tt.tv_sec);
}
+// return monotonically increasing CPU time in ticks relative to unspecified epoch
+static inline clock_t clock_now(void)
+{
+ struct timespec tm;
+ clock_gettime( CLOCK_MONOTONIC, &tm);
+ return tm.tv_sec * CLOCKS_PER_SEC + (tm.tv_nsec * (CLOCKS_PER_SEC/1e9));
+}
+// initialized by the constructor below
+static clock_t clock_start;
+
+// called by dlopen when .so is loaded
+__attribute__((constructor)) static void clock_crt0(void)
+{
+ clock_start = clock_now();
+}
+
+// return elapsed CPU time in clock ticks, since start of program execution
+// (spec says epoch is undefined, but glibc uses crt0 as epoch)
clock_t
clock(void)
{
- struct timespec tm;
- static int clock_inited;
- static clock_t clock_start;
- clock_t now;
-
- clock_gettime( CLOCK_MONOTONIC, &tm);
- now = tm.tv_sec * CLOCKS_PER_SEC + (tm.tv_nsec * (CLOCKS_PER_SEC/1e9));
-
- if (!clock_inited) {
- clock_start = now;
- clock_inited = 1;
- }
- return now - clock_start;
+ // note that if we are executing in a different thread than crt0, then the
+ // pthread_create that made us had a memory barrier so clock_start is defined
+ return clock_now() - clock_start;
}
diff --git a/linker/README.TXT b/linker/README.TXT
index 052a65b..a8efe35 100644
--- a/linker/README.TXT
+++ b/linker/README.TXT
@@ -77,7 +77,7 @@
Same as DT_INITARRAY but for finalizers. Note that the
functions must be called in reverse-order though
- Note: this is generally stroed in a .fini_array section
+ Note: this is generally stored in a .fini_array section
DT_FINI_ARRAYSZ
Size of FT_FINIARRAY
@@ -88,7 +88,7 @@
a list of functions that need to be called before any other
initialization function (i.e. DT_INIT and/or DT_INIT_ARRAY)
- Note: this is generally stroed in a .preinit_array section
+ Note: this is generally stored in a .preinit_array section
DT_PREINIT_ARRAYSZ
The size of DT_PREINIT_ARRAY
@@ -103,14 +103,14 @@
much processor dependent, and may use different ELF sections.
On the ARM (see "C++ ABI for ARM" document), the static constructors
-must be called explicitely from the DT_INIT_ARRAY, and each one of them
+must be called explicitly from the DT_INIT_ARRAY, and each one of them
shall register a destructor by calling the special __eabi_atexit()
function (provided by the C library). The DT_FINI_ARRAY is not used
by static C++ destructors.
On x86, the lists of constructors and destructors are placed in special
sections named ".ctors" and ".dtors", and the DT_INIT / DT_FINI functions
-are in charge of calling them explicitely.
+are in charge of calling them explicitly.
Debugging:
@@ -140,4 +140,4 @@
By default, traces are sent to logcat, with the "linker" tag. You can
change this to go to stdout instead by setting the definition of
-LINKER_DEBUG_TO_LOG to 0 in "linker_debug.h"
+LINKER_DEBUG_TO_LOG to 0 in "linker_debug.h".