144d362409d5469aed47d19e7908d19bd194493aThomas Graf/* 244d362409d5469aed47d19e7908d19bd194493aThomas Graf * lib/utils.c Utility Functions 344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 444d362409d5469aed47d19e7908d19bd194493aThomas Graf * This library is free software; you can redistribute it and/or 544d362409d5469aed47d19e7908d19bd194493aThomas Graf * modify it under the terms of the GNU Lesser General Public 644d362409d5469aed47d19e7908d19bd194493aThomas Graf * License as published by the Free Software Foundation version 2.1 744d362409d5469aed47d19e7908d19bd194493aThomas Graf * of the License. 844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 98a3efffa5b3fde252675239914118664d36a2c24Thomas Graf * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf 1244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 136782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf * @ingroup core 1444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @defgroup utils Utilities 1544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 1644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1744d362409d5469aed47d19e7908d19bd194493aThomas Graf 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink-local.h> 1944d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netlink.h> 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/utils.h> 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/socket.h> 2244d362409d5469aed47d19e7908d19bd194493aThomas Graf 2344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 2444d362409d5469aed47d19e7908d19bd194493aThomas Graf * Debug level 2544d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 2644d362409d5469aed47d19e7908d19bd194493aThomas Grafint nl_debug = 0; 2744d362409d5469aed47d19e7908d19bd194493aThomas Graf 2844d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_dump_params nl_debug_dp = { 29d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf .dp_type = NL_DUMP_DETAILS, 3044d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 3144d362409d5469aed47d19e7908d19bd194493aThomas Graf 323c56ed5787481a06703ffb25561df3dd56b447bdThomas Grafstatic void __init nl_debug_init(void) 3344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 343c56ed5787481a06703ffb25561df3dd56b447bdThomas Graf char *nldbg, *end; 353c56ed5787481a06703ffb25561df3dd56b447bdThomas Graf 363c56ed5787481a06703ffb25561df3dd56b447bdThomas Graf if ((nldbg = getenv("NLDBG"))) { 373c56ed5787481a06703ffb25561df3dd56b447bdThomas Graf long level = strtol(nldbg, &end, 0); 383c56ed5787481a06703ffb25561df3dd56b447bdThomas Graf if (nldbg != end) 393c56ed5787481a06703ffb25561df3dd56b447bdThomas Graf nl_debug = level; 403c56ed5787481a06703ffb25561df3dd56b447bdThomas Graf } 413c56ed5787481a06703ffb25561df3dd56b447bdThomas Graf 4244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_debug_dp.dp_fd = stderr; 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf 4544d362409d5469aed47d19e7908d19bd194493aThomas Grafint __nl_read_num_str_file(const char *path, int (*cb)(long, const char *)) 4644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf FILE *fd; 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf fd = fopen(path, "r"); 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (fd == NULL) 528a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -nl_syserr2nlerr(errno); 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf 5444d362409d5469aed47d19e7908d19bd194493aThomas Graf while (fgets(buf, sizeof(buf), fd)) { 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf int goodlen, err; 5644d362409d5469aed47d19e7908d19bd194493aThomas Graf long num; 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf char *end; 5844d362409d5469aed47d19e7908d19bd194493aThomas Graf 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*buf == '#' || *buf == '\n' || *buf == '\r') 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf continue; 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf num = strtol(buf, &end, 0); 6344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (end == buf) 648a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_INVAL; 6544d362409d5469aed47d19e7908d19bd194493aThomas Graf 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (num == LONG_MIN || num == LONG_MAX) 678a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_RANGE; 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf 6944d362409d5469aed47d19e7908d19bd194493aThomas Graf while (*end == ' ' || *end == '\t') 7044d362409d5469aed47d19e7908d19bd194493aThomas Graf end++; 7144d362409d5469aed47d19e7908d19bd194493aThomas Graf 7244d362409d5469aed47d19e7908d19bd194493aThomas Graf goodlen = strcspn(end, "#\r\n\t "); 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (goodlen == 0) 748a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_INVAL; 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf 7644d362409d5469aed47d19e7908d19bd194493aThomas Graf end[goodlen] = '\0'; 7744d362409d5469aed47d19e7908d19bd194493aThomas Graf 7844d362409d5469aed47d19e7908d19bd194493aThomas Graf err = cb(num, end); 7944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf return err; 8144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 8244d362409d5469aed47d19e7908d19bd194493aThomas Graf 8344d362409d5469aed47d19e7908d19bd194493aThomas Graf fclose(fd); 8444d362409d5469aed47d19e7908d19bd194493aThomas Graf 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Unit Pretty-Printing 9044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 9244d362409d5469aed47d19e7908d19bd194493aThomas Graf 9344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 9444d362409d5469aed47d19e7908d19bd194493aThomas Graf * Cancel down a byte counter 9544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg l byte counter 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg unit destination unit pointer 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf * 9844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Cancels down a byte counter until it reaches a reasonable 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf * unit. The chosen unit is assigned to \a unit. 10044d362409d5469aed47d19e7908d19bd194493aThomas Graf * 10144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return The cancelled down byte counter in the new unit. 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 10344d362409d5469aed47d19e7908d19bd194493aThomas Grafdouble nl_cancel_down_bytes(unsigned long long l, char **unit) 10444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l >= 1099511627776LL) { 10644d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "TiB"; 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf return ((double) l) / 1099511627776LL; 10844d362409d5469aed47d19e7908d19bd194493aThomas Graf } else if (l >= 1073741824) { 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "GiB"; 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf return ((double) l) / 1073741824; 11144d362409d5469aed47d19e7908d19bd194493aThomas Graf } else if (l >= 1048576) { 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "MiB"; 11344d362409d5469aed47d19e7908d19bd194493aThomas Graf return ((double) l) / 1048576; 11444d362409d5469aed47d19e7908d19bd194493aThomas Graf } else if (l >= 1024) { 11544d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "KiB"; 11644d362409d5469aed47d19e7908d19bd194493aThomas Graf return ((double) l) / 1024; 11744d362409d5469aed47d19e7908d19bd194493aThomas Graf } else { 11844d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "B"; 11944d362409d5469aed47d19e7908d19bd194493aThomas Graf return (double) l; 12044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 12144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 12244d362409d5469aed47d19e7908d19bd194493aThomas Graf 12344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 12444d362409d5469aed47d19e7908d19bd194493aThomas Graf * Cancel down a bit counter 12544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg l bit counter 12644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg unit destination unit pointer 12744d362409d5469aed47d19e7908d19bd194493aThomas Graf * 12844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Cancels downa bit counter until it reaches a reasonable 12944d362409d5469aed47d19e7908d19bd194493aThomas Graf * unit. The chosen unit is assigned to \a unit. 13044d362409d5469aed47d19e7908d19bd194493aThomas Graf * 13144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return The cancelled down bit counter in the new unit. 13244d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 13344d362409d5469aed47d19e7908d19bd194493aThomas Grafdouble nl_cancel_down_bits(unsigned long long l, char **unit) 13444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 13544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l >= 1099511627776ULL) { 13644d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "Tbit"; 13744d362409d5469aed47d19e7908d19bd194493aThomas Graf return ((double) l) / 1099511627776ULL; 13844d362409d5469aed47d19e7908d19bd194493aThomas Graf } else if (l >= 1073741824) { 13944d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "Gbit"; 14044d362409d5469aed47d19e7908d19bd194493aThomas Graf return ((double) l) / 1073741824; 14144d362409d5469aed47d19e7908d19bd194493aThomas Graf } else if (l >= 1048576) { 14244d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "Mbit"; 14344d362409d5469aed47d19e7908d19bd194493aThomas Graf return ((double) l) / 1048576; 14444d362409d5469aed47d19e7908d19bd194493aThomas Graf } else if (l >= 1024) { 14544d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "Kbit"; 14644d362409d5469aed47d19e7908d19bd194493aThomas Graf return ((double) l) / 1024; 14744d362409d5469aed47d19e7908d19bd194493aThomas Graf } else { 14844d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "bit"; 14944d362409d5469aed47d19e7908d19bd194493aThomas Graf return (double) l; 15044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 15144d362409d5469aed47d19e7908d19bd194493aThomas Graf 15244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 15344d362409d5469aed47d19e7908d19bd194493aThomas Graf 15444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 15544d362409d5469aed47d19e7908d19bd194493aThomas Graf * Cancel down a micro second value 15644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg l micro seconds 15744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg unit destination unit pointer 15844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 15944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Cancels down a microsecond counter until it reaches a 16044d362409d5469aed47d19e7908d19bd194493aThomas Graf * reasonable unit. The chosen unit is assigned to \a unit. 16144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 16244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return The cancelled down microsecond in the new unit 16344d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 16444d362409d5469aed47d19e7908d19bd194493aThomas Grafdouble nl_cancel_down_us(uint32_t l, char **unit) 16544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 16644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l >= 1000000) { 16744d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "s"; 16844d362409d5469aed47d19e7908d19bd194493aThomas Graf return ((double) l) / 1000000; 16944d362409d5469aed47d19e7908d19bd194493aThomas Graf } else if (l >= 1000) { 17044d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "ms"; 17144d362409d5469aed47d19e7908d19bd194493aThomas Graf return ((double) l) / 1000; 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf } else { 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf *unit = "us"; 17444d362409d5469aed47d19e7908d19bd194493aThomas Graf return (double) l; 17544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 17644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 17744d362409d5469aed47d19e7908d19bd194493aThomas Graf 17844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 17944d362409d5469aed47d19e7908d19bd194493aThomas Graf 18044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 18144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Generic Unit Translations 18244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 18344d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 18444d362409d5469aed47d19e7908d19bd194493aThomas Graf 18544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 18644d362409d5469aed47d19e7908d19bd194493aThomas Graf * Convert a character string to a size 18744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg str size encoded as character string 18844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 18944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Converts the specified size as character to the corresponding 19044d362409d5469aed47d19e7908d19bd194493aThomas Graf * number of bytes. 19144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 19244d362409d5469aed47d19e7908d19bd194493aThomas Graf * Supported formats are: 19344d362409d5469aed47d19e7908d19bd194493aThomas Graf * - b,kb/k,m/mb,gb/g for bytes 19444d362409d5469aed47d19e7908d19bd194493aThomas Graf * - bit,kbit/mbit/gbit 19544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 19644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return The number of bytes or -1 if the string is unparseable 19744d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 19844d362409d5469aed47d19e7908d19bd194493aThomas Graflong nl_size2int(const char *str) 19944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 20044d362409d5469aed47d19e7908d19bd194493aThomas Graf char *p; 20144d362409d5469aed47d19e7908d19bd194493aThomas Graf long l = strtol(str, &p, 0); 20244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (p == str) 20300466b0f95af19623c6536edafca6904945ced83Thomas Graf return -NLE_INVAL; 20444d362409d5469aed47d19e7908d19bd194493aThomas Graf 20544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*p) { 20644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!strcasecmp(p, "kb") || !strcasecmp(p, "k")) 20744d362409d5469aed47d19e7908d19bd194493aThomas Graf l *= 1024; 20844d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (!strcasecmp(p, "gb") || !strcasecmp(p, "g")) 20944d362409d5469aed47d19e7908d19bd194493aThomas Graf l *= 1024*1024*1024; 21044d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (!strcasecmp(p, "gbit")) 21144d362409d5469aed47d19e7908d19bd194493aThomas Graf l *= 1024*1024*1024/8; 21244d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (!strcasecmp(p, "mb") || !strcasecmp(p, "m")) 21344d362409d5469aed47d19e7908d19bd194493aThomas Graf l *= 1024*1024; 21444d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (!strcasecmp(p, "mbit")) 21544d362409d5469aed47d19e7908d19bd194493aThomas Graf l *= 1024*1024/8; 21644d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (!strcasecmp(p, "kbit")) 21744d362409d5469aed47d19e7908d19bd194493aThomas Graf l *= 1024/8; 21844d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (!strcasecmp(p, "bit")) 21944d362409d5469aed47d19e7908d19bd194493aThomas Graf l /= 8; 22044d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (strcasecmp(p, "b") != 0) 22100466b0f95af19623c6536edafca6904945ced83Thomas Graf return -NLE_INVAL; 22244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 22344d362409d5469aed47d19e7908d19bd194493aThomas Graf 22444d362409d5469aed47d19e7908d19bd194493aThomas Graf return l; 22544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 22644d362409d5469aed47d19e7908d19bd194493aThomas Graf 22744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 22844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Convert a character string to a probability 22944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg str probability encoded as character string 23044d362409d5469aed47d19e7908d19bd194493aThomas Graf * 23144d362409d5469aed47d19e7908d19bd194493aThomas Graf * Converts the specified probability as character to the 23244d362409d5469aed47d19e7908d19bd194493aThomas Graf * corresponding probability number. 23344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 23444d362409d5469aed47d19e7908d19bd194493aThomas Graf * Supported formats are: 23544d362409d5469aed47d19e7908d19bd194493aThomas Graf * - 0.0-1.0 23644d362409d5469aed47d19e7908d19bd194493aThomas Graf * - 0%-100% 23744d362409d5469aed47d19e7908d19bd194493aThomas Graf * 23844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return The probability relative to NL_PROB_MIN and NL_PROB_MAX 23944d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 24044d362409d5469aed47d19e7908d19bd194493aThomas Graflong nl_prob2int(const char *str) 24144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 24244d362409d5469aed47d19e7908d19bd194493aThomas Graf char *p; 24344d362409d5469aed47d19e7908d19bd194493aThomas Graf double d = strtod(str, &p); 24444d362409d5469aed47d19e7908d19bd194493aThomas Graf 24544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (p == str) 24600466b0f95af19623c6536edafca6904945ced83Thomas Graf return -NLE_INVAL; 24744d362409d5469aed47d19e7908d19bd194493aThomas Graf 24844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (d > 1.0) 24944d362409d5469aed47d19e7908d19bd194493aThomas Graf d /= 100.0f; 25044d362409d5469aed47d19e7908d19bd194493aThomas Graf 25144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (d > 1.0f || d < 0.0f) 25200466b0f95af19623c6536edafca6904945ced83Thomas Graf return -NLE_RANGE; 25344d362409d5469aed47d19e7908d19bd194493aThomas Graf 25444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*p && strcmp(p, "%") != 0) 25500466b0f95af19623c6536edafca6904945ced83Thomas Graf return -NLE_INVAL; 25644d362409d5469aed47d19e7908d19bd194493aThomas Graf 25744d362409d5469aed47d19e7908d19bd194493aThomas Graf return rint(d * NL_PROB_MAX); 25844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 25944d362409d5469aed47d19e7908d19bd194493aThomas Graf 26044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 26144d362409d5469aed47d19e7908d19bd194493aThomas Graf 26244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 26344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Time Translations 26444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 26544d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 26644d362409d5469aed47d19e7908d19bd194493aThomas Graf 26744d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifdef USER_HZ 26844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic uint32_t user_hz = USER_HZ; 26944d362409d5469aed47d19e7908d19bd194493aThomas Graf#else 27044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic uint32_t user_hz = 100; 27144d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 27244d362409d5469aed47d19e7908d19bd194493aThomas Graf 27344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic double ticks_per_usec = 1.0f; 27444d362409d5469aed47d19e7908d19bd194493aThomas Graf 27544d362409d5469aed47d19e7908d19bd194493aThomas Graf/* Retrieves the configured HZ and ticks/us value in the kernel. 27644d362409d5469aed47d19e7908d19bd194493aThomas Graf * The value is cached. Supported ways of getting it: 27744d362409d5469aed47d19e7908d19bd194493aThomas Graf * 27844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 1) environment variable 27944d362409d5469aed47d19e7908d19bd194493aThomas Graf * 2) /proc/net/psched and sysconf 28044d362409d5469aed47d19e7908d19bd194493aThomas Graf * 28144d362409d5469aed47d19e7908d19bd194493aThomas Graf * Supports the environment variables: 28244d362409d5469aed47d19e7908d19bd194493aThomas Graf * PROC_NET_PSCHED - may point to psched file in /proc 28344d362409d5469aed47d19e7908d19bd194493aThomas Graf * PROC_ROOT - may point to /proc fs */ 28444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void __init get_psched_settings(void) 28544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 28644d362409d5469aed47d19e7908d19bd194493aThomas Graf char name[FILENAME_MAX]; 28744d362409d5469aed47d19e7908d19bd194493aThomas Graf FILE *fd; 28852d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández int got_hz = 0; 28944d362409d5469aed47d19e7908d19bd194493aThomas Graf 29044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (getenv("HZ")) { 29144d362409d5469aed47d19e7908d19bd194493aThomas Graf long hz = strtol(getenv("HZ"), NULL, 0); 29244d362409d5469aed47d19e7908d19bd194493aThomas Graf 29344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (LONG_MIN != hz && LONG_MAX != hz) { 29444d362409d5469aed47d19e7908d19bd194493aThomas Graf user_hz = hz; 29544d362409d5469aed47d19e7908d19bd194493aThomas Graf got_hz = 1; 29644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 29744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 29844d362409d5469aed47d19e7908d19bd194493aThomas Graf 29944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!got_hz) 30044d362409d5469aed47d19e7908d19bd194493aThomas Graf user_hz = sysconf(_SC_CLK_TCK); 30144d362409d5469aed47d19e7908d19bd194493aThomas Graf 30244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (getenv("TICKS_PER_USEC")) { 30344d362409d5469aed47d19e7908d19bd194493aThomas Graf double t = strtod(getenv("TICKS_PER_USEC"), NULL); 30444d362409d5469aed47d19e7908d19bd194493aThomas Graf ticks_per_usec = t; 30544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 30652d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández else { 30752d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández if (getenv("PROC_NET_PSCHED")) 30852d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández snprintf(name, sizeof(name), "%s", getenv("PROC_NET_PSCHED")); 30952d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández else if (getenv("PROC_ROOT")) 31052d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández snprintf(name, sizeof(name), "%s/net/psched", 31152d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández getenv("PROC_ROOT")); 31252d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández else 31352d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández strncpy(name, "/proc/net/psched", sizeof(name) - 1); 31444d362409d5469aed47d19e7908d19bd194493aThomas Graf 31552d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández if ((fd = fopen(name, "r"))) { 31652d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández uint32_t tick, us; 31752d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández /* the file contains 4 hexadecimals, but we just use 31852d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández the first two of them */ 3190fa04772ab1e092fce34b658d6cc4e6f6b59be1dThomas Graf fscanf(fd, "%08x %08x", &tick, &us); 32044d362409d5469aed47d19e7908d19bd194493aThomas Graf ticks_per_usec = (double)tick/(double)us; 32152d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández fclose(fd); 32252d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0Jose Ignacio Naranjo Hernández } 32344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 32444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 32544d362409d5469aed47d19e7908d19bd194493aThomas Graf 32644d362409d5469aed47d19e7908d19bd194493aThomas Graf 32744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 32844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Return the value of HZ 32944d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 33044d362409d5469aed47d19e7908d19bd194493aThomas Grafint nl_get_hz(void) 33144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 33244d362409d5469aed47d19e7908d19bd194493aThomas Graf return user_hz; 33344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 33444d362409d5469aed47d19e7908d19bd194493aThomas Graf 33544d362409d5469aed47d19e7908d19bd194493aThomas Graf 33644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 33744d362409d5469aed47d19e7908d19bd194493aThomas Graf * Convert micro seconds to ticks 33844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg us micro seconds 33944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return number of ticks 34044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 34144d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nl_us2ticks(uint32_t us) 34244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 34344d362409d5469aed47d19e7908d19bd194493aThomas Graf return us * ticks_per_usec; 34444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 34544d362409d5469aed47d19e7908d19bd194493aThomas Graf 34644d362409d5469aed47d19e7908d19bd194493aThomas Graf 34744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 34844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Convert ticks to micro seconds 34944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg ticks number of ticks 35044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return microseconds 35144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 35244d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nl_ticks2us(uint32_t ticks) 35344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 35444d362409d5469aed47d19e7908d19bd194493aThomas Graf return ticks / ticks_per_usec; 35544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 35644d362409d5469aed47d19e7908d19bd194493aThomas Graf 357c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Grafint nl_str2msec(const char *str, uint64_t *result) 35844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 359c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf uint64_t total = 0, l; 360c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf int plen; 36144d362409d5469aed47d19e7908d19bd194493aThomas Graf char *p; 36244d362409d5469aed47d19e7908d19bd194493aThomas Graf 363c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf do { 364c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf l = strtoul(str, &p, 0); 365c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf if (p == str) 36600466b0f95af19623c6536edafca6904945ced83Thomas Graf return -NLE_INVAL; 367c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf else if (*p) { 368c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf plen = strcspn(p, " \t"); 369c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf 370c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf if (!plen) 371c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf total += l; 372c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf else if (!strncasecmp(p, "sec", plen)) 373c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf total += (l * 1000); 374c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf else if (!strncasecmp(p, "min", plen)) 375c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf total += (l * 1000*60); 376c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf else if (!strncasecmp(p, "hour", plen)) 377c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf total += (l * 1000*60*60); 378c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf else if (!strncasecmp(p, "day", plen)) 379c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf total += (l * 1000*60*60*24); 380c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf else 381c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf return -NLE_INVAL; 382c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf 383c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf str = p + plen; 384c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf } else 385c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf total += l; 386c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf } while (*str && *p); 387c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf 388c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf *result = total; 38944d362409d5469aed47d19e7908d19bd194493aThomas Graf 390c48a17694b6719606fa76fdad8a5cef3289cb42cThomas Graf return 0; 39144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 39244d362409d5469aed47d19e7908d19bd194493aThomas Graf 39344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 39444d362409d5469aed47d19e7908d19bd194493aThomas Graf * Convert milliseconds to a character string 39544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg msec number of milliseconds 39644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg buf destination buffer 39744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg len buffer length 39844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 39944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Converts milliseconds to a character string split up in days, hours, 40044d362409d5469aed47d19e7908d19bd194493aThomas Graf * minutes, seconds, and milliseconds and stores it in the specified 40144d362409d5469aed47d19e7908d19bd194493aThomas Graf * destination buffer. 40244d362409d5469aed47d19e7908d19bd194493aThomas Graf * 40344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return The destination buffer. 40444d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 40544d362409d5469aed47d19e7908d19bd194493aThomas Grafchar * nl_msec2str(uint64_t msec, char *buf, size_t len) 40644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 40744d362409d5469aed47d19e7908d19bd194493aThomas Graf int i, split[5]; 40844d362409d5469aed47d19e7908d19bd194493aThomas Graf char *units[] = {"d", "h", "m", "s", "msec"}; 40944d362409d5469aed47d19e7908d19bd194493aThomas Graf 41044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define _SPLIT(idx, unit) if ((split[idx] = msec / unit) > 0) msec %= unit 41144d362409d5469aed47d19e7908d19bd194493aThomas Graf _SPLIT(0, 86400000); /* days */ 41244d362409d5469aed47d19e7908d19bd194493aThomas Graf _SPLIT(1, 3600000); /* hours */ 41344d362409d5469aed47d19e7908d19bd194493aThomas Graf _SPLIT(2, 60000); /* minutes */ 41444d362409d5469aed47d19e7908d19bd194493aThomas Graf _SPLIT(3, 1000); /* seconds */ 41544d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef _SPLIT 41644d362409d5469aed47d19e7908d19bd194493aThomas Graf split[4] = msec; 41744d362409d5469aed47d19e7908d19bd194493aThomas Graf 41844d362409d5469aed47d19e7908d19bd194493aThomas Graf memset(buf, 0, len); 41944d362409d5469aed47d19e7908d19bd194493aThomas Graf 42044d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i < ARRAY_SIZE(split); i++) { 42144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (split[i] > 0) { 42244d362409d5469aed47d19e7908d19bd194493aThomas Graf char t[64]; 42344d362409d5469aed47d19e7908d19bd194493aThomas Graf snprintf(t, sizeof(t), "%s%d%s", 42444d362409d5469aed47d19e7908d19bd194493aThomas Graf strlen(buf) ? " " : "", split[i], units[i]); 42544d362409d5469aed47d19e7908d19bd194493aThomas Graf strncat(buf, t, len - strlen(buf) - 1); 42644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 42744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 42844d362409d5469aed47d19e7908d19bd194493aThomas Graf 42944d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 43044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 43144d362409d5469aed47d19e7908d19bd194493aThomas Graf 43244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 43344d362409d5469aed47d19e7908d19bd194493aThomas Graf 43444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 4356782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf * @name Netlink Family Translations 4366782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf * @{ 4376782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf */ 4386782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf 4396782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Grafstatic struct trans_tbl nlfamilies[] = { 4406782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_ROUTE,route) 4416782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_USERSOCK,usersock) 4426782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_FIREWALL,firewall) 4436782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_INET_DIAG,inetdiag) 4446782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_NFLOG,nflog) 4456782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_XFRM,xfrm) 4466782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_SELINUX,selinux) 4476782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_ISCSI,iscsi) 4486782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_AUDIT,audit) 4496782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_FIB_LOOKUP,fib_lookup) 4506782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_CONNECTOR,connector) 4516782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_NETFILTER,netfilter) 4526782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_IP6_FW,ip6_fw) 4536782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_DNRTMSG,dnrtmsg) 4546782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_KOBJECT_UEVENT,kobject_uevent) 4556782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_GENERIC,generic) 4566782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_SCSITRANSPORT,scsitransport) 4576782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf __ADD(NETLINK_ECRYPTFS,ecryptfs) 4586782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf}; 4596782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf 4606782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Grafchar * nl_nlfamily2str(int family, char *buf, size_t size) 4616782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf{ 4626782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf return __type2str(family, buf, size, nlfamilies, 4636782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf ARRAY_SIZE(nlfamilies)); 4646782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf} 4656782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf 4666782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Grafint nl_str2nlfamily(const char *name) 4676782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf{ 4686782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf return __str2type(name, nlfamilies, ARRAY_SIZE(nlfamilies)); 4696782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf} 4706782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf 4716782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf/** 4726782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf * @} 4736782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf */ 4746782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf 4756782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf/** 47644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Link Layer Protocol Translations 47744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 47844d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 47944d362409d5469aed47d19e7908d19bd194493aThomas Graf 48044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl llprotos[] = { 48144d362409d5469aed47d19e7908d19bd194493aThomas Graf {0, "generic"}, 48244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_ETHER,ether) 48344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_EETHER,eether) 48444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_AX25,ax25) 48544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_PRONET,pronet) 48644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_CHAOS,chaos) 48744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_IEEE802,ieee802) 48844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_ARCNET,arcnet) 48944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_APPLETLK,atalk) 49044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_DLCI,dlci) 49144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_ATM,atm) 49244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_METRICOM,metricom) 49344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_IEEE1394,ieee1394) 49444d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifdef ARPHRD_EUI64 49544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_EUI64,eui64) 49644d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 49744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_INFINIBAND,infiniband) 49844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_SLIP,slip) 49944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_CSLIP,cslip) 50044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_SLIP6,slip6) 50144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_CSLIP6,cslip6) 50244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_RSRVD,rsrvd) 50344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_ADAPT,adapt) 50444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_ROSE,rose) 50544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_X25,x25) 50644d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifdef ARPHRD_HWX25 50744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_HWX25,hwx25) 50844d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 50944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_PPP,ppp) 51044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_HDLC,hdlc) 51144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_LAPB,lapb) 51244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_DDCMP,ddcmp) 51344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_RAWHDLC,rawhdlc) 51444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_TUNNEL,ipip) 51544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_TUNNEL6,tunnel6) 51644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FRAD,frad) 51744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_SKIP,skip) 51844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_LOOPBACK,loopback) 51944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_LOCALTLK,localtlk) 52044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FDDI,fddi) 52144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_BIF,bif) 52244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_SIT,sit) 52344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_IPDDP,ip/ddp) 52444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_IPGRE,gre) 52544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_PIMREG,pimreg) 52644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_HIPPI,hippi) 52744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_ASH,ash) 52844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_ECONET,econet) 52944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_IRDA,irda) 53044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCPP,fcpp) 53144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCAL,fcal) 53244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCPL,fcpl) 53344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC,fcfb_0) 53444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+1,fcfb_1) 53544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+2,fcfb_2) 53644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+3,fcfb_3) 53744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+4,fcfb_4) 53844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+5,fcfb_5) 53944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+6,fcfb_6) 54044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+7,fcfb_7) 54144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+8,fcfb_8) 54244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+9,fcfb_9) 54344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+10,fcfb_10) 54444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+11,fcfb_11) 54544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_FCFABRIC+12,fcfb_12) 54644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_IEEE802_TR,tr) 54744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_IEEE80211,ieee802.11) 54844d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifdef ARPHRD_IEEE80211_PRISM 54944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_IEEE80211_PRISM, ieee802.11_prism) 55044d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 55144d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifdef ARPHRD_VOID 55244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ARPHRD_VOID,void) 55344d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 55444d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 55544d362409d5469aed47d19e7908d19bd194493aThomas Graf 55644d362409d5469aed47d19e7908d19bd194493aThomas Grafchar * nl_llproto2str(int llproto, char *buf, size_t len) 55744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 55844d362409d5469aed47d19e7908d19bd194493aThomas Graf return __type2str(llproto, buf, len, llprotos, ARRAY_SIZE(llprotos)); 55944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 56044d362409d5469aed47d19e7908d19bd194493aThomas Graf 56144d362409d5469aed47d19e7908d19bd194493aThomas Grafint nl_str2llproto(const char *name) 56244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 56344d362409d5469aed47d19e7908d19bd194493aThomas Graf return __str2type(name, llprotos, ARRAY_SIZE(llprotos)); 56444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 56544d362409d5469aed47d19e7908d19bd194493aThomas Graf 56644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 56744d362409d5469aed47d19e7908d19bd194493aThomas Graf 56844d362409d5469aed47d19e7908d19bd194493aThomas Graf 56944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 57044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Ethernet Protocol Translations 57144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 57244d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 57344d362409d5469aed47d19e7908d19bd194493aThomas Graf 57444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl ether_protos[] = { 57544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_LOOP,loop) 57644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_PUP,pup) 57744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_PUPAT,pupat) 57844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_IP,ip) 57944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_X25,x25) 58044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_ARP,arp) 58144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_BPQ,bpq) 58244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_IEEEPUP,ieeepup) 58344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_IEEEPUPAT,ieeepupat) 58444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_DEC,dec) 58544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_DNA_DL,dna_dl) 58644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_DNA_RC,dna_rc) 58744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_DNA_RT,dna_rt) 58844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_LAT,lat) 58944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_DIAG,diag) 59044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_CUST,cust) 59144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_SCA,sca) 59244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_RARP,rarp) 59344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_ATALK,atalk) 59444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_AARP,aarp) 59544d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifdef ETH_P_8021Q 59644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_8021Q,802.1q) 59744d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 59844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_IPX,ipx) 59944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_IPV6,ipv6) 60044d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifdef ETH_P_WCCP 60144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_WCCP,wccp) 60244d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 60344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_PPP_DISC,ppp_disc) 60444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_PPP_SES,ppp_ses) 60544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_MPLS_UC,mpls_uc) 60644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_MPLS_MC,mpls_mc) 60744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_ATMMPOA,atmmpoa) 60844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_ATMFATE,atmfate) 60944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_EDP2,edp2) 61044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_802_3,802.3) 61144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_AX25,ax25) 61244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_ALL,all) 61344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_802_2,802.2) 61444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_SNAP,snap) 61544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_DDCMP,ddcmp) 61644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_WAN_PPP,wan_ppp) 61744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_PPP_MP,ppp_mp) 61844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_LOCALTALK,localtalk) 61944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_PPPTALK,ppptalk) 62044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_TR_802_2,tr_802.2) 62144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_MOBITEX,mobitex) 62244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_CONTROL,control) 62344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_IRDA,irda) 62444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_ECONET,econet) 62544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ETH_P_HDLC,hdlc) 62644d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 62744d362409d5469aed47d19e7908d19bd194493aThomas Graf 62844d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *nl_ether_proto2str(int eproto, char *buf, size_t len) 62944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 63044d362409d5469aed47d19e7908d19bd194493aThomas Graf return __type2str(eproto, buf, len, ether_protos, 63144d362409d5469aed47d19e7908d19bd194493aThomas Graf ARRAY_SIZE(ether_protos)); 63244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 63344d362409d5469aed47d19e7908d19bd194493aThomas Graf 63444d362409d5469aed47d19e7908d19bd194493aThomas Grafint nl_str2ether_proto(const char *name) 63544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 63644d362409d5469aed47d19e7908d19bd194493aThomas Graf return __str2type(name, ether_protos, ARRAY_SIZE(ether_protos)); 63744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 63844d362409d5469aed47d19e7908d19bd194493aThomas Graf 63944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 64044d362409d5469aed47d19e7908d19bd194493aThomas Graf 64144d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 64244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name IP Protocol Translations 64344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 64444d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 64544d362409d5469aed47d19e7908d19bd194493aThomas Graf 64644d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *nl_ip_proto2str(int proto, char *buf, size_t len) 64744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 64844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct protoent *p = getprotobynumber(proto); 64944d362409d5469aed47d19e7908d19bd194493aThomas Graf 65044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (p) { 65144d362409d5469aed47d19e7908d19bd194493aThomas Graf snprintf(buf, len, "%s", p->p_name); 65244d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 65344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 65444d362409d5469aed47d19e7908d19bd194493aThomas Graf 65544d362409d5469aed47d19e7908d19bd194493aThomas Graf snprintf(buf, len, "0x%x", proto); 65644d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 65744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 65844d362409d5469aed47d19e7908d19bd194493aThomas Graf 65944d362409d5469aed47d19e7908d19bd194493aThomas Grafint nl_str2ip_proto(const char *name) 66044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 66144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct protoent *p = getprotobyname(name); 66244d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned long l; 66344d362409d5469aed47d19e7908d19bd194493aThomas Graf char *end; 66444d362409d5469aed47d19e7908d19bd194493aThomas Graf 66544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (p) 66644d362409d5469aed47d19e7908d19bd194493aThomas Graf return p->p_proto; 66744d362409d5469aed47d19e7908d19bd194493aThomas Graf 66844d362409d5469aed47d19e7908d19bd194493aThomas Graf l = strtoul(name, &end, 0); 66944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l == ULONG_MAX || *end != '\0') 67000466b0f95af19623c6536edafca6904945ced83Thomas Graf return -NLE_OBJ_NOTFOUND; 67144d362409d5469aed47d19e7908d19bd194493aThomas Graf 67244d362409d5469aed47d19e7908d19bd194493aThomas Graf return (int) l; 67344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 67444d362409d5469aed47d19e7908d19bd194493aThomas Graf 67544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 67644d362409d5469aed47d19e7908d19bd194493aThomas Graf 677508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf/** 678508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * @name Dumping Helpers 679508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * @{ 680508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf */ 681508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf 682508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf/** 683508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * Handle a new line while dumping 684508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * @arg params Dumping parameters 685508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * 686508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * This function must be called before dumping any onto a 687508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * new line. It will ensure proper prefixing as specified 688508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * by the dumping parameters. 689508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * 690508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * @note This function will NOT dump any newlines itself 691508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf */ 692662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Grafvoid nl_new_line(struct nl_dump_params *params) 693508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf{ 694662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf params->dp_line++; 695662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf 696508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf if (params->dp_prefix) { 697508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf int i; 698508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf for (i = 0; i < params->dp_prefix; i++) { 699508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf if (params->dp_fd) 700508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf fprintf(params->dp_fd, " "); 701508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf else if (params->dp_buf) 702508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf strncat(params->dp_buf, " ", 703508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf params->dp_buflen - 704508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf sizeof(params->dp_buf) - 1); 705508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf } 706508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf } 707508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf 708508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf if (params->dp_nl_cb) 709662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf params->dp_nl_cb(params, params->dp_line); 710508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf} 711508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf 7128cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafstatic void dump_one(struct nl_dump_params *parms, const char *fmt, 7138cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf va_list args) 7148cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf{ 7158cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (parms->dp_fd) 7168cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf vfprintf(parms->dp_fd, fmt, args); 7178cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf else if (parms->dp_buf || parms->dp_cb) { 7188cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf char *buf = NULL; 7198cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf vasprintf(&buf, fmt, args); 7208cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (parms->dp_cb) 7218cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf parms->dp_cb(parms, buf); 7228cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf else 7238cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf strncat(parms->dp_buf, buf, 7248cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf parms->dp_buflen - strlen(parms->dp_buf) - 1); 7258cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf free(buf); 7268cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf } 7278cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf} 7288cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 7298cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 730508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf/** 731508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * Dump a formatted character string 732508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * @arg params Dumping parameters 733508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * @arg fmt printf style formatting string 734508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * @arg ... Arguments to formatting string 735508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * 736508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * Dumps a printf style formatting string to the output device 737508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf * as specified by the dumping parameters. 738508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf */ 739508685c269275cb7ba3471c75abc689b4e3839b1Thomas Grafvoid nl_dump(struct nl_dump_params *params, const char *fmt, ...) 740508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf{ 741508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf va_list args; 742508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf 743508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf va_start(args, fmt); 7448cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf dump_one(params, fmt, args); 745508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf va_end(args); 746508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf} 747508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf 748662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Grafvoid nl_dump_line(struct nl_dump_params *parms, const char *fmt, ...) 749662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf{ 750662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf va_list args; 751662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf 752662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf nl_new_line(parms); 753662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf 754662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf va_start(args, fmt); 7558cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf dump_one(parms, fmt, args); 756662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf va_end(args); 757662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf} 758662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf 759662887c052f0fcd98287e2a7fa5843a4f66ca256Thomas Graf 760508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf/** @} */ 761508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf 7628cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf/** @cond SKIP */ 7638cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 7648cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafint __trans_list_add(int i, const char *a, struct nl_list_head *head) 7658cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf{ 7668cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf struct trans_list *tl; 7678cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 7688cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf tl = calloc(1, sizeof(*tl)); 7698cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (!tl) 7708cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return -NLE_NOMEM; 7718cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 7728cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf tl->i = i; 7738cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf tl->a = strdup(a); 7748cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 7758cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf nl_list_add_tail(&tl->list, head); 7768cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 7778cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return 0; 7788cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf} 7798cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 7808cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafvoid __trans_list_clear(struct nl_list_head *head) 7818cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf{ 7828cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf struct trans_list *tl, *next; 7838cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 7848cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf nl_list_for_each_entry_safe(tl, next, head, list) { 7858cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf free(tl->a); 7868cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf free(tl); 7878cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf } 7888cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf} 7898cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 7908cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafchar *__type2str(int type, char *buf, size_t len, struct trans_tbl *tbl, 7918cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf size_t tbl_len) 7928cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf{ 7938cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf int i; 7948cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf for (i = 0; i < tbl_len; i++) { 7958cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (tbl[i].i == type) { 7968cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf snprintf(buf, len, "%s", tbl[i].a); 7978cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return buf; 7988cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf } 7998cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf } 8008cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8018cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf snprintf(buf, len, "0x%x", type); 8028cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return buf; 8038cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf} 8048cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8058cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafchar *__list_type2str(int type, char *buf, size_t len, 8068cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf struct nl_list_head *head) 8078cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf{ 8088cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf struct trans_list *tl; 8098cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8108cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf nl_list_for_each_entry(tl, head, list) { 8118cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (tl->i == type) { 8128cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf snprintf(buf, len, "%s", tl->a); 8138cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return buf; 8148cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf } 8158cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf } 8168cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8178cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf snprintf(buf, len, "0x%x", type); 8188cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return buf; 8198cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf} 8208cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8218cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafchar *__flags2str(int flags, char *buf, size_t len, 8228cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf struct trans_tbl *tbl, size_t tbl_len) 8238cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf{ 8248cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf int i; 8258cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf int tmp = flags; 8268cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8278cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf memset(buf, 0, len); 8288cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8298cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf for (i = 0; i < tbl_len; i++) { 8308cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (tbl[i].i & tmp) { 8318cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf tmp &= ~tbl[i].i; 8328cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf strncat(buf, tbl[i].a, len - strlen(buf) - 1); 8338cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if ((tmp & flags)) 8348cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf strncat(buf, ",", len - strlen(buf) - 1); 8358cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf } 8368cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf } 8378cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8388cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return buf; 8398cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf} 8408cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8418cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafint __str2type(const char *buf, struct trans_tbl *tbl, size_t tbl_len) 8428cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf{ 8438cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf unsigned long l; 8448cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf char *end; 8458cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf int i; 8468cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8478cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (*buf == '\0') 84800466b0f95af19623c6536edafca6904945ced83Thomas Graf return -NLE_INVAL; 8498cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8508cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf for (i = 0; i < tbl_len; i++) 8518cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (!strcasecmp(tbl[i].a, buf)) 8528cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return tbl[i].i; 8538cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8548cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf l = strtoul(buf, &end, 0); 8558cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (l == ULONG_MAX || *end != '\0') 85600466b0f95af19623c6536edafca6904945ced83Thomas Graf return -NLE_OBJ_NOTFOUND; 8578cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8588cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return (int) l; 8598cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf} 8608cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8618cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafint __list_str2type(const char *buf, struct nl_list_head *head) 8628cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf{ 8638cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf struct trans_list *tl; 8648cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf unsigned long l; 8658cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf char *end; 8668cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8678cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (*buf == '\0') 86800466b0f95af19623c6536edafca6904945ced83Thomas Graf return -NLE_INVAL; 8698cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8708cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf nl_list_for_each_entry(tl, head, list) { 8718cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (!strcasecmp(tl->a, buf)) 8728cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return tl->i; 8738cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf } 8748cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8758cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf l = strtoul(buf, &end, 0); 8768cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (l == ULONG_MAX || *end != '\0') 87700466b0f95af19623c6536edafca6904945ced83Thomas Graf return -NLE_OBJ_NOTFOUND; 8788cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8798cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return (int) l; 8808cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf} 8818cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8828cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafint __str2flags(const char *buf, struct trans_tbl *tbl, size_t tbl_len) 8838cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf{ 8848cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf int i, flags = 0, len; 8858cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf char *p = (char *) buf, *t; 8868cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8878cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf for (;;) { 8888cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (*p == ' ') 8898cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf p++; 8908cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8918cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf t = strchr(p, ','); 8928cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf len = t ? t - p : strlen(p); 8938cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf for (i = 0; i < tbl_len; i++) 8948cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (!strncasecmp(tbl[i].a, p, len)) 8958cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf flags |= tbl[i].i; 8968cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 8978cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (!t) 8988cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return flags; 8998cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 9008cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf p = ++t; 9018cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf } 9028cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 9038cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf return 0; 9048cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf} 9058cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 9068cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafvoid dump_from_ops(struct nl_object *obj, struct nl_dump_params *params) 9078cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf{ 9088cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf int type = params->dp_type; 9098cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 9108cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (type < 0 || type > NL_DUMP_MAX) 9118cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf BUG(); 9128cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 9138cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf params->dp_line = 0; 9148cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 9158cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (params->dp_dump_msgtype) { 9168cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf#if 0 9178cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf /* XXX */ 9188cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf char buf[64]; 9198cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 9208cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf dp_dump_line(params, 0, "%s ", 9218cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf nl_cache_mngt_type2name(obj->ce_ops, 9228cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf obj->ce_ops->co_protocol, 9238cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf obj->ce_msgtype, 9248cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf buf, sizeof(buf))); 9258cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf#endif 9268cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf params->dp_pre_dump = 1; 927d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf } 9288cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 9298cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf if (obj->ce_ops->oo_dump[type]) 9308cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf obj->ce_ops->oo_dump[type](obj, params); 9318cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf} 9328cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 9338cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf/** @endcond */ 9348cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf 93544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 936