1 /* 2 * netifd - network interface daemon 3 * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 7 * as published by the Free Software Foundation 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 #include <string.h> 15 #include <stdlib.h> 16 17 #include <arpa/inet.h> 18 #include <netinet/in.h> 19 #include <sys/socket.h> 20 21 #ifdef __APPLE__ 22 #include <libproc.h> 23 #endif 24 25 #include "utils.h" 26 27 void 28 __vlist_simple_init(struct vlist_simple_tree *tree, int offset) 29 { 30 INIT_LIST_HEAD(&tree->list); 31 tree->version = 1; 32 tree->head_offset = offset; 33 } 34 35 void 36 vlist_simple_delete(struct vlist_simple_tree *tree, struct vlist_simple_node *node) 37 { 38 char *ptr; 39 40 list_del(&node->list); 41 ptr = (char *) node - tree->head_offset; 42 free(ptr); 43 } 44 45 void 46 vlist_simple_flush(struct vlist_simple_tree *tree) 47 { 48 struct vlist_simple_node *n, *tmp; 49 50 list_for_each_entry_safe(n, tmp, &tree->list, list) { 51 if ((n->version == tree->version || n->version == -1) && 52 tree->version != -1) 53 continue; 54 55 vlist_simple_delete(tree, n); 56 } 57 } 58 59 void 60 vlist_simple_replace(struct vlist_simple_tree *dest, struct vlist_simple_tree *old) 61 { 62 struct vlist_simple_node *n, *tmp; 63 64 vlist_simple_update(dest); 65 list_for_each_entry_safe(n, tmp, &old->list, list) { 66 list_del(&n->list); 67 vlist_simple_add(dest, n); 68 } 69 vlist_simple_flush(dest); 70 } 71 72 void 73 vlist_simple_flush_all(struct vlist_simple_tree *tree) 74 { 75 tree->version = -1; 76 vlist_simple_flush(tree); 77 } 78 79 unsigned int 80 parse_netmask_string(const char *str, bool v6) 81 { 82 struct in_addr addr; 83 unsigned int ret; 84 char *err = NULL; 85 86 if (!strchr(str, '.')) { 87 ret = strtoul(str, &err, 0); 88 if (err && *err) 89 goto error; 90 91 return ret; 92 } 93 94 if (v6) 95 goto error; 96 97 if (inet_aton(str, &addr) != 1) 98 goto error; 99 100 return 32 - fls(~(ntohl(addr.s_addr))); 101 102 error: 103 return ~0; 104 } 105 106 bool 107 split_netmask(char *str, unsigned int *netmask, bool v6) 108 { 109 char *delim = strchr(str, '/'); 110 111 if (delim) { 112 *(delim++) = 0; 113 114 *netmask = parse_netmask_string(delim, v6); 115 } 116 return true; 117 } 118 119 int 120 parse_ip_and_netmask(int af, const char *str, void *addr, unsigned int *netmask) 121 { 122 char *astr = alloca(strlen(str) + 1); 123 124 strcpy(astr, str); 125 if (!split_netmask(astr, netmask, af == AF_INET6)) 126 return 0; 127 128 if (af == AF_INET6) { 129 if (*netmask > 128) 130 return 0; 131 } else { 132 if (*netmask > 32) 133 return 0; 134 } 135 136 return inet_pton(af, astr, addr); 137 } 138 139 char * 140 format_macaddr(uint8_t *mac) 141 { 142 static char str[sizeof("ff:ff:ff:ff:ff:ff ")]; 143 144 snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", 145 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 146 147 return str; 148 } 149 150 uint32_t 151 crc32_file(FILE *fp) 152 { 153 static uint32_t *crcvals = NULL; 154 if (!crcvals) { 155 crcvals = malloc(sizeof(*crcvals) * 256); 156 157 for (size_t i = 0; i < 256; ++i) { 158 uint32_t c = i; 159 for (size_t j = 0; j < 8; ++j) 160 c = (c & 1) ? (0xEDB88320 ^ (c >> 1)) : (c >> 1); 161 crcvals[i] = c; 162 } 163 } 164 165 uint8_t buf[1024]; 166 size_t len; 167 uint32_t c = 0xFFFFFFFF; 168 169 do { 170 len = fread(buf, 1, sizeof(buf), fp); 171 for (size_t i = 0; i < len; ++i) 172 c = crcvals[(c ^ buf[i]) & 0xFF] ^ (c >> 8); 173 } while (len == sizeof(buf)); 174 175 return c ^ 0xFFFFFFFF; 176 } 177 178 bool check_pid_path(int pid, const char *exe) 179 { 180 const char deleted[] = " (deleted)"; 181 const int deleted_len = strlen(deleted); 182 int proc_exe_len; 183 int exe_len = strlen(exe); 184 185 #ifdef __APPLE__ 186 char proc_exe_buf[PROC_PIDPATHINFO_SIZE]; 187 188 proc_exe_len = proc_pidpath(pid, proc_exe_buf, sizeof(proc_exe_buf)); 189 #else 190 char proc_exe[32]; 191 char *proc_exe_buf = alloca(exe_len); 192 193 sprintf(proc_exe, "/proc/%d/exe", pid); 194 proc_exe_len = readlink(proc_exe, proc_exe_buf, exe_len); 195 #endif 196 197 if (proc_exe_len == exe_len) 198 return !memcmp(exe, proc_exe_buf, exe_len); 199 else if (proc_exe_len == exe_len + deleted_len) 200 return !memcmp(exe, proc_exe_buf, exe_len) && 201 !memcmp(exe + exe_len, deleted, deleted_len); 202 else 203 return false; 204 } 205 206 static const char * const uci_validate_name[__BLOBMSG_TYPE_LAST] = { 207 [BLOBMSG_TYPE_STRING] = "string", 208 [BLOBMSG_TYPE_ARRAY] = "list(string)", 209 [BLOBMSG_TYPE_INT32] = "uinteger", 210 [BLOBMSG_TYPE_BOOL] = "bool", 211 }; 212 213 const char* 214 uci_get_validate_string(const struct uci_blob_param_list *p, int i) 215 { 216 if (p->validate[i]) 217 return p->validate[i]; 218 219 else if (uci_validate_name[p->params[i].type]) 220 return uci_validate_name[p->params[i].type]; 221 222 return p->validate[BLOBMSG_TYPE_STRING]; 223 } 224
This page was automatically generated by LXR 0.3.1. • OpenWrt