18b52a31eSHanoh Haim/*
28b52a31eSHanoh HaimCopyright (c) 2015-2015 Cisco Systems, Inc.
38b52a31eSHanoh Haim
48b52a31eSHanoh HaimLicensed under the Apache License, Version 2.0 (the "License");
58b52a31eSHanoh Haimyou may not use this file except in compliance with the License.
68b52a31eSHanoh HaimYou may obtain a copy of the License at
78b52a31eSHanoh Haim
88b52a31eSHanoh Haim    http://www.apache.org/licenses/LICENSE-2.0
98b52a31eSHanoh Haim
108b52a31eSHanoh HaimUnless required by applicable law or agreed to in writing, software
118b52a31eSHanoh Haimdistributed under the License is distributed on an "AS IS" BASIS,
128b52a31eSHanoh HaimWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138b52a31eSHanoh HaimSee the License for the specific language governing permissions and
148b52a31eSHanoh Haimlimitations under the License.
158b52a31eSHanoh Haim*/
168b52a31eSHanoh Haim#include "basic_utils.h"
178b52a31eSHanoh Haim#include <ctype.h>
188b52a31eSHanoh Haim#include <stdio.h>
198b52a31eSHanoh Haim#include <string>
204eacb570Simarom#include <sstream>
215f846485Simarom#include <sys/resource.h>
228b52a31eSHanoh Haim
23ab28fcccSimarom#include "pal_utl.h"
24ab28fcccSimarom
25ab28fcccSimaromint my_inet_pton4(const char *src, unsigned char *dst);
26ab28fcccSimarom
278b52a31eSHanoh Haimbool utl_is_file_exists (const std::string& name) {
288b52a31eSHanoh Haim    if (FILE *file = fopen(name.c_str(), "r")) {
298b52a31eSHanoh Haim        fclose(file);
308b52a31eSHanoh Haim        return true;
318b52a31eSHanoh Haim    } else {
328b52a31eSHanoh Haim        return false;
338b52a31eSHanoh Haim    }
348b52a31eSHanoh Haim}
358b52a31eSHanoh Haim
36567fe4bcSHanoh Haimvoid utl_k12_pkt_format(FILE* fp,void  * src,  unsigned int size) {
37567fe4bcSHanoh Haim    unsigned int i;
38567fe4bcSHanoh Haim    fprintf(fp,"\n");
39567fe4bcSHanoh Haim    fprintf(fp,"+---------+---------------+----------+\n");
40567fe4bcSHanoh Haim    fprintf(fp,"00:00:00,000,000   ETHER \n");
41567fe4bcSHanoh Haim    fprintf(fp,"|0   |");
42567fe4bcSHanoh Haim    for ( i=0; i<size;i++ ) {
43567fe4bcSHanoh Haim        fprintf(fp,"%02x|",((unsigned char *)src)[i]);
44567fe4bcSHanoh Haim    }
45567fe4bcSHanoh Haim    fprintf(fp,"\n");;
46567fe4bcSHanoh Haim}
47567fe4bcSHanoh Haim
488b52a31eSHanoh Haim
498b52a31eSHanoh Haimvoid utl_DumpBuffer(FILE* fp,void  * src,  unsigned int size,int offset) {
508b52a31eSHanoh Haim    unsigned int i;
518b52a31eSHanoh Haim    for ( i=0; i<size;i++ ) {
528b52a31eSHanoh Haim        if ( (!(i%16)) && (i!=0) ) fprintf(fp,"]\n");
538b52a31eSHanoh Haim        if ( !(i%4) && !(i%16) ) fprintf(fp,"[");
548b52a31eSHanoh Haim        if ( !(i%4) &&  (i%16) ) fprintf(fp,"] [");
558b52a31eSHanoh Haim        fprintf(fp,"%02x",((unsigned char *)src)[i + offset]);
568b52a31eSHanoh Haim        if ( (i+1)%4 ) fprintf(fp," ");
578b52a31eSHanoh Haim    }
588b52a31eSHanoh Haim    for ( ;i%4;i++ )
598b52a31eSHanoh Haim        fprintf(fp,"  ");
608b52a31eSHanoh Haim    fprintf(fp,"]");
618b52a31eSHanoh Haim
628b52a31eSHanoh Haim    fprintf(fp,"\n");;
638b52a31eSHanoh Haim}
648b52a31eSHanoh Haim
658b52a31eSHanoh Haim
668b52a31eSHanoh Haimvoid utl_DumpChar(FILE* fd,
678b52a31eSHanoh Haim                  void  * src,
688b52a31eSHanoh Haim                  unsigned int eln,
698b52a31eSHanoh Haim                  unsigned int width
708b52a31eSHanoh Haim                  ){
718b52a31eSHanoh Haim    int size=eln*width;
728b52a31eSHanoh Haim    unsigned char * p=(unsigned char *)src;
738b52a31eSHanoh Haim    int i;
748b52a31eSHanoh Haim    fprintf(fd," - ");
758b52a31eSHanoh Haim    for (i=0; i<size;i++) {
768b52a31eSHanoh Haim        if ( isprint(*p) ) {
778b52a31eSHanoh Haim          fprintf(fd,"%c",*p);
788b52a31eSHanoh Haim        }else{
798b52a31eSHanoh Haim            fprintf(fd,"%c",'.');
808b52a31eSHanoh Haim        }
818b52a31eSHanoh Haim        p++;
828b52a31eSHanoh Haim    }
838b52a31eSHanoh Haim}
848b52a31eSHanoh Haim
858b52a31eSHanoh Haimvoid utl_DumpBufferLine(FILE* fd,
868b52a31eSHanoh Haim                        void  * src,
878b52a31eSHanoh Haim                        int     offset,
888b52a31eSHanoh Haim                        unsigned int eln,
898b52a31eSHanoh Haim                        unsigned int width ,
908b52a31eSHanoh Haim                        unsigned int mask){
918b52a31eSHanoh Haim    unsigned char * p=(unsigned char *)src;
928b52a31eSHanoh Haim    uint32 addr;
938b52a31eSHanoh Haim
948b52a31eSHanoh Haim    if ( mask & SHOW_BUFFER_ADDR_EN){
958b52a31eSHanoh Haim        addr=offset;
968b52a31eSHanoh Haim        fprintf(fd,"%08x: ",(int)addr);
978b52a31eSHanoh Haim    }
988b52a31eSHanoh Haim    int i;
998b52a31eSHanoh Haim    for (i=0; i<(int)eln; i++) {
1008b52a31eSHanoh Haim        switch (width) {
1018b52a31eSHanoh Haim            case 1:
1028b52a31eSHanoh Haim                fprintf(fd,"%02x ",*p);
1038b52a31eSHanoh Haim                p++;
1048b52a31eSHanoh Haim                break;
1058b52a31eSHanoh Haim            case 2:
1068b52a31eSHanoh Haim                fprintf(fd,"%04x ",*((uint16 *)p));
1078b52a31eSHanoh Haim                p+=2;
1088b52a31eSHanoh Haim                break;
1098b52a31eSHanoh Haim            case 4:
1108b52a31eSHanoh Haim                fprintf(fd,"%08x ",*((int *)p));
1118b52a31eSHanoh Haim                p+=4;
1128b52a31eSHanoh Haim                break;
1138b52a31eSHanoh Haim            case 8:
1148b52a31eSHanoh Haim                fprintf(fd,"%08x",*((int *)p));
1158b52a31eSHanoh Haim                fprintf(fd,"%08x ",*((int *)(p+4)));
1168b52a31eSHanoh Haim                p+=8;
1178b52a31eSHanoh Haim                break;
1188b52a31eSHanoh Haim        }
1198b52a31eSHanoh Haim    }
1208b52a31eSHanoh Haim    if (mask & SHOW_BUFFER_CHAR) {
1218b52a31eSHanoh Haim       utl_DumpChar(fd, src,eln,width);
1228b52a31eSHanoh Haim    }
1238b52a31eSHanoh Haim    fprintf(fd,"\n");
1248b52a31eSHanoh Haim}
1258b52a31eSHanoh Haim
1268b52a31eSHanoh Haimvoid utl_DumpBuffer2(FILE* fd,
1278b52a31eSHanoh Haim                     void  * src,
1288b52a31eSHanoh Haim                     unsigned int size, //buffer size
1298b52a31eSHanoh Haim                     unsigned int width ,
1308b52a31eSHanoh Haim                     unsigned int width_line ,
1318b52a31eSHanoh Haim                     unsigned int mask
1328b52a31eSHanoh Haim                     ) {
1338b52a31eSHanoh Haim    if (!( (width==1) || (width==2) || (width==4) || (width==8) )){
1348b52a31eSHanoh Haim        width=1;
1358b52a31eSHanoh Haim    }
1368b52a31eSHanoh Haim
1378b52a31eSHanoh Haim    int nlen=(size)/(width_line );
1388b52a31eSHanoh Haim    if ( ( (size % width_line))!=0 ) {
1398b52a31eSHanoh Haim        nlen++;
1408b52a31eSHanoh Haim    }
1418b52a31eSHanoh Haim    int i;
1428b52a31eSHanoh Haim    char *p=(char *)src;
1438b52a31eSHanoh Haim    int offset=0;
1448b52a31eSHanoh Haim
1458b52a31eSHanoh Haim    if (mask & SHOW_BUFFER_ADDR_EN){
1468b52a31eSHanoh Haim        if (mask & SHOW_BUFFER_ADDR) {
1478b52a31eSHanoh Haim            offset=(int)((uintptr_t)p);
1488b52a31eSHanoh Haim        }else{
1498b52a31eSHanoh Haim            offset=0;
1508b52a31eSHanoh Haim        }
1518b52a31eSHanoh Haim    }
1528b52a31eSHanoh Haim    unsigned int eln_w;
1538b52a31eSHanoh Haim    int len_exist=size;
1548b52a31eSHanoh Haim
1558b52a31eSHanoh Haim    for (i=0; i<nlen; i++) {
1568b52a31eSHanoh Haim      if ( len_exist > (int)(width_line /width) ){
1578b52a31eSHanoh Haim        eln_w=width_line /width;
1588b52a31eSHanoh Haim      }else{
1598b52a31eSHanoh Haim        eln_w=(len_exist+width-1)/width;
1608b52a31eSHanoh Haim      }
1618b52a31eSHanoh Haim      utl_DumpBufferLine(fd, p,offset,eln_w,width,mask);
1628b52a31eSHanoh Haim      p+=width_line;
1638b52a31eSHanoh Haim      offset+=width_line;
1648b52a31eSHanoh Haim      len_exist-=  width_line;
1658b52a31eSHanoh Haim    }
1668b52a31eSHanoh Haim}
1678b52a31eSHanoh Haim
1688b52a31eSHanoh Haim
1698b52a31eSHanoh Haimvoid TestDump(void){
1708b52a31eSHanoh Haim
1718b52a31eSHanoh Haim    char buffer[100];
1728b52a31eSHanoh Haim    int i;
1738b52a31eSHanoh Haim    for (i=0;i<100;i++) {
1748b52a31eSHanoh Haim        buffer[i]=0x61+i;
1758b52a31eSHanoh Haim    }
1768b52a31eSHanoh Haim
1778b52a31eSHanoh Haim
1788b52a31eSHanoh Haim    utl_DumpBuffer2(stdout,buffer,31,1,4,SHOW_BUFFER_ADDR_EN |SHOW_BUFFER_CHAR);
1798b52a31eSHanoh Haim}
1808b52a31eSHanoh Haim
18121fe2befSimaromvoid utl_macaddr_to_str(const uint8_t *macaddr, std::string &output) {
18221fe2befSimarom
18321fe2befSimarom    for (int i = 0; i < 6; i++) {
18421fe2befSimarom        char formatted[4];
18521fe2befSimarom
18621fe2befSimarom        if (i == 0) {
18721fe2befSimarom            snprintf(formatted, sizeof(formatted), "%02x", macaddr[i]);
18821fe2befSimarom        } else {
18921fe2befSimarom            snprintf(formatted, sizeof(formatted), ":%02x", macaddr[i]);
19021fe2befSimarom        }
1918b52a31eSHanoh Haim
19221fe2befSimarom        output += formatted;
19321fe2befSimarom    }
19421fe2befSimarom
19521fe2befSimarom}
1964eacb570Simarom
197ab28fcccSimaromstd::string utl_macaddr_to_str(const uint8_t *macaddr) {
198ab28fcccSimarom    std::string tmp;
199ab28fcccSimarom    utl_macaddr_to_str(macaddr, tmp);
200ab28fcccSimarom
201ab28fcccSimarom    return tmp;
202ab28fcccSimarom}
203ab28fcccSimarom
2046e1919c3Simarombool utl_str_to_macaddr(const std::string &s, uint8_t *mac) {
2056e1919c3Simarom    int last = -1;
2066e1919c3Simarom    int rc = sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx%n",
2076e1919c3Simarom                    mac + 0, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5,
2086e1919c3Simarom                    &last);
2096e1919c3Simarom
2106e1919c3Simarom    if ( (rc != 6) || (s.size() != last) ) {
2116e1919c3Simarom        return false;
2126e1919c3Simarom    }
2136e1919c3Simarom
2146e1919c3Simarom    return true;
2156e1919c3Simarom}
2166e1919c3Simarom
2174eacb570Simarom/**
2184eacb570Simarom * generate a random connection handler
2194eacb570Simarom *
2204eacb570Simarom */
2214eacb570Simaromstd::string
2224eacb570Simaromutl_generate_random_str(unsigned int &seed, int len) {
2234eacb570Simarom    std::stringstream ss;
2244eacb570Simarom
2254eacb570Simarom    static const char alphanum[] =
2264eacb570Simarom        "0123456789"
2274eacb570Simarom        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2284eacb570Simarom        "abcdefghijklmnopqrstuvwxyz";
2294eacb570Simarom
2304eacb570Simarom    /* generate 8 bytes of random handler */
2314eacb570Simarom    for (int i = 0; i < len; ++i) {
2324eacb570Simarom        ss << alphanum[rand_r(&seed) % (sizeof(alphanum) - 1)];
2334eacb570Simarom    }
2344eacb570Simarom
2354eacb570Simarom    return (ss.str());
2364eacb570Simarom}
2374eacb570Simarom
2385f846485Simarom/**
2395f846485Simarom * define the coredump size
2405f846485Simarom * allowed when crashing
2415f846485Simarom *
2425f846485Simarom * @param size - -1 means unlimited
2435f846485Simarom * @param map_huge_pages - should the core map the huge TLB
2445f846485Simarom *                       pages
2455f846485Simarom */
2465f846485Simaromvoid utl_set_coredump_size(long size, bool map_huge_pages) {
2475f846485Simarom    int mask;
2485f846485Simarom    struct rlimit core_limits;
2495f846485Simarom
2505f846485Simarom    if (size == -1) {
2515f846485Simarom        core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
2525f846485Simarom    } else {
2535f846485Simarom        core_limits.rlim_cur = core_limits.rlim_max = size;
2545f846485Simarom    }
2555f846485Simarom
2565f846485Simarom    setrlimit(RLIMIT_CORE, &core_limits);
2575f846485Simarom
2585f846485Simarom    /* set core dump mask */
2595f846485Simarom    FILE *fp = fopen("/proc/self/coredump_filter", "wb");
2605f846485Simarom    if (!fp) {
2615f846485Simarom        printf("failed to open /proc/self/coredump_filter\n");
2625f846485Simarom        exit(-1);
2635f846485Simarom    }
2645f846485Simarom
2655f846485Simarom    /* huge pages is the 5th bit */
2665f846485Simarom    if (map_huge_pages) {
2675f846485Simarom        mask = 0x33;
2685f846485Simarom    } else {
2695f846485Simarom        mask = 0x13;
2705f846485Simarom    }
2715f846485Simarom
2725f846485Simarom    fprintf(fp, "%08x\n", mask);
2735f846485Simarom    fclose(fp);
2745f846485Simarom}
275ab28fcccSimarom
276c420d1fdSimarombool utl_ipv4_to_uint32(const char *ipv4_str, uint32_t &ipv4_num) {
277ab28fcccSimarom
278ab28fcccSimarom    uint32_t tmp;
279ab28fcccSimarom
280ab28fcccSimarom    int rc = my_inet_pton4(ipv4_str, (unsigned char *)&tmp);
281ab28fcccSimarom    if (!rc) {
282c420d1fdSimarom        return false;
283ab28fcccSimarom    }
284ab28fcccSimarom
285ab28fcccSimarom    ipv4_num = PAL_NTOHL(tmp);
286ab28fcccSimarom
287c420d1fdSimarom    return true;
288ab28fcccSimarom}
289ab28fcccSimarom
290ab28fcccSimaromstd::string utl_uint32_to_ipv4(uint32_t ipv4_addr) {
291ab28fcccSimarom    std::stringstream ss;
292ab28fcccSimarom    ss << ((ipv4_addr >> 24) & 0xff) << "." << ((ipv4_addr >> 16) & 0xff) << "." << ((ipv4_addr >> 8) & 0xff) << "." << (ipv4_addr & 0xff);
293ab28fcccSimarom    return ss.str();
294ab28fcccSimarom}
295