1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * utils.c 3dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 4dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This program is free software; you can redistribute it and/or 5dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * modify it under the terms of the GNU General Public License 6dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * as published by the Free Software Foundation; either version 7dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 2 of the License, or (at your option) any later version. 8dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 9dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 11dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 12dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 13dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdio.h> 14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdlib.h> 15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <unistd.h> 16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <syslog.h> 17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <fcntl.h> 18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h> 19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netinet/in.h> 20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h> 21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netdb.h> 22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <arpa/inet.h> 23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <resolv.h> 24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <asm/types.h> 25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/pkt_sched.h> 26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <time.h> 27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/time.h> 28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h" 31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_integer(int *val, const char *arg, int base) 33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat long res; 35dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *ptr; 36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!arg || !*arg) 38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 39dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = strtol(arg, &ptr, base); 40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN) 41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *val = res; 43dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 44dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 45dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 46dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint mask2bits(__u32 netmask) 47dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned bits = 0; 49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 mask = ntohl(netmask); 50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 host = ~mask; 51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* a valid netmask must be 2^n - 1 */ 53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((host & (host + 1)) != 0) 54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (; mask; mask <<= 1) 57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ++bits; 58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return bits; 59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int get_netmask(unsigned *val, const char *arg, int base) 62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix addr; 64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 65dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!get_unsigned(val, arg, base)) 66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* try coverting dotted quad to CIDR */ 69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!get_addr_1(&addr, arg, AF_INET) && addr.family == AF_INET) { 70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int b = mask2bits(addr.data[0]); 71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (b >= 0) { 73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *val = b; 74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 75dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 76dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_unsigned(unsigned *val, const char *arg, int base) 82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long res; 84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *ptr; 85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!arg || !*arg) 87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = strtoul(arg, &ptr, base); 89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ptr || ptr == arg || *ptr || res > UINT_MAX) 90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *val = res; 92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * get_jiffies is "translated" from a similar routine "get_time" in 97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * tc_util.c. we don't use the exact same routine because tc passes 98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * microseconds to the kernel and the callers of get_jiffies want 99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * to pass jiffies, and have a different assumption for the units of 100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * a "raw" number. 101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_jiffies(unsigned *jiffies, const char *arg, int base, int *raw) 104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat double t; 106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long res; 107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *p; 108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strchr(arg,'.') != NULL) { 110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t = strtod(arg,&p); 111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (t < 0.0) 112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = strtoul(arg,&p,base); 116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (res > UINT_MAX) 117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t = (double)res; 119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p == arg) 121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (__iproute2_hz_internal == 0) 124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __iproute2_hz_internal = __get_hz(); 125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *raw = 1; 127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (*p) { 129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *raw = 0; 130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcasecmp(p, "s") == 0 || strcasecmp(p, "sec")==0 || 131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcasecmp(p, "secs")==0) 132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t *= __iproute2_hz_internal; 133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (strcasecmp(p, "ms") == 0 || strcasecmp(p, "msec")==0 || 134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcasecmp(p, "msecs") == 0) 135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t *= __iproute2_hz_internal/1000.0; 136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (strcasecmp(p, "us") == 0 || strcasecmp(p, "usec")==0 || 137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcasecmp(p, "usecs") == 0) 138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t *= __iproute2_hz_internal/1000000.0; 139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (strcasecmp(p, "ns") == 0 || strcasecmp(p, "nsec")==0 || 140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcasecmp(p, "nsecs") == 0) 141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t *= __iproute2_hz_internal/1000000000.0; 142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (strcasecmp(p, "j") == 0 || strcasecmp(p, "hz") == 0 || 143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcasecmp(p,"jiffies") == 0) 144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t *= 1.0; /* allow suffix, do nothing */ 145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* emulate ceil() without having to bring-in -lm and always be >= 1 */ 150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *jiffies = t; 152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (*jiffies < t) 153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *jiffies += 1; 154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_u64(__u64 *val, const char *arg, int base) 160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long long res; 162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *ptr; 163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!arg || !*arg) 165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = strtoull(arg, &ptr, base); 167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ptr || ptr == arg || *ptr || res == 0xFFFFFFFFULL) 168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *val = res; 170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 172dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_u32(__u32 *val, const char *arg, int base) 174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long res; 176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *ptr; 177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!arg || !*arg) 179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = strtoul(arg, &ptr, base); 181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ptr || ptr == arg || *ptr || res > 0xFFFFFFFFUL) 182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *val = res; 184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_u16(__u16 *val, const char *arg, int base) 188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long res; 190dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *ptr; 191dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 192dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!arg || !*arg) 193dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 194dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = strtoul(arg, &ptr, base); 195dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ptr || ptr == arg || *ptr || res > 0xFFFF) 196dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 197dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *val = res; 198dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 199dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 200dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 201dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_u8(__u8 *val, const char *arg, int base) 202dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 203dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long res; 204dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *ptr; 205dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 206dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!arg || !*arg) 207dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 208dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = strtoul(arg, &ptr, base); 209dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ptr || ptr == arg || *ptr || res > 0xFF) 210dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 211dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *val = res; 212dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 213dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 214dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 215dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_s16(__s16 *val, const char *arg, int base) 216dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 217dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat long res; 218dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *ptr; 219dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 220dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!arg || !*arg) 221dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 222dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = strtol(arg, &ptr, base); 223dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ptr || ptr == arg || *ptr || res > 0x7FFF || res < -0x8000) 224dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 225dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *val = res; 226dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 227dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 228dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 229dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_s8(__s8 *val, const char *arg, int base) 230dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 231dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat long res; 232dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *ptr; 233dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 234dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!arg || !*arg) 235dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 236dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = strtol(arg, &ptr, base); 237dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ptr || ptr == arg || *ptr || res > 0x7F || res < -0x80) 238dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 239dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *val = res; 240dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 241dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 242dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 243dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* This uses a non-standard parsing (ie not inet_aton, or inet_pton) 244dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * because of legacy choice to parse 10.8 as 10.8.0.0 not 10.0.0.8 245dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 246dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int get_addr_ipv4(__u8 *ap, const char *cp) 247dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 248dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 249dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 250dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i = 0; i < 4; i++) { 251dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long n; 252dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *endp; 253dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 254dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat n = strtoul(cp, &endp, 0); 255dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n > 255) 256dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; /* bogus network value */ 257dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 258dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (endp == cp) /* no digits */ 259dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 260dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 261dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ap[i] = n; 262dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 263dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (*endp == '\0') 264dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 265dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 266dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (i == 3 || *endp != '.') 267dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; /* extra characters */ 268dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cp = endp + 1; 269dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 270dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 271dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 1; 272dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 273dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 274dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_addr_1(inet_prefix *addr, const char *name, int family) 275dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 276dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(addr, 0, sizeof(*addr)); 277dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 278dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(name, "default") == 0 || 279dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(name, "all") == 0 || 280dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(name, "any") == 0) { 281dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (family == AF_DECnet) 282dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 283dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->family = family; 284dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->bytelen = (family == AF_INET6 ? 16 : 4); 285dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->bitlen = -1; 286dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 287dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 288dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 289dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strchr(name, ':')) { 290dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->family = AF_INET6; 291dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (family != AF_UNSPEC && family != AF_INET6) 292dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 293dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (inet_pton(AF_INET6, name, addr->data) <= 0) 294dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 295dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->bytelen = 16; 296dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->bitlen = -1; 297dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 298dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 299dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 300f1cbadf4caabd2f5fb30b1e4f3728e1493d40bb7San Mehat#ifndef ANDROID 301dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (family == AF_DECnet) { 302dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct dn_naddr dna; 303dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->family = AF_DECnet; 304dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (dnet_pton(AF_DECnet, name, &dna) <= 0) 305dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 306dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(addr->data, dna.a_addr, 2); 307dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->bytelen = 2; 308dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->bitlen = -1; 309dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 310dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 311f1cbadf4caabd2f5fb30b1e4f3728e1493d40bb7San Mehat#endif 312dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 313dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->family = AF_INET; 314dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (family != AF_UNSPEC && family != AF_INET) 315dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 316dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 317dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_addr_ipv4((__u8 *)addr->data, name) <= 0) 318dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 319dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 320dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->bytelen = 4; 321dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr->bitlen = -1; 322dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 323dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 324dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 325dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_prefix_1(inet_prefix *dst, char *arg, int family) 326dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 327dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int err; 328dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned plen; 329dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *slash; 330dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 331dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(dst, 0, sizeof(*dst)); 332dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 333dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(arg, "default") == 0 || 334dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(arg, "any") == 0 || 335dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(arg, "all") == 0) { 336dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (family == AF_DECnet) 337dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 338dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst->family = family; 339dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst->bytelen = 0; 340dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst->bitlen = 0; 341dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 342dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 343dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 344dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat slash = strchr(arg, '/'); 345dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (slash) 346dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *slash = 0; 347dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 348dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat err = get_addr_1(dst, arg, family); 349dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (err == 0) { 350dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat switch(dst->family) { 351dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_INET6: 352dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst->bitlen = 128; 353dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 354dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_DECnet: 355dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst->bitlen = 16; 356dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 357dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat default: 358dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_INET: 359dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst->bitlen = 32; 360dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 361dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (slash) { 362dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_netmask(&plen, slash+1, 0) 363dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat || plen > dst->bitlen) { 364dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat err = -1; 365dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto done; 366dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 367dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst->flags |= PREFIXLEN_SPECIFIED; 368dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst->bitlen = plen; 369dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 370dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 371dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatdone: 372dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (slash) 373dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *slash = '/'; 374dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return err; 375dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 376dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 377dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_addr(inet_prefix *dst, const char *arg, int family) 378dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 379dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (family == AF_PACKET) { 380dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Error: \"%s\" may be inet address, but it is not allowed in this context.\n", arg); 381dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 382dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 383dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_addr_1(dst, arg, family)) { 384dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Error: an inet address is expected rather than \"%s\".\n", arg); 385dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 386dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 387dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 388dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 389dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 390dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint get_prefix(inet_prefix *dst, char *arg, int family) 391dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 392dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (family == AF_PACKET) { 393dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Error: \"%s\" may be inet prefix, but it is not allowed in this context.\n", arg); 394dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 395dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 396dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_prefix_1(dst, arg, family)) { 397dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Error: an inet prefix is expected rather than \"%s\".\n", arg); 398dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 399dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 400dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 401dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 402dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 403dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat__u32 get_addr32(const char *name) 404dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 405dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix addr; 406dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_addr_1(&addr, name, AF_INET)) { 407dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Error: an IP address is expected rather than \"%s\"\n", name); 408dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 409dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 410dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return addr.data[0]; 411dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 412dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 413dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid incomplete_command(void) 414dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 415dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Command line is not complete. Try option \"help\"\n"); 416dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 417dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 418dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 419dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid missarg(const char *key) 420dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 421dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Error: argument \"%s\" is required\n", key); 422dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 423dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 424dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 425dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid invarg(const char *msg, const char *arg) 426dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 427dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Error: argument \"%s\" is wrong: %s\n", arg, msg); 428dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 429dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 430dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 431dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid duparg(const char *key, const char *arg) 432dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 433dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Error: duplicate \"%s\": \"%s\" is the second value.\n", key, arg); 434dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 435dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 436dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 437dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid duparg2(const char *key, const char *arg) 438dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 439dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Error: either \"%s\" is duplicate, or \"%s\" is a garbage.\n", key, arg); 440dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 441dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 442dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 443dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint matches(const char *cmd, const char *pattern) 444dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 445dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int len = strlen(cmd); 446dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len > strlen(pattern)) 447dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 448dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return memcmp(pattern, cmd, len); 449dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 450dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 451dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits) 452dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 453dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const __u32 *a1 = a->data; 454dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const __u32 *a2 = b->data; 455dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int words = bits >> 0x05; 456dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 457dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat bits &= 0x1f; 458dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 459dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (words) 460dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (memcmp(a1, a2, words << 2)) 461dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 462dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 463dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (bits) { 464dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 w1, w2; 465dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 mask; 466dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 467dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat w1 = a1[words]; 468dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat w2 = a2[words]; 469dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 470dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat mask = htonl((0xffffffff) << (0x20 - bits)); 471dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 472dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((w1 ^ w2) & mask) 473dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 1; 474dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 475dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 476dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 477dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 478dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 479dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint __iproute2_hz_internal; 480dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 481dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint __get_hz(void) 482dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 483dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char name[1024]; 484dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int hz = 0; 485dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat FILE *fp; 486dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 487dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (getenv("HZ")) 488dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return atoi(getenv("HZ")) ? : HZ; 489dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 490dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (getenv("PROC_NET_PSCHED")) { 491dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat snprintf(name, sizeof(name)-1, "%s", getenv("PROC_NET_PSCHED")); 492dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (getenv("PROC_ROOT")) { 493dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat snprintf(name, sizeof(name)-1, "%s/net/psched", getenv("PROC_ROOT")); 494dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 495dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcpy(name, "/proc/net/psched"); 496dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 497dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fp = fopen(name, "r"); 498dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 499dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (fp) { 500dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned nom, denom; 501dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2) 502dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (nom == 1000000) 503dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat hz = denom; 504dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fclose(fp); 505dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 506dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (hz) 507dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return hz; 508dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return HZ; 509dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 510dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 511dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint __iproute2_user_hz_internal; 512dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 513dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint __get_user_hz(void) 514dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 515dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return sysconf(_SC_CLK_TCK); 516dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 517dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 518dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatconst char *rt_addr_n2a(int af, int len, const void *addr, char *buf, int buflen) 519dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 520dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat switch (af) { 521dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_INET: 522dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_INET6: 523dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return inet_ntop(af, addr, buf, buflen); 524f1cbadf4caabd2f5fb30b1e4f3728e1493d40bb7San Mehat#ifndef ANDROID 525dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_IPX: 526dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipx_ntop(af, addr, buf, buflen); 527dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_DECnet: 528dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 529dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct dn_naddr dna = { 2, { 0, 0, }}; 530dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(dna.a_addr, addr, 2); 531dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return dnet_ntop(af, &dna, buf, buflen); 532dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 533f1cbadf4caabd2f5fb30b1e4f3728e1493d40bb7San Mehat#endif 534dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat default: 535dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return "???"; 536dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 537dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 538dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 539dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#ifdef RESOLVE_HOSTNAMES 540dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct namerec 541dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 542dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct namerec *next; 543dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const char *name; 544dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix addr; 545dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 546dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 547dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#define NHASH 257 548dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct namerec *nht[NHASH]; 549dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 550dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *resolve_address(const void *addr, int len, int af) 551dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 552dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct namerec *n; 553dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct hostent *h_ent; 554dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned hash; 555dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat static int notfirst; 556dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 557dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 558dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (af == AF_INET6 && ((__u32*)addr)[0] == 0 && 559dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ((__u32*)addr)[1] == 0 && ((__u32*)addr)[2] == htonl(0xffff)) { 560dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat af = AF_INET; 561dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addr += 12; 562dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len = 4; 563dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 564dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 565dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat hash = *(__u32 *)(addr + len - 4) % NHASH; 566dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 567dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (n = nht[hash]; n; n = n->next) { 568dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->addr.family == af && 569dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat n->addr.bytelen == len && 570dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcmp(n->addr.data, addr, len) == 0) 571dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return n->name; 572dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 573dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((n = malloc(sizeof(*n))) == NULL) 574dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return NULL; 575dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat n->addr.family = af; 576dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat n->addr.bytelen = len; 577dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat n->name = NULL; 578dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(n->addr.data, addr, len); 579dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat n->next = nht[hash]; 580dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat nht[hash] = n; 581dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (++notfirst == 1) 582dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sethostent(1); 583dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fflush(stdout); 584dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 585dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((h_ent = gethostbyaddr(addr, len, af)) != NULL) 586dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat n->name = strdup(h_ent->h_name); 587dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 588dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* Even if we fail, "negative" entry is remembered. */ 589dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return n->name; 590dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 591dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#endif 592dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 593dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 594dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatconst char *format_host(int af, int len, const void *addr, 595dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *buf, int buflen) 596dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 597dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#ifdef RESOLVE_HOSTNAMES 598dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (resolve_hosts) { 599dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const char *n; 600dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 601dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len <= 0) { 602dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat switch (af) { 603dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_INET: 604dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len = 4; 605dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 606dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_INET6: 607dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len = 16; 608dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 609dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_IPX: 610dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len = 10; 611dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 612dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#ifdef AF_DECnet 613dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* I see no reasons why gethostbyname 614dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat may not work for DECnet */ 615dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_DECnet: 616dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len = 2; 617dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 618dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#endif 619dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat default: ; 620dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 621dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 622dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len > 0 && 623dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (n = resolve_address(addr, len, af)) != NULL) 624dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return n; 625dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 626dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#endif 627dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return rt_addr_n2a(af, len, addr, buf, buflen); 628dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 629dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 630dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 631dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatchar *hexstring_n2a(const __u8 *str, int len, char *buf, int blen) 632dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 633dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *ptr = buf; 634dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 635dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 636dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i=0; i<len; i++) { 637dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (blen < 3) 638dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 639dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(ptr, "%02x", str[i]); 640dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ptr += 2; 641dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat blen -= 2; 642dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (i != len-1 && blen > 1) { 643dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *ptr++ = ':'; 644dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat blen--; 645dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 646dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 647dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return buf; 648dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 649dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 650dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat__u8* hexstring_a2n(const char *str, __u8 *buf, int blen) 651dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 652dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int cnt = 0; 653dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 654dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (;;) { 655dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned acc; 656dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char ch; 657dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 658dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat acc = 0; 659dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 660dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while ((ch = *str) != ':' && ch != 0) { 661dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ch >= '0' && ch <= '9') 662dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ch -= '0'; 663dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (ch >= 'a' && ch <= 'f') 664dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ch -= 'a'-10; 665dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (ch >= 'A' && ch <= 'F') 666dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ch -= 'A'-10; 667dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 668dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return NULL; 669dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat acc = (acc<<4) + ch; 670dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat str++; 671dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 672dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 673dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (acc > 255) 674dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return NULL; 675dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (cnt < blen) { 676dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat buf[cnt] = acc; 677dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cnt++; 678dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 679dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ch == 0) 680dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 681dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ++str; 682dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 683dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (cnt < blen) 684dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(buf+cnt, 0, blen-cnt); 685dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return buf; 686dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 687dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 688dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_timestamp(FILE *fp) 689dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 690dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct timeval tv; 691dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *tstr; 692dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 693dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&tv, 0, sizeof(tv)); 694dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat gettimeofday(&tv, NULL); 695dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 696dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tstr = asctime(localtime(&tv.tv_sec)); 697dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tstr[strlen(tstr)-1] = 0; 698dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "Timestamp: %s %lu usec\n", tstr, tv.tv_usec); 699dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 700dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 701dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 702dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint cmdlineno; 703dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 704f1cbadf4caabd2f5fb30b1e4f3728e1493d40bb7San Mehat#ifndef ANDROID 705dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* Like glibc getline but handle continuation lines and comments */ 706dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatssize_t getcmdline(char **linep, size_t *lenp, FILE *in) 707dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 708dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ssize_t cc; 709dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *cp; 710dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 711dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((cc = getline(linep, lenp, in)) < 0) 712dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return cc; /* eof or error */ 713dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ++cmdlineno; 714dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 715dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cp = strchr(*linep, '#'); 716dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (cp) 717dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *cp = '\0'; 718dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 719dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while ((cp = strstr(*linep, "\\\n")) != NULL) { 720dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *line1 = NULL; 721dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat size_t len1 = 0; 722dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat size_t cc1; 723dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 724dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((cc1 = getline(&line1, &len1, in)) < 0) { 725dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Missing continuation line\n"); 726dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return cc1; 727dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 728dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 729dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ++cmdlineno; 730dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *cp = 0; 731dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 732dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cp = strchr(line1, '#'); 733dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (cp) 734dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *cp = '\0'; 735dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 736dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *lenp = strlen(*linep) + strlen(line1) + 1; 737dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *linep = realloc(*linep, *lenp); 738dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!*linep) { 739dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Out of memory\n"); 740dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *lenp = 0; 741dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 742dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 743dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cc += cc1 - 2; 744dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcat(*linep, line1); 745dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free(line1); 746dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 747dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return cc; 748dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 749f1cbadf4caabd2f5fb30b1e4f3728e1493d40bb7San Mehat#endif 750dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 751dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* split command line into argument vector */ 752dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint makeargs(char *line, char *argv[], int maxargs) 753dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 754dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat static const char ws[] = " \t\r\n"; 755dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *cp; 756dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int argc = 0; 757dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 758dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (cp = strtok(line, ws); cp; cp = strtok(NULL, ws)) { 759dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc >= (maxargs - 1)) { 760dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Too many arguments to command\n"); 761dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 762dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 763dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argv[argc++] = cp; 764dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 765dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argv[argc] = NULL; 766dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 767dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return argc; 768dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 769