basic_utils.cpp revision 567fe4bc
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
23bool utl_is_file_exists (const std::string& name) {
24    if (FILE *file = fopen(name.c_str(), "r")) {
25        fclose(file);
26        return true;
27    } else {
28        return false;
29    }
30}
31
32void utl_k12_pkt_format(FILE* fp,void  * src,  unsigned int size) {
33    unsigned int i;
34    fprintf(fp,"\n");
35    fprintf(fp,"+---------+---------------+----------+\n");
36    fprintf(fp,"00:00:00,000,000   ETHER \n");
37    fprintf(fp,"|0   |");
38    for ( i=0; i<size;i++ ) {
39        fprintf(fp,"%02x|",((unsigned char *)src)[i]);
40    }
41    fprintf(fp,"\n");;
42}
43
44
45void utl_DumpBuffer(FILE* fp,void  * src,  unsigned int size,int offset) {
46    unsigned int i;
47    for ( i=0; i<size;i++ ) {
48        if ( (!(i%16)) && (i!=0) ) fprintf(fp,"]\n");
49        if ( !(i%4) && !(i%16) ) fprintf(fp,"[");
50        if ( !(i%4) &&  (i%16) ) fprintf(fp,"] [");
51        fprintf(fp,"%02x",((unsigned char *)src)[i + offset]);
52        if ( (i+1)%4 ) fprintf(fp," ");
53    }
54    for ( ;i%4;i++ )
55        fprintf(fp,"  ");
56    fprintf(fp,"]");
57
58    fprintf(fp,"\n");;
59}
60
61
62void utl_DumpChar(FILE* fd,
63                  void  * src,
64                  unsigned int eln,
65                  unsigned int width
66                  ){
67    int size=eln*width;
68    unsigned char * p=(unsigned char *)src;
69    int i;
70    fprintf(fd," - ");
71    for (i=0; i<size;i++) {
72        if ( isprint(*p) ) {
73          fprintf(fd,"%c",*p);
74        }else{
75            fprintf(fd,"%c",'.');
76        }
77        p++;
78    }
79}
80
81void utl_DumpBufferLine(FILE* fd,
82                        void  * src,
83                        int     offset,
84                        unsigned int eln,
85                        unsigned int width ,
86                        unsigned int mask){
87    unsigned char * p=(unsigned char *)src;
88    uint32 addr;
89
90    if ( mask & SHOW_BUFFER_ADDR_EN){
91        addr=offset;
92        fprintf(fd,"%08x: ",(int)addr);
93    }
94    int i;
95    for (i=0; i<(int)eln; i++) {
96        switch (width) {
97            case 1:
98                fprintf(fd,"%02x ",*p);
99                p++;
100                break;
101            case 2:
102                fprintf(fd,"%04x ",*((uint16 *)p));
103                p+=2;
104                break;
105            case 4:
106                fprintf(fd,"%08x ",*((int *)p));
107                p+=4;
108                break;
109            case 8:
110                fprintf(fd,"%08x",*((int *)p));
111                fprintf(fd,"%08x ",*((int *)(p+4)));
112                p+=8;
113                break;
114        }
115    }
116    if (mask & SHOW_BUFFER_CHAR) {
117       utl_DumpChar(fd, src,eln,width);
118    }
119    fprintf(fd,"\n");
120}
121
122void utl_DumpBuffer2(FILE* fd,
123                     void  * src,
124                     unsigned int size, //buffer size
125                     unsigned int width ,
126                     unsigned int width_line ,
127                     unsigned int mask
128                     ) {
129    if (!( (width==1) || (width==2) || (width==4) || (width==8) )){
130        width=1;
131    }
132
133    int nlen=(size)/(width_line );
134    if ( ( (size % width_line))!=0 ) {
135        nlen++;
136    }
137    int i;
138    char *p=(char *)src;
139    int offset=0;
140
141    if (mask & SHOW_BUFFER_ADDR_EN){
142        if (mask & SHOW_BUFFER_ADDR) {
143            offset=(int)((uintptr_t)p);
144        }else{
145            offset=0;
146        }
147    }
148    unsigned int eln_w;
149    int len_exist=size;
150
151    for (i=0; i<nlen; i++) {
152      if ( len_exist > (int)(width_line /width) ){
153        eln_w=width_line /width;
154      }else{
155        eln_w=(len_exist+width-1)/width;
156      }
157      utl_DumpBufferLine(fd, p,offset,eln_w,width,mask);
158      p+=width_line;
159      offset+=width_line;
160      len_exist-=  width_line;
161    }
162}
163
164
165void TestDump(void){
166
167    char buffer[100];
168    int i;
169    for (i=0;i<100;i++) {
170        buffer[i]=0x61+i;
171    }
172
173
174    utl_DumpBuffer2(stdout,buffer,31,1,4,SHOW_BUFFER_ADDR_EN |SHOW_BUFFER_CHAR);
175}
176
177void utl_macaddr_to_str(const uint8_t *macaddr, std::string &output) {
178
179    for (int i = 0; i < 6; i++) {
180        char formatted[4];
181
182        if (i == 0) {
183            snprintf(formatted, sizeof(formatted), "%02x", macaddr[i]);
184        } else {
185            snprintf(formatted, sizeof(formatted), ":%02x", macaddr[i]);
186        }
187
188        output += formatted;
189    }
190
191}
192
193/**
194 * generate a random connection handler
195 *
196 */
197std::string
198utl_generate_random_str(unsigned int &seed, int len) {
199    std::stringstream ss;
200
201    static const char alphanum[] =
202        "0123456789"
203        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
204        "abcdefghijklmnopqrstuvwxyz";
205
206    /* generate 8 bytes of random handler */
207    for (int i = 0; i < len; ++i) {
208        ss << alphanum[rand_r(&seed) % (sizeof(alphanum) - 1)];
209    }
210
211    return (ss.str());
212}
213
214/**
215 * define the coredump size
216 * allowed when crashing
217 *
218 * @param size - -1 means unlimited
219 * @param map_huge_pages - should the core map the huge TLB
220 *                       pages
221 */
222void utl_set_coredump_size(long size, bool map_huge_pages) {
223    int mask;
224    struct rlimit core_limits;
225
226    if (size == -1) {
227        core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
228    } else {
229        core_limits.rlim_cur = core_limits.rlim_max = size;
230    }
231
232    setrlimit(RLIMIT_CORE, &core_limits);
233
234    /* set core dump mask */
235    FILE *fp = fopen("/proc/self/coredump_filter", "wb");
236    if (!fp) {
237        printf("failed to open /proc/self/coredump_filter\n");
238        exit(-1);
239    }
240
241    /* huge pages is the 5th bit */
242    if (map_huge_pages) {
243        mask = 0x33;
244    } else {
245        mask = 0x13;
246    }
247
248    fprintf(fp, "%08x\n", mask);
249    fclose(fp);
250}
251