aboutsummaryrefslogtreecommitdiffstats
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/Android.mk1
-rw-r--r--libc/SYSCALLS.TXT2
-rw-r--r--libc/arch-sh/syscalls/__socketcall.S6
-rw-r--r--libc/bionic/md5.c2
-rw-r--r--libc/bionic/memmove_words.c147
-rw-r--r--libc/include/netinet/icmp6.h730
-rw-r--r--libc/include/netinet/in.h1
-rw-r--r--libc/include/netinet/in6.h1
-rw-r--r--libc/include/netinet/ip6.h319
-rw-r--r--libc/include/sys/linux-syscalls.h2
-rw-r--r--libc/kernel/arch-arm/asm/ptrace.h7
-rw-r--r--libc/kernel/arch-arm/asm/user.h11
-rw-r--r--libc/kernel/common/linux/icmpv6.h152
-rw-r--r--libc/kernel/common/linux/if_arp.h5
-rw-r--r--libc/kernel/common/linux/if_link.h175
-rw-r--r--libc/kernel/common/linux/if_tun.h38
-rw-r--r--libc/kernel/common/linux/in6.h43
-rw-r--r--libc/kernel/common/linux/ipv6.h133
-rw-r--r--libc/kernel/common/linux/mroute6.h104
-rw-r--r--libc/kernel/common/linux/netfilter_ipv6.h4
-rw-r--r--libc/kernel/common/linux/rtnetlink.h65
-rwxr-xr-xlibc/kernel/tools/clean_header.py41
-rw-r--r--libc/kernel/tools/cpp.py291
-rw-r--r--libc/kernel/tools/defaults.py20
-rwxr-xr-xlibc/kernel/tools/find_headers.py61
-rw-r--r--libc/kernel/tools/kernel.py7
-rwxr-xr-xlibc/kernel/tools/update_all.py47
-rw-r--r--libc/kernel/tools/utils.py27
-rw-r--r--libc/stdio/fvwrite.c2
-rw-r--r--libc/stdio/fvwrite.h2
-rw-r--r--libc/stdio/vfprintf.c5
-rw-r--r--libc/stdlib/strtod.c5
-rw-r--r--libc/tools/bionic_utils.py59
-rwxr-xr-xlibc/tools/checksyscalls.py85
-rwxr-xr-xlibc/tools/gensyscalls.py25
-rw-r--r--libc/tzcode/strptime.c52
-rw-r--r--libc/unistd/time.c34
37 files changed, 2346 insertions, 365 deletions
diff --git a/libc/Android.mk b/libc/Android.mk
index d94075376..647739ea4 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -269,6 +269,7 @@ libc_common_src_files := \
bionic/libc_init_common.c \
bionic/logd_write.c \
bionic/md5.c \
+ bionic/memmove_words.c \
bionic/pututline.c \
bionic/realpath.c \
bionic/sched_getaffinity.c \
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 5653c3cad..bd3e4d4e5 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -219,7 +219,7 @@ int sendmsg:socketcall:16(int, const struct msghdr *, unsigned int) -
int recvmsg:socketcall:17(int, struct msghdr *, unsigned int) -1,102,-1
# sockets for sh.
-int __socketcall:__socketcall(int, unsigned long*) -1,-1,102
+int __socketcall:socketcall(int, unsigned long*) -1,-1,102
# scheduler & real-time
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param) 156
diff --git a/libc/arch-sh/syscalls/__socketcall.S b/libc/arch-sh/syscalls/__socketcall.S
index 864e9aa01..7c705bbbc 100644
--- a/libc/arch-sh/syscalls/__socketcall.S
+++ b/libc/arch-sh/syscalls/__socketcall.S
@@ -14,7 +14,7 @@ __socketcall:
/* check return value */
cmp/pz r0
- bt __NR___socketcall_end
+ bt __NR_socketcall_end
/* keep error number */
sts.l pr, @-r15
@@ -23,10 +23,10 @@ __socketcall:
mov r0, r4
lds.l @r15+, pr
-__NR___socketcall_end:
+__NR_socketcall_end:
rts
nop
.align 2
-0: .long __NR___socketcall
+0: .long __NR_socketcall
1: .long __set_syscall_errno
diff --git a/libc/bionic/md5.c b/libc/bionic/md5.c
index 087786ff3..1117c3b7b 100644
--- a/libc/bionic/md5.c
+++ b/libc/bionic/md5.c
@@ -237,7 +237,7 @@ MD5_Update (struct md5 *m, const void *v, size_t len)
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/bionic/memmove_words.c b/libc/bionic/memmove_words.c
new file mode 100644
index 000000000..22058bce8
--- /dev/null
+++ b/libc/bionic/memmove_words.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+
+/*
+ * Works like memmove(), except:
+ * - if all arguments are at least 32-bit aligned, we guarantee that we
+ * will use operations that preserve atomicity of 32-bit values
+ * - if not, we guarantee atomicity of 16-bit values
+ *
+ * If all three arguments are not at least 16-bit aligned, the behavior
+ * of this function is undefined. (We could remove this restriction by
+ * testing for unaligned values and punting to memmove(), but that's
+ * not currently useful.)
+ *
+ * TODO: add loop for 64-bit alignment
+ * TODO: use __builtin_prefetch
+ * TODO: write an ARM-optimized version
+ */
+void _memmove_words(void* dest, const void* src, size_t n)
+{
+ assert((((uintptr_t) dest | (uintptr_t) src | n) & 0x01) == 0);
+
+ char* d = (char*) dest;
+ const char* s = (const char*) src;
+ size_t copyCount;
+
+ /*
+ * If the source and destination pointers are the same, this is
+ * an expensive no-op. Testing for an empty move now allows us
+ * to skip a check later.
+ */
+ if (n == 0 || d == s)
+ return;
+
+ /*
+ * Determine if the source and destination buffers will overlap if
+ * we copy data forward (i.e. *dest++ = *src++).
+ *
+ * It's okay if the destination buffer starts before the source and
+ * there is some overlap, because the reader is always ahead of the
+ * writer.
+ */
+ if (__builtin_expect((d < s) || ((size_t)(d - s) >= n), 1)) {
+ /*
+ * Copy forward. We prefer 32-bit loads and stores even for 16-bit
+ * data, so sort that out.
+ */
+ if ((((uintptr_t) d | (uintptr_t) s) & 0x03) != 0) {
+ /*
+ * Not 32-bit aligned. Two possibilities:
+ * (1) Congruent, we can align to 32-bit by copying one 16-bit val
+ * (2) Non-congruent, we can do one of:
+ * a. copy whole buffer as a series of 16-bit values
+ * b. load/store 32 bits, using shifts to ensure alignment
+ * c. just copy the as 32-bit values and assume the CPU
+ * will do a reasonable job
+ *
+ * We're currently using (a), which is suboptimal.
+ */
+ if ((((uintptr_t) d ^ (uintptr_t) s) & 0x03) != 0) {
+ copyCount = n;
+ } else {
+ copyCount = 2;
+ }
+ n -= copyCount;
+ copyCount /= sizeof(uint16_t);
+
+ while (copyCount--) {
+ *(uint16_t*)d = *(uint16_t*)s;
+ d += sizeof(uint16_t);
+ s += sizeof(uint16_t);
+ }
+ }
+
+ /*
+ * Copy 32-bit aligned words.
+ */
+ copyCount = n / sizeof(uint32_t);
+ while (copyCount--) {
+ *(uint32_t*)d = *(uint32_t*)s;
+ d += sizeof(uint32_t);
+ s += sizeof(uint32_t);
+ }
+
+ /*
+ * Check for leftovers. Either we finished exactly, or we have
+ * one remaining 16-bit chunk.
+ */
+ if ((n & 0x02) != 0) {
+ *(uint16_t*)d = *(uint16_t*)s;
+ }
+ } else {
+ /*
+ * Copy backward, starting at the end.
+ */
+ d += n;
+ s += n;
+
+ if ((((uintptr_t) d | (uintptr_t) s) & 0x03) != 0) {
+ /* try for 32-bit alignment */
+ if ((((uintptr_t) d ^ (uintptr_t) s) & 0x03) != 0) {
+ copyCount = n;
+ } else {
+ copyCount = 2;
+ }
+ n -= copyCount;
+ copyCount /= sizeof(uint16_t);
+
+ while (copyCount--) {
+ d -= sizeof(uint16_t);
+ s -= sizeof(uint16_t);
+ *(uint16_t*)d = *(uint16_t*)s;
+ }
+ }
+
+ /* copy 32-bit aligned words */
+ copyCount = n / sizeof(uint32_t);
+ while (copyCount--) {
+ d -= sizeof(uint32_t);
+ s -= sizeof(uint32_t);
+ *(uint32_t*)d = *(uint32_t*)s;
+ }
+
+ /* copy leftovers */
+ if ((n & 0x02) != 0) {
+ d -= sizeof(uint16_t);
+ s -= sizeof(uint16_t);
+ *(uint16_t*)d = *(uint16_t*)s;
+ }
+ }
+}
diff --git a/libc/include/netinet/icmp6.h b/libc/include/netinet/icmp6.h
new file mode 100644
index 000000000..fbc8234e3
--- /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 7a4b6c7b7..01bf58e48 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 580a510d2..7f3286ae9 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 000000000..aa816c241
--- /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/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h
index cb4d5e59e..5b8e2b48d 100644
--- a/libc/include/sys/linux-syscalls.h
+++ b/libc/include/sys/linux-syscalls.h
@@ -280,7 +280,7 @@
#define __NR_socketcall (__NR_SYSCALL_BASE + 102)
#define __NR_socketcall (__NR_SYSCALL_BASE + 102)
#define __NR_socketcall (__NR_SYSCALL_BASE + 102)
-#define __NR___socketcall (__NR_SYSCALL_BASE + 102)
+#define __NR_socketcall (__NR_SYSCALL_BASE + 102)
#define __NR_getcpu (__NR_SYSCALL_BASE + 318)
#define __NR_ioprio_set (__NR_SYSCALL_BASE + 288)
#define __NR_ioprio_get (__NR_SYSCALL_BASE + 289)
diff --git a/libc/kernel/arch-arm/asm/ptrace.h b/libc/kernel/arch-arm/asm/ptrace.h
index 3faf73892..a04eec386 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 5f258505f..d0baecd65 100644
--- a/libc/kernel/arch-arm/asm/user.h
+++ b/libc/kernel/arch-arm/asm/user.h
@@ -58,4 +58,15 @@ struct user{
#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 000000000..d1be8cded
--- /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 a3df6c83f..d8a400105 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 @@ struct arpreq_old {
#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 @@ struct arphdr
};
#endif
+
diff --git a/libc/kernel/common/linux/if_link.h b/libc/kernel/common/linux/if_link.h
index e9d77d48b..4b83760c8 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 @@ struct rtnl_link_stats
__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 @@ struct rtnl_link_ifmap
__u8 port;
};
-enum
-{
+enum {
IFLA_UNSPEC,
IFLA_ADDRESS,
IFLA_BROADCAST,
@@ -87,6 +113,11 @@ enum
#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 @@ enum
#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 @@ enum
#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 @@ enum
#define IFLA_INFO_MAX (__IFLA_INFO_MAX - 1)
-enum
-{
+enum {
IFLA_VLAN_UNSPEC,
IFLA_VLAN_ID,
IFLA_VLAN_FLAGS,
@@ -145,8 +172,7 @@ struct ifla_vlan_flags {
__u32 mask;
};
-enum
-{
+enum {
IFLA_VLAN_QOS_UNSPEC,
IFLA_VLAN_QOS_MAPPING,
__IFLA_VLAN_QOS_MAX
@@ -154,10 +180,123 @@ enum
#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 c5db4e02f..9ed49f1b7 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
+
+#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 {
- unsigned short flags;
- unsigned short proto;
+ __u16 flags;
+ __be16 proto;
+};
+
+#define TUN_FLT_ALLMULTI 0x0001
+struct tun_filter {
+ __u16 flags;
+ __u16 count;
+ __u8 addr[0][ETH_ALEN];
};
-#define TUN_PKT_STRIP 0x0001
#endif
+
diff --git a/libc/kernel/common/linux/in6.h b/libc/kernel/common/linux/in6.h
index ceaeb7da3..d148dfd38 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 @@ struct ipv6_mreq {
#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 @@ struct in6_flowlabel_req
#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 @@ struct in6_flowlabel_req
#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 @@ struct in6_flowlabel_req
#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 000000000..f4ee9a13d
--- /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 000000000..2b151b920
--- /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 0d68cd9c3..ce2f12c3e 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 e305505b0..bbd991ac4 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 @@ enum {
#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 @@ struct rtattr
#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 @@ struct rtmsg
unsigned rtm_flags;
};
-enum
-{
+enum {
RTN_UNSPEC,
RTN_UNICAST,
RTN_LOCAL,
@@ -191,8 +192,7 @@ enum
#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 @@ enum rt_scope_t
#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 @@ enum rt_class_t
RT_TABLE_MAX=0xFFFFFFFF
};
-enum rtattr_type_t
-{
+enum rtattr_type_t {
RTA_UNSPEC,
RTA_DST,
RTA_SRC,
@@ -235,6 +233,7 @@ enum rtattr_type_t
RTA_SESSION,
RTA_MP_ALGO,
RTA_TABLE,
+ RTA_MARK,
__RTA_MAX
};
@@ -243,8 +242,7 @@ enum rtattr_type_t
#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 @@ struct rtnexthop
#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 @@ struct rta_cacheinfo
__u32 rta_tsage;
};
-enum
-{
+enum {
RTAX_UNSPEC,
#define RTAX_UNSPEC RTAX_UNSPEC
RTAX_LOCK,
@@ -307,6 +303,8 @@ enum
#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 @@ enum
#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 @@ struct rta_session
} 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 @@ struct ifinfomsg
unsigned ifi_change;
};
-struct prefixmsg
-{
+struct prefixmsg {
unsigned char prefix_family;
unsigned char prefix_pad1;
unsigned short prefix_pad2;
@@ -376,14 +370,12 @@ enum
#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 @@ struct tcmsg
__u32 tcm_info;
};
-enum
-{
+enum {
TCA_UNSPEC,
TCA_KIND,
TCA_OPTIONS,
@@ -412,8 +403,7 @@ enum
#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 @@ struct nduseroptmsg
};
-enum
-{
+enum {
NDUSEROPT_UNSPEC,
NDUSEROPT_SRCADDR,
__NDUSEROPT_MAX
@@ -503,8 +492,7 @@ enum rtnetlink_groups {
};
#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 @@ struct tcamsg
#define TCAA_MAX 1
#endif
+
diff --git a/libc/kernel/tools/clean_header.py b/libc/kernel/tools/clean_header.py
index dad91206e..94b19cee8 100755
--- a/libc/kernel/tools/clean_header.py
+++ b/libc/kernel/tools/clean_header.py
@@ -7,12 +7,12 @@ from utils import *
noUpdate = 1
-def cleanupFile( path ):
+def cleanupFile( path, original_path=kernel_original_path ):
"""reads an original header and perform the cleanup operation on it
this functions returns the destination path and the clean header
as a single string"""
# check the header path
- src_path = path
+ src_path = path
if not os.path.exists(src_path):
if noUpdate:
@@ -26,7 +26,6 @@ def cleanupFile( path ):
sys.stderr.write( "warning: not a file: %s\n" % path )
return None, None
- original_path = kernel_original_path
if os.path.commonprefix( [ src_path, original_path ] ) != original_path:
if noUpdate:
panic( "file is not in 'original' directory: %s\n" % path );
@@ -54,27 +53,27 @@ def cleanupFile( path ):
else:
dst_path = "common/" + src_path
- dst_path = os.path.normpath( original_path + "/../" + dst_path )
+ dst_path = os.path.normpath( kernel_cleaned_path + "/" + dst_path )
# now, let's parse the file
#
- list = cpp.BlockParser().parseFile(path)
- if not list:
+ blocks = cpp.BlockParser().parseFile(path)
+ if not blocks:
sys.stderr.write( "error: can't parse '%s'" % path )
sys.exit(1)
- list.optimizeMacros( kernel_known_macros )
- list.optimizeIf01()
- list.removeVarsAndFuncs( statics )
- list.removeComments()
- list.removeEmptyLines()
- list.removeMacroDefines( kernel_ignored_macros )
- list.insertDisclaimer( kernel.kernel_disclaimer )
- list.replaceTokens( kernel_token_replacements )
+ blocks.optimizeMacros( kernel_known_macros )
+ blocks.optimizeIf01()
+ blocks.removeVarsAndFuncs( statics )
+ blocks.replaceTokens( kernel_token_replacements )
+ blocks.removeComments()
+ blocks.removeMacroDefines( kernel_ignored_macros )
+ blocks.removeWhiteSpace()
out = StringOutput()
- list.write(out)
+ out.write( kernel_disclaimer )
+ blocks.writeWithWarning(out, kernel_warning, 4)
return dst_path, out.get()
@@ -92,12 +91,15 @@ if __name__ == "__main__":
if the content has changed. with this, you can pass more
than one file on the command-line
+ -k<path> specify path of original kernel headers
+ -d<path> specify path of cleaned kernel headers
+
<header_path> must be in a subdirectory of 'original'
""" % os.path.basename(sys.argv[0])
sys.exit(1)
try:
- optlist, args = getopt.getopt( sys.argv[1:], 'uvk:' )
+ optlist, args = getopt.getopt( sys.argv[1:], 'uvk:d:' )
except:
# unrecognized option
sys.stderr.write( "error: unrecognized option\n" )
@@ -111,6 +113,8 @@ if __name__ == "__main__":
D_setlevel(1)
elif opt == '-k':
kernel_original_path = arg
+ elif opt == '-d':
+ kernel_cleaned_path = arg
if len(args) == 0:
usage()
@@ -143,9 +147,6 @@ if __name__ == "__main__":
print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r )
- if os.environ.has_key("ANDROID_PRODUCT_OUT"):
- b.updateP4Files()
- else:
- b.updateFiles()
+ b.updateGitFiles()
sys.exit(0)
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index 8828a5d23..8e15a6784 100644
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -1529,7 +1529,7 @@ def test_CppExpr():
class Block:
"""a class used to model a block of input source text. there are two block types:
- - direcive blocks: contain the tokens of a single pre-processor directive (e.g. #if)
+ - directive blocks: contain the tokens of a single pre-processor directive (e.g. #if)
- text blocks, contain the tokens of non-directive blocks
the cpp parser class below will transform an input source file into a list of Block
@@ -1609,6 +1609,91 @@ class Block:
else:
return None
+ def removeWhiteSpace(self):
+ # Remove trailing whitespace and empty lines
+ # All whitespace is also contracted to a single space
+ if self.directive != None:
+ return
+
+ tokens = []
+ line = 0 # index of line start
+ space = -1 # index of first space, or -1
+ ii = 0
+ nn = len(self.tokens)
+ while ii < nn:
+ tok = self.tokens[ii]
+
+ # If we find a space, record its position if this is the first
+ # one the line start or the previous character. Don't append
+ # anything to tokens array yet though.
+ if tok.id == tokSPACE:
+ if space < 0:
+ space = ii
+ ii += 1
+ continue
+
+ # If this is a line space, ignore the spaces we found previously
+ # on the line, and remove empty lines.
+ if tok.id == tokLN:
+ old_line = line
+ old_space = space
+ #print "N line=%d space=%d ii=%d" % (line, space, ii)
+ ii += 1
+ line = ii
+ space = -1
+ if old_space == old_line: # line only contains spaces
+ #print "-s"
+ continue
+ if ii-1 == old_line: # line is empty
+ #print "-e"
+ continue
+ tokens.append(tok)
+ continue
+
+ # Other token, append any space range if any, converting each
+ # one to a single space character, then append the token.
+ if space >= 0:
+ jj = space
+ space = -1
+ while jj < ii:
+ tok2 = self.tokens[jj]
+ tok2.value = " "
+ tokens.append(tok2)
+ jj += 1
+
+ tokens.append(tok)
+ ii += 1
+
+ self.tokens = tokens
+
+ def writeWithWarning(self,out,warning,left_count,repeat_count):
+ # removeWhiteSpace() will sometimes creates non-directive blocks
+ # without any tokens. These come from blocks that only contained
+ # empty lines and spaces. They should not be printed in the final
+ # output, and then should not be counted for this operation.
+ #
+ if not self.directive and self.tokens == []:
+ return left_count
+
+ if self.directive:
+ out.write(str(self) + "\n")
+ left_count -= 1
+ if left_count == 0:
+ out.write(warning)
+ left_count = repeat_count
+
+ else:
+ for tok in self.tokens:
+ out.write(str(tok))
+ if tok.id == tokLN:
+ left_count -= 1
+ if left_count == 0:
+ out.write(warning)
+ left_count = repeat_count
+
+ return left_count
+
+
def __repr__(self):
"""generate the representation of a given block"""
if self.directive:
@@ -1651,7 +1736,6 @@ class Block:
return result
-
class BlockList:
"""a convenience class used to hold and process a list of blocks returned by
the cpp parser"""
@@ -1694,6 +1778,10 @@ class BlockList:
if b.isIf():
b.expr.removePrefixed(prefix,names)
+ def removeWhiteSpace(self):
+ for b in self.blocks:
+ b.removeWhiteSpace()
+
def optimizeAll(self,macros):
self.optimizeMacros(macros)
self.optimizeIf01()
@@ -1713,72 +1801,17 @@ class BlockList:
def write(self,out):
out.write(str(self))
+ def writeWithWarning(self,out,warning,repeat_count):
+ left_count = repeat_count
+ for b in self.blocks:
+ left_count = b.writeWithWarning(out,warning,left_count,repeat_count)
+
def removeComments(self):
for b in self.blocks:
for tok in b.tokens:
if tok.id == tokSPACE:
tok.value = " "
- def removeEmptyLines(self):
- # state = 1 => previous line was tokLN
- # state = 0 => previous line was directive
- state = 1
- for b in self.blocks:
- if b.isDirective():
- #print "$$$ directive %s" % str(b)
- state = 0
- else:
- # a tokLN followed by spaces is replaced by a single tokLN
- # several successive tokLN are replaced by a single one
- #
- dst = []
- src = b.tokens
- n = len(src)
- i = 0
- #print "$$$ parsing %s" % repr(src)
- while i < n:
- # find final tokLN
- j = i
- while j < n and src[j].id != tokLN:
- j += 1
-
- if j >= n:
- # uhhh
- dst += src[i:]
- break
-
- if src[i].id == tokSPACE:
- k = i+1
- while src[k].id == tokSPACE:
- k += 1
-
- if k == j: # empty lines with spaces in it
- i = j # remove the spaces
-
- if i == j:
- # an empty line
- if state == 1:
- i += 1 # remove it
- else:
- state = 1
- dst.append(src[i])
- i += 1
- else:
- # this line is not empty, remove trailing spaces
- k = j
- while k > i and src[k-1].id == tokSPACE:
- k -= 1
-
- nn = i
- while nn < k:
- dst.append(src[nn])
- nn += 1
- dst.append(src[j])
- state = 0
- i = j+1
-
- b.tokens = dst
-
def removeVarsAndFuncs(self,knownStatics=set()):
"""remove all extern and static declarations corresponding
to variable and function declarations. we only accept typedefs
@@ -1789,66 +1822,118 @@ class BlockList:
which is useful for optimized byteorder swap functions and
stuff like that.
"""
- # state = 1 => typedef/struct encountered
- # state = 2 => vars or func declaration encountered, skipping until ";"
# state = 0 => normal (i.e. LN + spaces)
+ # state = 1 => typedef/struct encountered, ends with ";"
+ # state = 2 => var declaration encountered, ends with ";"
+ # state = 3 => func declaration encountered, ends with "}"
state = 0
depth = 0
blocks2 = []
+ skipTokens = False
for b in self.blocks:
if b.isDirective():
blocks2.append(b)
else:
n = len(b.tokens)
i = 0
- first = 0
- if state == 2:
+ if skipTokens:
first = n
+ else:
+ first = 0
while i < n:
tok = b.tokens[i]
- if state == 0:
- bad = 0
- if tok.id in [tokLN, tokSPACE]:
- pass
- elif tok.value in [ 'struct', 'typedef', 'enum', 'union', '__extension__' ]:
- state = 1
- else:
- if tok.value in [ 'static', 'extern', '__KINLINE' ]:
- j = i+1
- ident = ""
- while j < n and not (b.tokens[j].id in [ '(', ';' ]):
- if b.tokens[j].id == tokIDENT:
- ident = b.tokens[j].value
- j += 1
- if j < n and ident in knownStatics:
- # this is a known static, we're going to keep its
- # definition in the final output
- state = 1
- else:
- #print "### skip static '%s'" % ident
- pass
-
- if state == 0:
- if i > first:
- #print "### intermediate from '%s': '%s'" % (tok.value, repr(b.tokens[first:i]))
- blocks2.append( Block(b.tokens[first:i]) )
- state = 2
- first = n
-
- else: # state > 0
- if tok.id == '{':
+ tokid = tok.id
+ # If we are not looking for the start of a new
+ # type/var/func, then skip over tokens until
+ # we find our terminator, managing the depth of
+ # accolades as we go.
+ if state > 0:
+ terminator = False
+ if tokid == '{':
depth += 1
-
- elif tok.id == '}':
+ elif tokid == '}':
if depth > 0:
depth -= 1
+ if (depth == 0) and (state == 3):
+ terminator = True
+ elif tokid == ';' and depth == 0:
+ terminator = True
- elif depth == 0 and tok.id == ';':
- if state == 2:
- first = i+1
+ if terminator:
+ # we found the terminator
state = 0
+ if skipTokens:
+ skipTokens = False
+ first = i+1
+
+ i = i+1
+ continue
+
+ # We are looking for the start of a new type/func/var
+ # ignore whitespace
+ if tokid in [tokLN, tokSPACE]:
+ i = i+1
+ continue
- i += 1
+ # Is it a new type definition, then start recording it
+ if tok.value in [ 'struct', 'typedef', 'enum', 'union', '__extension__' ]:
+ #print "$$$ keep type declr" + repr(b.tokens[i:])
+ state = 1
+ i = i+1
+ continue
+
+ # Is it a variable or function definition. If so, first
+ # try to determine which type it is, and also extract
+ # its name.
+ #
+ # We're going to parse the next tokens of the same block
+ # until we find a semi-column or a left parenthesis.
+ #
+ # The semi-column corresponds to a variable definition,
+ # the left-parenthesis to a function definition.
+ #
+ # We also assume that the var/func name is the last
+ # identifier before the terminator.
+ #
+ j = i+1
+ ident = ""
+ while j < n:
+ tokid = b.tokens[j].id
+ if tokid == '(': # a function declaration
+ state = 3
+ break
+ elif tokid == ';': # a variable declaration
+ state = 2
+ break
+ if tokid == tokIDENT:
+ ident = b.tokens[j].value
+ j += 1
+
+ if j >= n:
+ # This can only happen when the declaration
+ # does not end on the current block (e.g. with
+ # a directive mixed inside it.
+ #
+ # We will treat it as malformed because
+ # it's very hard to recover from this case
+ # without making our parser much more
+ # complex.
+ #
+ #print "### skip unterminated static '%s'" % ident
+ break
+
+ if ident in knownStatics:
+ #print "### keep var/func '%s': %s" % (ident,repr(b.tokens[i:j]))
+ pass
+ else:
+ # We're going to skip the tokens for this declaration
+ #print "### skip variable /func'%s': %s" % (ident,repr(b.tokens[i:j]))
+ if i > first:
+ blocks2.append( Block(b.tokens[first:i]))
+ skipTokens = True
+ first = n
+
+ i = i+1
if i > first:
#print "### final '%s'" % repr(b.tokens[first:i])
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index ca7e6bb4a..2bee4ec43 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -16,7 +16,11 @@ kernel_dirs = [ "linux", "asm", "asm-generic", "mtd" ]
# path to the directory containing the original kernel headers
#
-kernel_original_path = os.path.normpath( find_program_dir() + '/../original' )
+kernel_original_path = os.path.normpath( find_program_dir() + '/../../../../external/kernel-headers/original' )
+
+# path to the default location of the cleaned-up headers
+#
+kernel_cleaned_path = os.path.normpath( find_program_dir() + '/..' )
# a special value that is used to indicate that a given macro is known to be
# undefined during optimization
@@ -45,7 +49,7 @@ kernel_default_arch_macros = {
# 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
@@ -112,6 +116,18 @@ kernel_disclaimer = """\
*** structures, and macros generated from the original header, and thus,
*** contains no copyrightable information.
***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
****************************************************************************
****************************************************************************/
"""
+
+# This is the warning line that will be inserted every N-th line in the output
+kernel_warning = """\
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+"""
diff --git a/libc/kernel/tools/find_headers.py b/libc/kernel/tools/find_headers.py
index 8e72bb603..3d622a8bc 100755
--- a/libc/kernel/tools/find_headers.py
+++ b/libc/kernel/tools/find_headers.py
@@ -3,7 +3,7 @@
# this program is used to find source code that includes linux kernel headers directly
# (e.g. with #include <linux/...> or #include <asm/...>)
#
-# then it lists
+# then it lists them on the standard output.
import sys, cpp, glob, os, re, getopt, kernel
from utils import *
@@ -12,20 +12,14 @@ from defaults import *
program_dir = find_program_dir()
wanted_archs = kernel_archs
-wanted_include = os.path.normpath(program_dir + '/../original')
-wanted_config = os.path.normpath(program_dir + '/../original/config')
+wanted_config = None
def usage():
print """\
- usage: find_headers.py [options] (file|directory|@listfile)+
+ usage: find_headers.py [options] <kernel-root> (file|directory|@listfile)+
options:
- -d <include-dir> specify alternate kernel headers
- 'include' directory
- ('%s' by default)
-
- -c <file> specify alternate .config file
- ('%s' by default)
+ -c <file> specify .config file (none by default)
-a <archs> used to specify an alternative list
of architectures to support
@@ -37,12 +31,12 @@ def usage():
by a set of source files or directories containing them. the search
is recursive to find *all* required files.
-""" % ( wanted_include, wanted_config, string.join(kernel_archs,",") )
+""" % ( string.join(kernel_archs,",") )
sys.exit(1)
try:
- optlist, args = getopt.getopt( sys.argv[1:], 'vc:d:a:' )
+ optlist, args = getopt.getopt( sys.argv[1:], 'vc:d:a:k:' )
except:
# unrecognized option
print "error: unrecognized option"
@@ -51,8 +45,6 @@ except:
for opt, arg in optlist:
if opt == '-a':
wanted_archs = string.split(arg,',')
- elif opt == '-d':
- wanted_include = arg
elif opt == '-c':
wanted_config = arg
elif opt == '-v':
@@ -62,10 +54,10 @@ for opt, arg in optlist:
else:
usage()
-if len(args) < 1:
+if len(args) < 2:
usage()
-kernel_root = wanted_include
+kernel_root = args[0]
if not os.path.exists(kernel_root):
sys.stderr.write( "error: directory '%s' does not exist\n" % kernel_root )
sys.exit(1)
@@ -74,26 +66,26 @@ if not os.path.isdir(kernel_root):
sys.stderr.write( "error: '%s' is not a directory\n" % kernel_root )
sys.exit(1)
-if not os.path.isdir(kernel_root+"/linux"):
- sys.stderr.write( "error: '%s' does not have a 'linux' directory\n" % kernel_root )
+if not os.path.isdir(kernel_root+"/include/linux"):
+ sys.stderr.write( "error: '%s' does not have an 'include/linux' directory\n" % kernel_root )
sys.exit(1)
-if not os.path.exists(wanted_config):
- sys.stderr.write( "error: file '%s' does not exist\n" % wanted_config )
- sys.exit(1)
+if wanted_config:
+ if not os.path.exists(wanted_config):
+ sys.stderr.write( "error: file '%s' does not exist\n" % wanted_config )
+ sys.exit(1)
-if not os.path.isfile(wanted_config):
- sys.stderr.write( "error: '%s' is not a file\n" % wanted_config )
- sys.exit(1)
+ if not os.path.isfile(wanted_config):
+ sys.stderr.write( "error: '%s' is not a file\n" % wanted_config )
+ sys.exit(1)
# find all architectures in the kernel tree
-re_asm_ = re.compile(r"asm-(\w+)")
archs = []
-for dir in os.listdir(kernel_root):
- m = re_asm_.match(dir)
- if m:
- if verbose: print ">> found kernel arch '%s'" % m.group(1)
- archs.append(m.group(1))
+for archdir in os.listdir(kernel_root+"/arch"):
+ if os.path.exists("%s/arch/%s/include/asm" % (kernel_root, archdir)):
+ if verbose:
+ print "Found arch '%s'" % archdir
+ archs.append(archdir)
# if we're using the 'kernel_headers' directory, there is only asm/
# and no other asm-<arch> directories (arm is assumed, which sucks)
@@ -126,6 +118,7 @@ if wanted_archs != None:
# helper function used to walk the user files
def parse_file(path, parser):
+ #print "parse %s" % path
parser.parseFile(path)
@@ -136,7 +129,8 @@ def parse_file(path, parser):
# try to read the config file
try:
cparser = kernel.ConfigParser()
- cparser.parseFile( wanted_config )
+ if wanted_config:
+ cparser.parseFile( wanted_config )
except:
sys.stderr.write( "error: can't parse '%s'" % wanted_config )
sys.exit(1)
@@ -145,7 +139,8 @@ kernel_config = cparser.getDefinitions()
# first, obtain the list of kernel files used by our clients
fparser = kernel.HeaderScanner()
-walk_source_files( args, parse_file, fparser, excludes=["kernel_headers"] )
+dir_excludes=[".repo","external/kernel-headers","ndk","out","prebuilt","bionic/libc/kernel","development/ndk","external/qemu/distrib"]
+walk_source_files( args[1:], parse_file, fparser, excludes=["./"+f for f in dir_excludes] )
headers = fparser.getHeaders()
files = fparser.getFiles()
@@ -170,6 +165,6 @@ if 0: # just for debugging
sys.exit(0)
for h in sorted(headers):
- print h
+ print "%s" % h
sys.exit(0)
diff --git a/libc/kernel/tools/kernel.py b/libc/kernel/tools/kernel.py
index 9d9b5f02d..c20398533 100644
--- a/libc/kernel/tools/kernel.py
+++ b/libc/kernel/tools/kernel.py
@@ -55,8 +55,11 @@ class HeaderScanner:
# <asm-generic/*>
# <mtd/*>
#
- re_combined =\
- re.compile(r"^.*<((%s)/[\d\w_\+\.\-/]*)>.*$" % string.join(kernel_dirs,"|") )
+ re_combined_str=\
+ r"^.*<((%s)/[\d\w_\+\.\-/]*)>.*$" % string.join(kernel_dirs,"|")
+
+ re_combined = re.compile(re_combined_str)
+
# some kernel files choose to include files with relative paths (x86 32/64
# dispatch for instance)
re_rel_dir = re.compile(r'^.*"([\d\w_\+\.\-/]+)".*$')
diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py
index d25dc0e7e..6a730a5f0 100755
--- a/libc/kernel/tools/update_all.py
+++ b/libc/kernel/tools/update_all.py
@@ -6,7 +6,7 @@ from utils import *
def usage():
print """\
- usage: %(progname)s
+ usage: %(progname)s [kernel-original-path]
this program is used to update all the auto-generated clean headers
used by the Bionic C library. it assumes the following:
@@ -31,13 +31,19 @@ except:
sys.stderr.write( "error: unrecognized option\n" )
usage()
-if len(optlist) > 0 or len(args) > 0:
+if len(optlist) > 0 or len(args) > 1:
usage()
progdir = find_program_dir()
-original_dir = os.path.normpath( progdir + "/../original" )
-if not os.path.isdir( original_dir ):
- panic( "required directory does not exists: %s\n" % original_dir )
+
+if len(args) == 1:
+ original_dir = arg[0]
+ if not os.path.isdir(original_dir):
+ panic( "Not a directory: %s" % original_dir )
+else:
+ original_dir = kernel_original_path
+ if not os.path.isdir(original_dir):
+ panic( "Missing directory, please specify one through command-line: %s" % original_dir )
# find all source files in 'original'
#
@@ -57,29 +63,36 @@ b.readDir( os.path.normpath( progdir + "/../common" ) )
#print "OLD " + repr(b.old_files)
+oldlen = 120
for path in sources:
- dst_path, newdata = clean_header.cleanupFile(path)
+ dst_path, newdata = clean_header.cleanupFile(path, original_dir)
if not dst_path:
continue
b.readFile( dst_path )
r = b.editFile( dst_path, newdata )
if r == 0:
- r = "unchanged"
+ state = "unchanged"
elif r == 1:
- r = "edited"
+ state = "edited"
else:
- r = "added"
+ state = "added"
+
+ str = "cleaning: %-*s -> %-*s (%s)" % ( 35, "<original>" + path[len(original_dir):], 35, dst_path, state )
+ if sys.stdout.isatty():
+ print "%-*s" % (oldlen,str),
+ if (r == 0):
+ print "\r",
+ else:
+ print "\n",
+ oldlen = 0
+ else:
+ print str
- print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r )
+ oldlen = len(str)
-# We don't use Perforce anymore, but just in case, define ANDROID_USE_P4
-# in your environment if you think you need it.
-usePerforce = os.environ.has_key("ANDROID_USE_P4")
+print "%-*s" % (oldlen,"Done!")
-if usePerforce:
- b.updateP4Files()
-else:
- b.updateFiles()
+b.updateGitFiles()
sys.exit(0)
diff --git a/libc/kernel/tools/utils.py b/libc/kernel/tools/utils.py
index 763c7d26f..f4cf5403b 100644
--- a/libc/kernel/tools/utils.py
+++ b/libc/kernel/tools/utils.py
@@ -231,6 +231,15 @@ def create_file_path(path):
def walk_source_files(paths,callback,args,excludes=[]):
"""recursively walk a list of paths and files, only keeping the source files in directories"""
for path in paths:
+ if len(path) > 0 and path[0] == '@':
+ # this is the name of another file, include it and parse it
+ path = path[1:]
+ if os.path.exists(path):
+ for line in open(path):
+ if len(line) > 0 and line[-1] == '\n':
+ line = line[:-1]
+ walk_source_files([line],callback,args,excludes)
+ continue
if not os.path.isdir(path):
callback(path,args)
else:
@@ -238,7 +247,7 @@ def walk_source_files(paths,callback,args,excludes=[]):
#print "w-- %s (ex: %s)" % (repr((root,dirs)), repr(excludes))
if len(excludes):
for d in dirs[:]:
- if d in excludes:
+ if os.path.join(root,d) in excludes:
dirs.remove(d)
for f in files:
r, ext = os.path.splitext(f)
@@ -395,3 +404,19 @@ class BatchFileUpdater:
D2("P4 DELETES: %s" % files)
o = commands.getoutput( "p4 delete " + files )
D2( o )
+
+ def updateGitFiles(self):
+ adds, deletes, edits = self.getChanges()
+
+ if adds:
+ for dst in sorted(adds):
+ self._writeFile(dst)
+ commands.getoutput("git add " + " ".join(adds))
+
+ if deletes:
+ commands.getoutput("git rm " + " ".join(deletes))
+
+ if edits:
+ for dst in sorted(edits):
+ self._writeFile(dst)
+ commands.getoutput("git add " + " ".join(edits))
diff --git a/libc/stdio/fvwrite.c b/libc/stdio/fvwrite.c
index 57a57e606..39d06048a 100644
--- a/libc/stdio/fvwrite.c
+++ b/libc/stdio/fvwrite.c
@@ -48,7 +48,7 @@ __LIBC_HIDDEN__ int
__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 2344e42e2..96f65de13 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 2ce0361ae..9c36b79e0 100644
--- a/libc/stdio/vfprintf.c
+++ b/libc/stdio/vfprintf.c
@@ -203,9 +203,9 @@ vfprintf(FILE *fp, const char *fmt0, __va_list ap)
* 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 @@ cvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch,
{
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 28515062a..ab637a157 100644
--- a/libc/stdlib/strtod.c
+++ b/libc/stdlib/strtod.c
@@ -754,6 +754,7 @@ mult
}
static Bigint *p5s;
+ static pthread_mutex_t p5s_mutex = PTHREAD_MUTEX_INITIALIZER;
static Bigint *
pow5mult
@@ -775,11 +776,13 @@ pow5mult
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 @@ pow5mult
p51 = mult(p5,p5);
if (p51 == BIGINT_INVALID) {
Bfree(b);
+ mutex_unlock(&p5s_mutex);
return p51;
}
p5->next = p51;
@@ -804,6 +808,7 @@ pow5mult
}
p5 = p51;
}
+ mutex_unlock(&p5s_mutex);
return b;
}
diff --git a/libc/tools/bionic_utils.py b/libc/tools/bionic_utils.py
index 17eef1348..e7c8c2d98 100644
--- a/libc/tools/bionic_utils.py
+++ b/libc/tools/bionic_utils.py
@@ -105,8 +105,29 @@ def find_bionic_root():
else:
return None
+def find_original_kernel_headers():
+ """try to find the directory containing the original kernel headers"""
+ bionic_root = find_bionic_root()
+ if not bionic_root:
+ D("Could not find Bionic root !!")
+ return None
+
+ path = os.path.normpath(bionic_root + "/../../external/kernel-headers/original")
+ if not os.path.isdir(path):
+ D("Could not find %s" % (path))
+ return None
+
+ return path
+
def find_kernel_headers():
"""try to find the directory containing the kernel headers for this machine"""
+
+ # First try to find the original kernel headers.
+ ret = find_original_kernel_headers()
+ if ret:
+ D("found original kernel headers in: %s" % (ret))
+ return ret
+
status, version = commands.getstatusoutput( "uname -r" ) # get Linux kernel version
if status != 0:
D("could not execute 'uname -r' command properly")
@@ -116,14 +137,39 @@ def find_kernel_headers():
if len(version) > 5 and version[-5:] == "-xenU":
version = version[:-5]
- path = "/usr/src/linux-headers-" + version
- D("probing %s for kernel headers" % (path+"/include"))
+ path = "/usr/src/linux-headers-" + version + "/include"
+ D("probing %s for kernel headers" % (path))
ret = os.path.isdir( path )
if ret:
- D("found kernel headers in: %s" % (path + "/include"))
+ D("found kernel headers in: %s" % (path))
return path
return None
+def find_arch_header(kernel_headers,arch,header):
+ # First, try in <root>/arch/<arm>/include/<header>
+ # corresponding to the location in the kernel source tree for
+ # certain architectures (e.g. arm).
+ path = "%s/arch/%s/include/asm/%s" % (kernel_headers, arch, header)
+ D("Probing for %s" % path)
+ if os.path.exists(path):
+ return path
+
+ # Try <root>/asm-<arch>/include/<header> corresponding to the location
+ # in the kernel source tree for other architectures (e.g. x86).
+ path = "%s/include/asm-%s/%s" % (kernel_headers, arch, header)
+ D("Probing for %s" % path)
+ if os.path.exists(path):
+ return path
+
+ # Otherwise, look under <root>/asm-<arch>/<header> corresponding
+ # the original kernel headers directory
+ path = "%s/asm-%s/%s" % (kernel_headers, arch, header)
+ D("Probing for %s" % path)
+ if os.path.exists(path):
+ return path
+
+
+ return None
# parser for the SYSCALLS.TXT file
#
@@ -212,7 +258,12 @@ class SysCallsTxtParser:
E("invalid syscall number in '%s'" % line)
return
- print str(syscall_id) + ':' + str(syscall_id2) + ':' + str(syscall_id3)
+ global verbose
+ if verbose >= 2:
+ if call_id < 0:
+ print "%s: %d,%d,%d" % (syscall_name, syscall_id, syscall_id2, syscall_id3)
+ else:
+ print "%s(%d): %d,%d,%d" % (syscall_name, call_id, syscall_id, syscall_id2, syscall_id3)
t = { "id" : syscall_id,
"id2" : syscall_id2,
diff --git a/libc/tools/checksyscalls.py b/libc/tools/checksyscalls.py
index 9edb39044..f642e84ae 100755
--- a/libc/tools/checksyscalls.py
+++ b/libc/tools/checksyscalls.py
@@ -40,8 +40,8 @@ def parse_command_line(args):
if len(args) == 0:
linux_root = find_kernel_headers()
if linux_root == None:
- print "could not locate this system kernel headers root directory, please"
- print "specify one when calling this program, i.e. 'checksyscalls <headers-directory>'"
+ print "Could not locate original or system kernel headers root directory."
+ print "Please specify one when calling this program, i.e. 'checksyscalls <headers-directory>'"
sys.exit(1)
print "using the following kernel headers root: '%s'" % linux_root
else:
@@ -112,62 +112,63 @@ def process_header(header_file,dict):
arm_dict = {}
x86_dict = {}
+superh_dict = {}
-
-# remove trailing slash and '/include' from the linux_root, if any
+# remove trailing slash from the linux_root, if any
if linux_root[-1] == '/':
linux_root = linux_root[:-1]
-if len(linux_root) > 8 and linux_root[-8:] == '/include':
- linux_root = linux_root[:-8]
-
-arm_unistd = linux_root + "/include/asm-arm/unistd.h"
-if not os.path.exists(arm_unistd):
- print "WEIRD: could not locate the ARM unistd.h header file"
- print "tried searching in '%s'" % arm_unistd
- print "maybe using a different set of kernel headers might help"
+arm_unistd = find_arch_header(linux_root, "arm", "unistd.h")
+if not arm_unistd:
+ print "WEIRD: Could not locate the ARM unistd.h kernel header file,"
+ print "maybe using a different set of kernel headers might help."
sys.exit(1)
# on recent kernels, asm-i386 and asm-x64_64 have been merged into asm-x86
# with two distinct unistd_32.h and unistd_64.h definition files.
# take care of this here
#
-x86_unistd = linux_root + "/include/asm-i386/unistd.h"
-if not os.path.exists(x86_unistd):
- x86_unistd1 = x86_unistd
- x86_unistd = linux_root + "/include/asm-x86/unistd_32.h"
- if not os.path.exists(x86_unistd):
- print "WEIRD: could not locate the i386/x86 unistd.h header file"
- print "tried searching in '%s' and '%s'" % (x86_unistd1, x86_unistd)
- print "maybe using a different set of kernel headers might help"
+x86_unistd = find_arch_header(linux_root, "i386", "unistd.h")
+if not x86_unistd:
+ x86_unistd = find_arch_header(linux_root, "x86", "unistd_32.h")
+ if not x86_unistd:
+ print "WEIRD: Could not locate the i386/x86 unistd.h header file,"
+ print "maybe using a different set of kernel headers might help."
sys.exit(1)
-process_header( linux_root+"/include/asm-arm/unistd.h", arm_dict )
+superh_unistd = find_arch_header(linux_root, "sh", "unistd_32.h")
+if not superh_unistd:
+ print "WEIRD: Could not locate the SuperH unistd.h kernel header file,"
+ print "maybe using a different set of kernel headers might help."
+ sys.exit(1)
+
+process_header( arm_unistd, arm_dict )
process_header( x86_unistd, x86_dict )
+process_header( superh_unistd, superh_dict )
# now perform the comparison
errors = 0
-for sc in syscalls:
- sc_name = sc["name"]
- sc_id = sc["id"]
- if sc_id >= 0:
- if not arm_dict.has_key(sc_name):
- print "arm syscall %s not defined !!" % sc_name
- errors += 1
- elif arm_dict[sc_name] != sc_id:
- print "arm syscall %s should be %d instead of %d !!" % (sc_name, arm_dict[sc_name], sc_id)
- errors += 1
-
-for sc in syscalls:
- sc_name = sc["name"]
- sc_id2 = sc["id2"]
- if sc_id2 >= 0:
- if not x86_dict.has_key(sc_name):
- print "x86 syscall %s not defined !!" % sc_name
- errors += 1
- elif x86_dict[sc_name] != sc_id2:
- print "x86 syscall %s should be %d instead of %d !!" % (sc_name, x86_dict[sc_name], sc_id2)
- errors += 1
+
+def check_syscalls(archname, idname, arch_dict):
+ errors = 0
+ for sc in syscalls:
+ sc_name = sc["name"]
+ sc_id = sc[idname]
+ if sc_id >= 0:
+ if not arch_dict.has_key(sc_name):
+ print "%s syscall %s not defined, should be %d !!" % (archname, sc_name, sc_id)
+ errors += 1
+ elif not arch_dict.has_key(sc_name):
+ print "%s syscall %s is not implemented!" % (archname, sc_name)
+ errors += 1
+ elif arch_dict[sc_name] != sc_id:
+ print "%s syscall %s should be %d instead of %d !!" % (archname, sc_name, arch_dict[sc_name], sc_id)
+ errors += 1
+ return errors
+
+errors += check_syscalls("arm", "id", arm_dict)
+errors += check_syscalls("x86", "id2", x86_dict)
+errors += check_syscalls("superh", "id3", superh_dict)
if errors == 0:
print "congratulations, everything's fine !!"
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 0535e5623..b58754bda 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -557,7 +557,7 @@ class State:
for sc in self.syscalls:
if sc.has_key("asm-arm") and 'arm' in all_archs:
fname = "arch-arm/syscalls/%s.S" % sc["func"]
- D( ">>> generating "+fname )
+ D2( ">>> generating "+fname )
fp = create_file( fname )
fp.write(sc["asm-arm"])
fp.close()
@@ -565,7 +565,7 @@ class State:
if sc.has_key("asm-thumb") and 'arm' in all_archs:
fname = "arch-arm/syscalls/%s.S" % sc["func"]
- D( ">>> generating "+fname )
+ D2( ">>> generating "+fname )
fp = create_file( fname )
fp.write(sc["asm-thumb"])
fp.close()
@@ -573,7 +573,7 @@ class State:
if sc.has_key("asm-x86") and 'x86' in all_archs:
fname = "arch-x86/syscalls/%s.S" % sc["func"]
- D( ">>> generating "+fname )
+ D2( ">>> generating "+fname )
fp = create_file( fname )
fp.write(sc["asm-x86"])
fp.close()
@@ -581,7 +581,7 @@ class State:
if sc.has_key("asm-sh"):
fname = "arch-sh/syscalls/%s.S" % sc["func"]
- D( ">>> generating "+fname )
+ D2( ">>> generating "+fname )
fp = create_file( fname )
fp.write(sc["asm-sh"])
fp.close()
@@ -626,7 +626,7 @@ class State:
for stub in self.new_stubs + self.other_files:
if not os.path.exists( bionic_root + stub ):
- # new file, P4 add it
+ # new file, git add it
D( "new file: " + stub)
adds.append( bionic_root + stub )
shutil.copyfile( bionic_temp + stub, bionic_root + stub )
@@ -643,16 +643,21 @@ class State:
if adds:
- commands.getoutput("p4 add " + " ".join(adds))
+ commands.getoutput("git add " + " ".join(adds))
if deletes:
- commands.getoutput("p4 delete " + " ".join(deletes))
+ commands.getoutput("git rm " + " ".join(deletes))
if edits:
- commands.getoutput("p4 edit " +
- " ".join((bionic_root + file) for file in edits))
for file in edits:
shutil.copyfile( bionic_temp + file, bionic_root + file )
+ commands.getoutput("git add " +
+ " ".join((bionic_root + file) for file in edits))
- D("ready to go !!")
+ commands.getoutput("git add %s%s" % (bionic_root,"SYSCALLS.TXT"))
+
+ if (not adds) and (not deletes) and (not edits):
+ D("no changes detected!")
+ else:
+ D("ready to go!!")
D_setlevel(1)
diff --git a/libc/tzcode/strptime.c b/libc/tzcode/strptime.c
index 1f481c9f8..0567aa419 100644
--- a/libc/tzcode/strptime.c
+++ b/libc/tzcode/strptime.c
@@ -89,29 +89,31 @@ static const struct {
#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 @@ literal:
*/
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 @@ literal:
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 @@ literal:
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 @@ literal:
* 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 13d73661a..4b51675f3 100644
--- a/libc/unistd/time.c
+++ b/libc/unistd/time.c
@@ -42,21 +42,29 @@ time(time_t *t)
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;
}