basic_utils.cpp revision ab28fccc
1/*
2Copyright (c) 2015-2015 Cisco Systems, Inc.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16#include "basic_utils.h"
17#include <ctype.h>
18#include <stdio.h>
19#include <string>
20#include <sstream>
21#include <sys/resource.h>
22
23#include "pal_utl.h"
24
25int my_inet_pton4(const char *src, unsigned char *dst);
26
27bool utl_is_file_exists (const std::string& name) {
28    if (FILE *file = fopen(name.c_str(), "r")) {
29        fclose(file);
30        return true;
31    } else {
32        return false;
33    }
34}
35
36void utl_k12_pkt_format(FILE* fp,void  * src,  unsigned int size) {
37    unsigned int i;
38    fprintf(fp,"\n");
39    fprintf(fp,"+---------+---------------+----------+\n");
40    fprintf(fp,"00:00:00,000,000   ETHER \n");
41    fprintf(fp,"|0   |");
42    for ( i=0; i<size;i++ ) {
43        fprintf(fp,"%02x|",((unsigned char *)src)[i]);
44    }
45    fprintf(fp,"\n");;
46}
47
48
49void utl_DumpBuffer(FILE* fp,void  * src,  unsigned int size,int offset) {
50    unsigned int i;
51    for ( i=0; i<size;i++ ) {
52        if ( (!(i%16)) && (i!=0) ) fprintf(fp,"]\n");
53        if ( !(i%4) && !(i%16) ) fprintf(fp,"[");
54        if ( !(i%4) &&  (i%16) ) fprintf(fp,"] [");
55        fprintf(fp,"%02x",((unsigned char *)src)[i + offset]);
56        if ( (i+1)%4 ) fprintf(fp," ");
57    }
58    for ( ;i%4;i++ )
59        fprintf(fp,"  ");
60    fprintf(fp,"]");
61
62    fprintf(fp,"\n");;
63}
64
65
66void utl_DumpChar(FILE* fd,
67                  void  * src,
68                  unsigned int eln,
69                  unsigned int width
70                  ){
71    int size=eln*width;
72    unsigned char * p=(unsigned char *)src;
73    int i;
74    fprintf(fd," - ");
75    for (i=0; i<size;i++) {
76        if ( isprint(*p) ) {
77          fprintf(fd,"%c",*p);
78        }else{
79            fprintf(fd,"%c",'.');
80        }
81        p++;
82    }
83}
84
85void utl_DumpBufferLine(FILE* fd,
86                        void  * src,
87                        int     offset,
88                        unsigned int eln,
89                        unsigned int width ,
90                        unsigned int mask){
91    unsigned char * p=(unsigned char *)src;
92    uint32 addr;
93
94    if ( mask & SHOW_BUFFER_ADDR_EN){
95        addr=offset;
96        fprintf(fd,"%08x: ",(int)addr);
97    }
98    int i;
99    for (i=0; i<(int)eln; i++) {
100        switch (width) {
101            case 1:
102                fprintf(fd,"%02x ",*p);
103                p++;
104                break;
105            case 2:
106                fprintf(fd,"%04x ",*((uint16 *)p));
107                p+=2;
108                break;
109            case 4:
110                fprintf(fd,"%08x ",*((int *)p));
111                p+=4;
112                break;
113            case 8:
114                fprintf(fd,"%08x",*((int *)p));
115                fprintf(fd,"%08x ",*((int *)(p+4)));
116                p+=8;
117                break;
118        }
119    }
120    if (mask & SHOW_BUFFER_CHAR) {
121       utl_DumpChar(fd, src,eln,width);
122    }
123    fprintf(fd,"\n");
124}
125
126void utl_DumpBuffer2(FILE* fd,
127                     void  * src,
128                     unsigned int size, //buffer size
129                     unsigned int width ,
130                     unsigned int width_line ,
131                     unsigned int mask
132                     ) {
133    if (!( (width==1) || (width==2) || (width==4) || (width==8) )){
134        width=1;
135    }
136
137    int nlen=(size)/(width_line );
138    if ( ( (size % width_line))!=0 ) {
139        nlen++;
140    }
141    int i;
142    char *p=(char *)src;
143    int offset=0;
144
145    if (mask & SHOW_BUFFER_ADDR_EN){
146        if (mask & SHOW_BUFFER_ADDR) {
147            offset=(int)((uintptr_t)p);
148        }else{
149            offset=0;
150        }
151    }
152    unsigned int eln_w;
153    int len_exist=size;
154
155    for (i=0; i<nlen; i++) {
156      if ( len_exist > (int)(width_line /width) ){
157        eln_w=width_line /width;
158      }else{
159        eln_w=(len_exist+width-1)/width;
160      }
161      utl_DumpBufferLine(fd, p,offset,eln_w,width,mask);
162      p+=width_line;
163      offset+=width_line;
164      len_exist-=  width_line;
165    }
166}
167
168
169void TestDump(void){
170
171    char buffer[100];
172    int i;
173    for (i=0;i<100;i++) {
174        buffer[i]=0x61+i;
175    }
176
177
178    utl_DumpBuffer2(stdout,buffer,31,1,4,SHOW_BUFFER_ADDR_EN |SHOW_BUFFER_CHAR);
179}
180
181void utl_macaddr_to_str(const uint8_t *macaddr, std::string &output) {
182
183    for (int i = 0; i < 6; i++) {
184        char formatted[4];
185
186        if (i == 0) {
187            snprintf(formatted, sizeof(formatted), "%02x", macaddr[i]);
188        } else {
189            snprintf(formatted, sizeof(formatted), ":%02x", macaddr[i]);
190        }
191
192        output += formatted;
193    }
194
195}
196
197std::string utl_macaddr_to_str(const uint8_t *macaddr) {
198    std::string tmp;
199    utl_macaddr_to_str(macaddr, tmp);
200
201    return tmp;
202}
203
204/**
205 * generate a random connection handler
206 *
207 */
208std::string
209utl_generate_random_str(unsigned int &seed, int len) {
210    std::stringstream ss;
211
212    static const char alphanum[] =
213        "0123456789"
214        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
215        "abcdefghijklmnopqrstuvwxyz";
216
217    /* generate 8 bytes of random handler */
218    for (int i = 0; i < len; ++i) {
219        ss << alphanum[rand_r(&seed) % (sizeof(alphanum) - 1)];
220    }
221
222    return (ss.str());
223}
224
225/**
226 * define the coredump size
227 * allowed when crashing
228 *
229 * @param size - -1 means unlimited
230 * @param map_huge_pages - should the core map the huge TLB
231 *                       pages
232 */
233void utl_set_coredump_size(long size, bool map_huge_pages) {
234    int mask;
235    struct rlimit core_limits;
236
237    if (size == -1) {
238        core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
239    } else {
240        core_limits.rlim_cur = core_limits.rlim_max = size;
241    }
242
243    setrlimit(RLIMIT_CORE, &core_limits);
244
245    /* set core dump mask */
246    FILE *fp = fopen("/proc/self/coredump_filter", "wb");
247    if (!fp) {
248        printf("failed to open /proc/self/coredump_filter\n");
249        exit(-1);
250    }
251
252    /* huge pages is the 5th bit */
253    if (map_huge_pages) {
254        mask = 0x33;
255    } else {
256        mask = 0x13;
257    }
258
259    fprintf(fp, "%08x\n", mask);
260    fclose(fp);
261}
262
263uint32_t utl_ipv4_to_uint32(const char *ipv4_str, uint32_t &ipv4_num) {
264
265    uint32_t tmp;
266
267    int rc = my_inet_pton4(ipv4_str, (unsigned char *)&tmp);
268    if (!rc) {
269        return (0);
270    }
271
272    ipv4_num = PAL_NTOHL(tmp);
273
274    return (1);
275}
276
277std::string utl_uint32_to_ipv4(uint32_t ipv4_addr) {
278    std::stringstream ss;
279    ss << ((ipv4_addr >> 24) & 0xff) << "." << ((ipv4_addr >> 16) & 0xff) << "." << ((ipv4_addr >> 8) & 0xff) << "." << (ipv4_addr & 0xff);
280    return ss.str();
281}
282