diff options
Diffstat (limited to 'libc')
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; } |