basic_utils.cpp revision c420d1fd
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
204bool utl_str_to_macaddr(const std::string &s, uint8_t *mac) {
205    int last = -1;
206    int rc = sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx%n",
207                    mac + 0, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5,
208                    &last);
209
210    if ( (rc != 6) || (s.size() != last) ) {
211        return false;
212    }
213
214    return true;
215}
216
217/**
218 * generate a random connection handler
219 *
220 */
221std::string
222utl_generate_random_str(unsigned int &seed, int len) {
223    std::stringstream ss;
224
225    static const char alphanum[] =
226        "0123456789"
227        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
228        "abcdefghijklmnopqrstuvwxyz";
229
230    /* generate 8 bytes of random handler */
231    for (int i = 0; i < len; ++i) {
232        ss << alphanum[rand_r(&seed) % (sizeof(alphanum) - 1)];
233    }
234
235    return (ss.str());
236}
237
238/**
239 * define the coredump size
240 * allowed when crashing
241 *
242 * @param size - -1 means unlimited
243 * @param map_huge_pages - should the core map the huge TLB
244 *                       pages
245 */
246void utl_set_coredump_size(long size, bool map_huge_pages) {
247    int mask;
248    struct rlimit core_limits;
249
250    if (size == -1) {
251        core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
252    } else {
253        core_limits.rlim_cur = core_limits.rlim_max = size;
254    }
255
256    setrlimit(RLIMIT_CORE, &core_limits);
257
258    /* set core dump mask */
259    FILE *fp = fopen("/proc/self/coredump_filter", "wb");
260    if (!fp) {
261        printf("failed to open /proc/self/coredump_filter\n");
262        exit(-1);
263    }
264
265    /* huge pages is the 5th bit */
266    if (map_huge_pages) {
267        mask = 0x33;
268    } else {
269        mask = 0x13;
270    }
271
272    fprintf(fp, "%08x\n", mask);
273    fclose(fp);
274}
275
276bool utl_ipv4_to_uint32(const char *ipv4_str, uint32_t &ipv4_num) {
277
278    uint32_t tmp;
279
280    int rc = my_inet_pton4(ipv4_str, (unsigned char *)&tmp);
281    if (!rc) {
282        return false;
283    }
284
285    ipv4_num = PAL_NTOHL(tmp);
286
287    return true;
288}
289
290std::string utl_uint32_to_ipv4(uint32_t ipv4_addr) {
291    std::stringstream ss;
292    ss << ((ipv4_addr >> 24) & 0xff) << "." << ((ipv4_addr >> 16) & 0xff) << "." << ((ipv4_addr >> 8) & 0xff) << "." << (ipv4_addr & 0xff);
293    return ss.str();
294}
295