(Trivial) Fix spellling in a comment.
[metze/wireshark/wip.git] / epan / address_to_str.c
1 /* address_to_str.c
2  * Routines for utilities to convert addresses to strings.
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 #include "config.h"
26
27 #include <stdlib.h>
28 #include <string.h>
29
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>         /* needed for <netinet/in.h> */
32 #endif
33
34 #ifdef HAVE_NETINET_IN_H
35 # include <netinet/in.h>        /* needed for <arpa/inet.h> on some platforms */
36 #endif
37
38 #ifdef HAVE_ARPA_INET_H
39 #include <arpa/inet.h>
40 #endif
41
42 #ifdef HAVE_SYS_SOCKET_H
43 #include <sys/socket.h>         /* needed to define AF_ values on UNIX */
44 #endif
45
46 #ifdef HAVE_WINSOCK2_H
47 #include <winsock2.h>           /* needed to define AF_ values on Windows */
48 #endif
49
50 #ifdef NEED_INET_V6DEFS_H
51 # include "wsutil/inet_v6defs.h"
52 #endif
53
54 #include "to_str-int.h"
55 #include "to_str.h"
56 #include "value_string.h"
57 #include "addr_resolv.h"
58 #include "wsutil/pint.h"
59 #include "atalk-utils.h"
60 #include "sna-utils.h"
61 #include "osi-utils.h"
62 #include <epan/dissectors/packet-mtp3.h>
63 #include <stdio.h>
64 #include "emem.h"
65 #include "wmem/wmem.h"
66
67 /*
68  * If a user _does_ pass in a too-small buffer, this is probably
69  * going to be too long to fit.  However, even a partial string
70  * starting with "[Buf" should provide enough of a clue to be
71  * useful.
72  */
73 #define BUF_TOO_SMALL_ERR "[Buffer too small]"
74
75 /* Wrapper for the most common case of asking
76  * for a string using a colon as the hex-digit separator.
77  */
78 /* XXX FIXME
79 remove this one later when every call has been converted to ep_address_to_str()
80 */
81 const gchar *
82 ether_to_str(const guint8 *ad)
83 {
84     return bytestring_to_ep_str(ad, 6, ':');
85 }
86
87 const gchar *
88 tvb_ether_to_str(tvbuff_t *tvb, const gint offset)
89 {
90     return bytestring_to_ep_str(tvb_get_ptr(tvb, offset, 6), 6, ':');
91 }
92
93 /*
94  This function is very fast and this function is called a lot.
95  XXX update the ep_address_to_str stuff to use this function.
96 */
97 const gchar *
98 ip_to_str(const guint8 *ad) {
99     gchar *buf;
100
101     buf=(gchar *)ep_alloc(MAX_IP_STR_LEN);
102     ip_to_str_buf(ad, buf, MAX_IP_STR_LEN);
103     return buf;
104 }
105
106 #define IPV4_LENGTH 4
107 const gchar *
108 tvb_ip_to_str(tvbuff_t *tvb, const gint offset)
109 {
110     gchar *buf;
111
112     buf=(gchar *)ep_alloc(MAX_IP_STR_LEN);
113     ip_to_str_buf(tvb_get_ptr(tvb, offset, IPV4_LENGTH), buf, MAX_IP_STR_LEN);
114     return buf;
115 }
116
117 /* XXX FIXME
118 remove this one later when every call has been converted to ep_address_to_str()
119 */
120 const gchar *
121 ip6_to_str(const struct e_in6_addr *ad) {
122     gchar *str;
123
124     str=(gchar *)ep_alloc(MAX_IP6_STR_LEN);
125     ip6_to_str_buf(ad, str);
126     return str;
127 }
128
129 #define IPV6_LENGTH 16
130 const gchar *
131 tvb_ip6_to_str(tvbuff_t *tvb, const gint offset)
132 {
133     gchar *buf;
134
135     buf=(gchar *)ep_alloc(MAX_IP6_STR_LEN);
136     ip6_to_str_buf((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, IPV6_LENGTH), buf);
137     return buf;
138 }
139
140 /* const char *
141  * inet_ntop6(src, dst, size)
142  *  convert IPv6 binary address into presentation (printable) format
143  * author:
144  *  Paul Vixie, 1996.
145  */
146 static void
147 ip6_to_str_buf_len(const guchar* src, char *buf, size_t buf_len)
148 {
149     struct { int base, len; } best, cur;
150     guint words[8];
151     int i;
152
153     if (buf_len < MAX_IP6_STR_LEN) { /* buf_len < 40 */
154         g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
155         return;
156     }
157
158     /*
159      * Preprocess:
160      *  Copy the input (bytewise) array into a wordwise array.
161      *  Find the longest run of 0x00's in src[] for :: shorthanding.
162      */
163     for (i = 0; i < 16; i += 2) {
164         words[i / 2] = (src[i+1] << 0);
165         words[i / 2] |= (src[i] << 8);
166     }
167     best.base = -1; best.len = 0;
168     cur.base = -1;  cur.len = 0;
169     for (i = 0; i < 8; i++) {
170         if (words[i] == 0) {
171             if (cur.base == -1) {
172                 cur.base = i;
173                 cur.len = 1;
174             } else
175                 cur.len++;
176         } else {
177             if (cur.base != -1) {
178                 if (best.base == -1 || cur.len > best.len)
179                     best = cur;
180                 cur.base = -1;
181             }
182         }
183     }
184     if (cur.base != -1) {
185         if (best.base == -1 || cur.len > best.len)
186             best = cur;
187     }
188     if (best.base != -1 && best.len < 2)
189         best.base = -1;
190
191     /* Is this address an encapsulated IPv4? */
192     /* XXX,
193      * Orginal code dated 1996 uses ::/96 as a valid IPv4-compatible addresses
194      * but since Feb 2006 ::/96 is deprecated one.
195      * Quoting wikipedia [0]:
196      * > The 96-bit zero-value prefix ::/96, originally known as IPv4-compatible
197      * > addresses, was mentioned in 1995[35] but first described in 1998.[41]
198      * > This class of addresses was used to represent IPv4 addresses within
199      * > an IPv6 transition technology. Such an IPv6 address has its first
200      * > (most significant) 96 bits set to zero, while its last 32 bits are the
201      * > IPv4 address that is represented.
202      * > In February 2006 the Internet Engineering Task Force (IETF) has deprecated
203      * > the use of IPv4-compatible addresses.[1] The only remaining use of this address
204      * > format is to represent an IPv4 address in a table or database with fixed size
205      * > members that must also be able to store an IPv6 address.
206      *
207      * If needed it can be fixed by changing next line:
208      *   if (best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
209      * to:
210      *   if (best.base == 0 && best.len == 5 && words[5] == 0xffff)
211      *
212      * [0] http://en.wikipedia.org/wiki/IPv6_address#Historical_notes
213      */
214
215     if (best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
216     {
217         /* best.len == 6 -> ::IPv4; 5 -> ::ffff:IPv4 */
218         buf = g_stpcpy(buf, "::");
219         if (best.len == 5)
220         buf = g_stpcpy(buf, "ffff:");
221         ip_to_str_buf(src + 12, buf, MAX_IP_STR_LEN);
222         /* max: 2 + 5 + 16 == 23 bytes */
223         return;
224     }
225
226     /*
227      * Format the result.
228      */
229     for (i = 0; i < 8; i++) {
230         /* Are we inside the best run of 0x00's? */
231         if (i == best.base) {
232             *buf++ = ':';
233             i += best.len;
234
235             /* Was it a trailing run of 0x00's? */
236             if (i == 8) {
237                 *buf++ = ':';
238                 break;
239             }
240         }
241         /* Are we following an initial run of 0x00s or any real hex? */
242         if (i != 0)
243             *buf++ = ':';
244
245         buf = word_to_hex_npad(buf, words[i]); /* max: 4B */
246         /* max: 8 * 4 + 7 == 39 bytes */
247     }
248     *buf = '\0'; /* 40 byte */
249 }
250
251 void
252 ip6_to_str_buf(const struct e_in6_addr *ad, gchar *buf)
253 {
254     ip6_to_str_buf_len((const guchar*)ad, buf, MAX_IP6_STR_LEN);
255 }
256
257 gchar*
258 ipx_addr_to_str(const guint32 net, const guint8 *ad)
259 {
260     gchar   *buf;
261     char    *name;
262
263     name = get_ether_name_if_known(ad);
264
265     if (name) {
266         buf = ep_strdup_printf("%s.%s", get_ipxnet_name(net), name);
267     }
268     else {
269         buf = ep_strdup_printf("%s.%s", get_ipxnet_name(net),
270             bytestring_to_ep_str(ad, 6, '\0'));
271     }
272     return buf;
273 }
274
275 gchar*
276 ipxnet_to_string(const guint8 *ad)
277 {
278     guint32 addr = pntoh32(ad);
279     return ipxnet_to_str_punct(addr, ' ');
280 }
281
282 gchar *
283 ipxnet_to_str_punct(const guint32 ad, const char punct)
284 {
285     gchar *buf = (gchar *)ep_alloc(12);
286
287     *dword_to_hex_punct(buf, ad, punct) = '\0';
288     return buf;
289 }
290
291 static void
292 vines_addr_to_str_buf(const guint8 *addrp, gchar *buf, int buf_len)
293 {
294     if (buf_len < 14) {
295         g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
296         return;
297     }
298
299     buf = dword_to_hex(buf, pntoh32(&addrp[0])); /* 8 bytes */
300     *buf++ = '.'; /* 1 byte */
301     buf = word_to_hex(buf, pntoh16(&addrp[4])); /* 4 bytes */
302     *buf = '\0'; /* 1 byte */
303 }
304
305 gchar *
306 tvb_vines_addr_to_str(tvbuff_t *tvb, const gint offset)
307 {
308     gchar *buf;
309
310     buf=(gchar *)ep_alloc(214); /* XXX, 14 here? */
311
312     vines_addr_to_str_buf(tvb_get_ptr(tvb, offset, VINES_ADDR_LEN), buf, 214);
313     return buf;
314 }
315
316 /*
317  This function is very fast and this function is called a lot.
318  XXX update the ep_address_to_str stuff to use this function.
319 */
320 gchar *
321 eui64_to_str(const guint64 ad) {
322     gchar *buf;
323     guint8 *p_eui64;
324
325     p_eui64 = (guint8 *)ep_alloc(8);
326     buf=(gchar *)ep_alloc(EUI64_STR_LEN);
327
328     /* Copy and convert the address to network byte order. */
329     *(guint64 *)(void *)(p_eui64) = pntoh64(&(ad));
330
331     g_snprintf(buf, EUI64_STR_LEN, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
332     p_eui64[0], p_eui64[1], p_eui64[2], p_eui64[3],
333     p_eui64[4], p_eui64[5], p_eui64[6], p_eui64[7] );
334     return buf;
335 }
336 gchar *
337 tvb_eui64_to_str(tvbuff_t *tvb, const gint offset, const guint encoding)
338 {
339     if(encoding)
340     {
341         return eui64_to_str(tvb_get_letoh64(tvb, offset));
342     }else {
343         return eui64_to_str(tvb_get_ntoh64(tvb, offset));
344     }
345 }
346
347 static void
348 usb_addr_to_str_buf(const guint8 *addrp, gchar *buf, int buf_len)
349 {
350     if(pletoh32(&addrp[0])==0xffffffff){
351         g_snprintf(buf, buf_len, "host");
352     } else {
353         g_snprintf(buf, buf_len, "%d.%d", pletoh32(&addrp[0]), pletoh32(&addrp[4]));
354     }
355 }
356
357 static void
358 tipc_addr_to_str_buf( const guint8 *data, gchar *buf, int buf_len){
359     guint8 zone;
360     guint16 subnetwork;
361     guint16 processor;
362     guint32 tipc_address;
363
364     tipc_address = data[0];
365     tipc_address = (tipc_address << 8) ^ data[1];
366     tipc_address = (tipc_address << 8) ^ data[2];
367     tipc_address = (tipc_address << 8) ^ data[3];
368
369     processor = tipc_address & 0x0fff;
370
371     tipc_address = tipc_address >> 12;
372     subnetwork = tipc_address & 0x0fff;
373
374     tipc_address = tipc_address >> 12;
375     zone = tipc_address & 0xff;
376
377     g_snprintf(buf,buf_len,"%u.%u.%u",zone,subnetwork,processor);
378 }
379
380 static void
381 ib_addr_to_str_buf( const address *addr, gchar *buf, int buf_len){
382     if (addr->len >= 16) { /* GID is 128bits */
383         #define PREAMBLE_STR_LEN ((int)(sizeof("GID: ") - 1))
384         g_snprintf(buf,buf_len,"GID: ");
385         if (buf_len < PREAMBLE_STR_LEN ||
386                 inet_ntop(AF_INET6, addr->data, buf + PREAMBLE_STR_LEN,
387                           buf_len - PREAMBLE_STR_LEN) == NULL ) /* Returns NULL if no space and does not touch buf */
388             g_snprintf ( buf, buf_len, BUF_TOO_SMALL_ERR ); /* Let the unexpected value alert user */
389     } else {    /* this is a LID (16 bits) */
390         guint16 lid_number;
391
392         memcpy((void *)&lid_number, addr->data, sizeof lid_number);
393         g_snprintf(buf,buf_len,"LID: %u",lid_number);
394     }
395 }
396
397 /* XXX FIXME
398 remove this one later when every call has been converted to ep_address_to_str()
399 */
400 const gchar *
401 fc_to_str(const guint8 *ad)
402 {
403     return bytestring_to_ep_str (ad, 3, '.');
404 }
405
406 const gchar *
407 tvb_fc_to_str(tvbuff_t *tvb, const gint offset)
408 {
409     return bytestring_to_ep_str (tvb_get_ptr(tvb, offset, 3), 3, '.');
410 }
411
412 /* FC Network Header Network Address Authority Identifiers */
413
414 #define FC_NH_NAA_IEEE          1   /* IEEE 802.1a */
415 #define FC_NH_NAA_IEEE_E        2   /* IEEE Exteneded */
416 #define FC_NH_NAA_LOCAL         3
417 #define FC_NH_NAA_IP            4   /* 32-bit IP address */
418 #define FC_NH_NAA_IEEE_R        5   /* IEEE Registered */
419 #define FC_NH_NAA_IEEE_R_E      6   /* IEEE Registered Exteneded */
420 /* according to FC-PH 3 draft these are now reclaimed and reserved */
421 #define FC_NH_NAA_CCITT_INDV    12  /* CCITT 60 bit individual address */
422 #define FC_NH_NAA_CCITT_GRP     14  /* CCITT 60 bit group address */
423
424 gchar *
425 fcwwn_to_str (const guint8 *ad)
426 {
427     int fmt;
428     guint8 oui[6];
429     gchar *ethstr;
430     gchar *ethptr;
431
432     if (ad == NULL) return NULL;
433
434     ethstr=(gchar *)ep_alloc(512);
435     ethptr = bytes_to_hexstr_punct(ethstr, ad, 8, ':'); /* 23 bytes */
436
437     fmt = (ad[0] & 0xF0) >> 4;
438
439     switch (fmt) {
440
441     case FC_NH_NAA_IEEE:
442     case FC_NH_NAA_IEEE_E:
443         memcpy (oui, &ad[2], 6);
444
445         g_snprintf (ethptr, 512-23, " (%s)", get_manuf_name (oui));
446         break;
447
448     case FC_NH_NAA_IEEE_R:
449         oui[0] = ((ad[0] & 0x0F) << 4) | ((ad[1] & 0xF0) >> 4);
450         oui[1] = ((ad[1] & 0x0F) << 4) | ((ad[2] & 0xF0) >> 4);
451         oui[2] = ((ad[2] & 0x0F) << 4) | ((ad[3] & 0xF0) >> 4);
452         oui[3] = ((ad[3] & 0x0F) << 4) | ((ad[4] & 0xF0) >> 4);
453         oui[4] = ((ad[4] & 0x0F) << 4) | ((ad[5] & 0xF0) >> 4);
454         oui[5] = ((ad[5] & 0x0F) << 4) | ((ad[6] & 0xF0) >> 4);
455
456         g_snprintf (ethptr, 512-23, " (%s)", get_manuf_name (oui));
457         break;
458
459     default:
460         *ethptr = '\0';
461         break;
462     }
463     return (ethstr);
464 }
465
466 gchar *
467 tvb_fcwwn_to_str(tvbuff_t *tvb, const gint offset)
468 {
469     return fcwwn_to_str (tvb_get_ptr(tvb, offset, 8));
470 }
471
472 /* XXX FIXME
473 remove this one later when every call has been converted to address_to_str()
474 */
475 const gchar *
476 ax25_to_str(const guint8 *ad)
477 {
478     return bytestring_to_ep_str(ad, 7, ':');
479 }
480
481 /* XXX FIXME
482 remove this one later when every call has been converted to address_to_str()
483 */
484 gchar *
485 get_ax25_name(const guint8 *ad)
486 {
487     address addr;
488
489     addr.type = AT_AX25;
490     addr.len  = 7;
491     addr.data = ad;
492
493     return ep_address_to_str( &addr );
494 }
495
496 /*XXX FIXME the code below may be called very very frequently in the future.
497   optimize it for speed and get rid of the slow sprintfs */
498 /* XXX - perhaps we should have individual address types register
499    a table of routines to do operations such as address-to-name translation,
500    address-to-string translation, and the like, and have this call them,
501    and also have an address-to-string-with-a-name routine */
502 /* XXX - use this, and that future address-to-string-with-a-name routine,
503    in "col_set_addr()"; it might also be useful to have address types
504    export the names of the source and destination address fields, so
505    that "col_set_addr()" need know nothing whatsoever about particular
506    address types */
507 /* convert an address struct into a printable string */
508
509 gchar*
510 address_to_str(wmem_allocator_t *scope, const address *addr)
511 {
512     gchar *str;
513
514     str=(gchar *)wmem_alloc(scope, MAX_ADDR_STR_LEN);
515     address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
516     return str;
517 }
518
519 gchar*
520 ep_address_to_str(const address *addr)
521 {
522     gchar *str;
523
524     str=(gchar *)ep_alloc(MAX_ADDR_STR_LEN);
525     address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
526     return str;
527 }
528
529 /* The called routines use se_alloc'ed memory */
530 gchar*
531 se_address_to_str(const address *addr)
532 {
533     gchar *str;
534
535     str=(gchar *)se_alloc(MAX_ADDR_STR_LEN);
536     address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
537     return str;
538 }
539
540 void
541 address_to_str_buf(const address *addr, gchar *buf, int buf_len)
542 {
543     const guint8 *addrdata;
544     struct atalk_ddp_addr ddp_addr;
545     guint16 ieee_802_15_4_short_addr;
546
547     char temp[32];
548     char *tempptr = temp;
549
550     if (!buf || !buf_len)
551         return;
552
553     switch(addr->type){
554     case AT_NONE:
555         buf[0] = '\0';
556         break;
557     case AT_ETHER: /* 18 bytes */
558         tempptr = bytes_to_hexstr_punct(tempptr, (const guint8 *)addr->data, 6, ':'); /* 17 bytes */
559         break;
560     case AT_IPv4:
561         ip_to_str_buf((const guint8 *)addr->data, buf, buf_len);
562         break;
563     case AT_IPv6:
564         ip6_to_str_buf_len((const guchar *)addr->data, buf, buf_len);
565         break;
566     case AT_IPX: /* 22 bytes */
567         addrdata = (const guint8 *)addr->data;
568         tempptr = bytes_to_hexstr(tempptr, &addrdata[0], 4); /* 8 bytes */
569         *tempptr++ = '.'; /*1 byte */
570         tempptr = bytes_to_hexstr(tempptr, &addrdata[4], 6); /* 12 bytes */
571         break;
572     case AT_SNA:
573         sna_fid_to_str_buf(addr, buf, buf_len);
574         break;
575     case AT_ATALK:
576         memcpy(&ddp_addr, addr->data, sizeof ddp_addr);
577         atalk_addr_to_str_buf(&ddp_addr, buf, buf_len);
578         break;
579     case AT_VINES:
580         vines_addr_to_str_buf((const guint8 *)addr->data, buf, buf_len);
581         break;
582     case AT_USB:
583         usb_addr_to_str_buf((const guint8 *)addr->data, buf, buf_len);
584         break;
585     case AT_OSI:
586         print_nsap_net_buf((const guint8 *)addr->data, addr->len, buf, buf_len);
587         break;
588     case AT_ARCNET: /* 5 bytes */
589         tempptr = g_stpcpy(tempptr, "0x"); /* 2 bytes */
590         tempptr = bytes_to_hexstr(tempptr, (const guint8 *)addr->data, 1); /* 2 bytes */
591         break;
592     case AT_FC: /* 9 bytes */
593         tempptr = bytes_to_hexstr_punct(tempptr, (const guint8 *)addr->data, 3, '.'); /* 8 bytes */
594         break;
595     case AT_SS7PC:
596         mtp3_addr_to_str_buf((const mtp3_addr_pc_t *)addr->data, buf, buf_len);
597         break;
598     case AT_STRINGZ:
599         g_strlcpy(buf, (const gchar *)addr->data, buf_len);
600         break;
601         case AT_EUI64: /* 24 bytes */
602         tempptr = bytes_to_hexstr_punct(tempptr, (const guint8 *)addr->data, 8, ':'); /* 23 bytes */
603         break;
604     case AT_URI: {
605         int copy_len = addr->len < (buf_len - 1) ? addr->len : (buf_len - 1);
606         memcpy(buf, addr->data, copy_len );
607         buf[copy_len] = '\0';
608         }
609         break;
610     case AT_TIPC:
611         tipc_addr_to_str_buf((const guint8 *)addr->data, buf, buf_len);
612         break;
613     case AT_IB:
614         ib_addr_to_str_buf(addr, buf, buf_len);
615         break;
616     case AT_AX25:
617         addrdata = (const guint8 *)addr->data;
618         g_snprintf(buf, buf_len, "%c%c%c%c%c%c-%02d",
619                 (addrdata[0] >> 1) & 0x7f, (addrdata[1] >> 1) & 0x7f, (addrdata[2] >> 1) & 0x7f,
620                 (addrdata[3] >> 1) & 0x7f, (addrdata[4] >> 1) & 0x7f, (addrdata[5] >> 1) & 0x7f,
621                 (addrdata[6] >> 1) & 0x0f );
622         break;
623     case AT_IEEE_802_15_4_SHORT:
624         ieee_802_15_4_short_addr = pletoh16(addr->data);
625         if (ieee_802_15_4_short_addr == 0xffff)
626             g_snprintf(buf, buf_len, "Broadcast");
627         else
628             g_snprintf(buf, buf_len, "0x%04x", ieee_802_15_4_short_addr);
629         break;
630     case AT_J1939:
631         addrdata = (const guint8 *)addr->data;
632         g_snprintf(buf, buf_len, "%d", addrdata[0]);
633         break;
634     case AT_DEVICENET:
635         addrdata = (const guint8 *)addr->data;
636         g_snprintf(buf, buf_len, "%d", addrdata[0] & 0x3f);
637         break;
638     default:
639         g_assert_not_reached();
640     }
641
642     /* copy to output buffer */
643     if (tempptr != temp) {
644         size_t temp_len = (size_t) (tempptr - temp);
645
646         if (temp_len < (size_t) buf_len) {
647             memcpy(buf, temp, temp_len);
648             buf[temp_len] = '\0';
649         } else
650             g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len);/* Let the unexpected value alert user */
651     }
652 }
653
654 /*
655  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
656  *
657  * Local variables:
658  * c-basic-offset: 4
659  * tab-width: 8
660  * indent-tabs-mode: nil
661  * End:
662  *
663  * vi: set shiftwidth=4 tabstop=8 expandtab:
664  * :indentSize=4:tabSize=8:noTabs=true:
665  */