Froim Rene Pilz:
[obnox/wireshark/wip.git] / epan / column.c
1 /* column.c
2  * Routines for handling column preferences
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <errno.h>
33
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #include <epan/timestamp.h>
39 #include <epan/prefs.h>
40 #include <epan/column.h>
41 #include <epan/packet.h>
42
43 /* Given a format number (as defined in packet.h), returns its equivalent
44    string */
45 const gchar *
46 col_format_to_string(gint fmt) {
47   const gchar *slist[] = {
48         "%m", 
49         "%t",
50         "%Rt",
51         "%At",
52         "%Yt",
53         "%Tt",
54         "%s",
55         "%rs",
56         "%us",
57         "%hs",
58         "%rhs",
59         "%uhs",
60         "%ns",
61         "%rns",
62         "%uns",
63         "%d",
64         "%rd",
65         "%ud",
66         "%hd",
67         "%rhd",
68     "%uhd",
69     "%nd", 
70     "%rnd",
71         "%und", 
72     "%S", 
73     "%rS", 
74     "%uS", 
75     "%D", 
76     "%rD", 
77     "%uD", 
78     "%p",
79         "%i", 
80     "%L", 
81     "%B", 
82     "%XO", 
83     "%XR", 
84     "%I", 
85     "%c", 
86     "%Xs", 
87         "%Xd", 
88     "%V", 
89     "%x", 
90     "%e", 
91     "%H", 
92     "%P", 
93     "%y", 
94     "%z", 
95     "%v", 
96     "%E",
97         "%C",
98         "%l"
99 };
100                      
101   if (fmt < 0 || fmt >= NUM_COL_FMTS)
102     return NULL;
103
104   return(slist[fmt]);
105 }
106
107 /* Given a format number (as defined in packet.h), returns its
108   description */
109 static const gchar *dlist[NUM_COL_FMTS] = {
110         "Number",                                   /* COL_NUMBER */
111         "Time (format as specified)",               /* COL_CLS_TIME */
112         "Relative time",                            /* COL_REL_TIME */
113         "Absolute time",                            /* COL_ABS_TIME */
114         "Absolute date and time",                   /* COL_ABS_DATE_TIME */
115         "Delta time",                               /* COL_DELTA_TIME */
116         "Source address",                           /* COL_DEF_SRC */
117         "Src addr (resolved)",                      /* COL_RES_SRC */
118         "Src addr (unresolved)",                    /* COL_UNRES_SRC */
119         "Hardware src addr",                        /* COL_DEF_DL_SRC */
120         "Hw src addr (resolved)",                   /* COL_RES_DL_SRC*/
121         "Hw src addr (unresolved)",                 /* COL_UNRES_DL_SRC */
122         "Network src addr",                         /* COL_DEF_NET_SRC */
123         "Net src addr (resolved)",                  /* COL_RES_NET_SRC */
124         "Net src addr (unresolved)",                /* COL_UNRES_NET_SRC */
125         "Destination address",                      /* COL_DEF_DST */
126         "Dest addr (resolved)",                     /* COL_RES_DST */
127         "Dest addr (unresolved)",                   /* COL_UNRES_DST */
128         "Hardware dest addr",                       /* COL_DEF_DL_DST */
129         "Hw dest addr (resolved)",                  /* COL_RES_DL_DST */
130         "Hw dest addr (unresolved)",                /* COL_UNRES_DL_DST */
131         "Network dest addr",                        /* COL_DEF_NET_DST */
132         "Net dest addr (resolved)",                 /* COL_RES_NET_DST */
133         "Net dest addr (unresolved)",               /* COL_UNRES_NET_DST */
134         "Source port",                              /* COL_DEF_SRC_PORT */
135         "Src port (resolved)",                      /* COL_RES_SRC_PORT */
136         "Src port (unresolved)",                    /* COL_UNRES_SRC_PORT */
137         "Destination port",                         /* COL_DEF_DST_PORT */
138         "Dest port (resolved)",                     /* COL_RES_DST_PORT */
139         "Dest port (unresolved)",                   /* COL_UNRES_DST_PORT */
140         "Protocol",                                 /* COL_PROTOCOL */
141         "Information",                              /* COL_INFO */
142         "Packet length (bytes)" ,                   /* COL_PACKET_LENGTH */
143         "Cumulative Bytes" ,                        /* COL_CUMULATIVE_BYTES */
144         "Fibre Channel OXID",                       /* COL_OXID */
145         "Fibre Channel RXID",                       /* COL_RXID */
146         "FW-1 monitor if/direction",                /* COL_IF_DIR */
147         "Circuit ID",                               /* COL_CIRCUIT_ID */
148         "Cisco Src PortIdx",                        /* COL_SRCIDX */
149         "Cisco Dst PortIdx",                        /* COL_DSTIDX */
150         "Cisco VSAN",                               /* COL_VSAN */
151         "IEEE 802.11 TX rate",                      /* COL_TX_RATE */
152         "IEEE 802.11 RSSI",                         /* COL_RSSI */
153         "HP-UX Subsystem",                          /* COL_HPUX_SUBSYS */
154         "HP-UX Device ID",                          /* COL_HPUX_DEVID */
155         "DCE/RPC call (cn_call_id / dg_seqnum)",    /* COL_DCE_CALL */
156         "DCE/RPC context ID (cn_ctx_id)",           /* COL_DCE_CTX */
157         "802.1Q VLAN id",                           /* COL_8021Q_VLAN_ID */
158         "TEI",                                      /* XXX - why is it missing in column_utils.c and elsewhere? */
159         "Frame Relay DLCI",                                                     /* COL_FR_DLCI */
160         "GPRS BSSGP TLLI",                                                      /* COL_BSSGP_TLLI */
161 };
162
163 const gchar *
164 col_format_desc(gint fmt) {
165   g_assert((fmt >= 0) && (fmt < NUM_COL_FMTS));
166   return(dlist[fmt]);
167 }
168
169 /* Marks each array element true if it can be substituted for the given
170    column format */
171 void
172 get_column_format_matches(gboolean *fmt_list, gint format) {
173
174   /* Get the obvious: the format itself */
175   if ((format >= 0) && (format < NUM_COL_FMTS))
176     fmt_list[format] = TRUE;
177
178   /* Get any formats lower down on the chain */
179   switch (format) {
180     case COL_DEF_SRC:
181       fmt_list[COL_RES_DL_SRC] = TRUE;
182       fmt_list[COL_RES_NET_SRC] = TRUE;
183       break;
184     case COL_RES_SRC:
185       fmt_list[COL_RES_DL_SRC] = TRUE;
186       fmt_list[COL_RES_NET_SRC] = TRUE;
187       break;
188     case COL_UNRES_SRC:
189       fmt_list[COL_UNRES_DL_SRC] = TRUE;
190       fmt_list[COL_UNRES_NET_SRC] = TRUE;
191       break;
192     case COL_DEF_DST:
193       fmt_list[COL_RES_DL_DST] = TRUE;
194       fmt_list[COL_RES_NET_DST] = TRUE;
195       break;
196     case COL_RES_DST:
197       fmt_list[COL_RES_DL_DST] = TRUE;
198       fmt_list[COL_RES_NET_DST] = TRUE;
199       break;
200     case COL_UNRES_DST:
201       fmt_list[COL_UNRES_DL_DST] = TRUE;
202       fmt_list[COL_UNRES_NET_DST] = TRUE;
203       break;
204     case COL_DEF_DL_SRC:
205       fmt_list[COL_RES_DL_SRC] = TRUE;
206       break;
207     case COL_DEF_DL_DST:
208       fmt_list[COL_RES_DL_DST] = TRUE;
209       break;
210     case COL_DEF_NET_SRC:
211       fmt_list[COL_RES_NET_SRC] = TRUE;
212       break;
213     case COL_DEF_NET_DST:
214       fmt_list[COL_RES_NET_DST] = TRUE;
215       break;
216     case COL_DEF_SRC_PORT:
217       fmt_list[COL_RES_SRC_PORT] = TRUE;
218       break;
219     case COL_DEF_DST_PORT:
220       fmt_list[COL_RES_DST_PORT] = TRUE;
221       break;
222     case COL_OXID:
223       fmt_list[COL_OXID] = TRUE;
224       break;
225     case COL_RXID:
226       fmt_list[COL_RXID] = TRUE;
227       break;
228     case COL_IF_DIR:
229       fmt_list[COL_IF_DIR] = TRUE;
230       break;
231     case COL_CIRCUIT_ID:
232       fmt_list[COL_CIRCUIT_ID] = TRUE;
233       break;
234     case COL_SRCIDX:
235       fmt_list[COL_SRCIDX] = TRUE;
236       break;
237     case COL_DSTIDX:
238       fmt_list[COL_DSTIDX] = TRUE;
239       break;
240     case COL_VSAN:
241       fmt_list[COL_VSAN] = TRUE;
242       break;
243     case COL_TX_RATE:
244       fmt_list[COL_TX_RATE] = TRUE;
245       break;
246     case COL_RSSI:
247       fmt_list[COL_RSSI] = TRUE;
248       break;
249     case COL_HPUX_SUBSYS:
250       fmt_list[COL_HPUX_SUBSYS] = TRUE;
251       break;
252     case COL_HPUX_DEVID:
253       fmt_list[COL_HPUX_DEVID] = TRUE;
254       break;
255     case COL_DCE_CALL:
256       fmt_list[COL_DCE_CALL] = TRUE;
257       break;
258     case COL_DCE_CTX:
259       fmt_list[COL_DCE_CTX] = TRUE;
260       break;
261     case COL_8021Q_VLAN_ID:
262       fmt_list[COL_8021Q_VLAN_ID] = TRUE;
263       break;
264     case COL_TEI:
265       fmt_list[COL_TEI] = TRUE;
266       break;
267     case COL_FR_DLCI:
268       fmt_list[COL_FR_DLCI] = TRUE;
269       break;
270     case COL_BSSGP_TLLI:
271       fmt_list[COL_BSSGP_TLLI] = TRUE;
272       break;
273     default:
274       break;
275   }
276 }
277
278 /* Returns a string representing the longest possible value for 
279    a timestamp column type. */
280 static const char *
281 get_timestamp_column_longest_string(gint type, gint precision)
282 {
283
284         switch(type) {
285         case(TS_ABSOLUTE_WITH_DATE):
286                 switch(precision) {
287                         case(TS_PREC_AUTO_SEC):
288                         case(TS_PREC_FIXED_SEC):
289                                 return "0000-00-00 00:00:00";
290                                 break;
291                         case(TS_PREC_AUTO_DSEC):
292                         case(TS_PREC_FIXED_DSEC):
293                                 return "0000-00-00 00:00:00.0";
294                                 break;
295                         case(TS_PREC_AUTO_CSEC):
296                         case(TS_PREC_FIXED_CSEC):
297                                 return "0000-00-00 00:00:00.00";
298                                 break;
299                         case(TS_PREC_AUTO_MSEC):
300                         case(TS_PREC_FIXED_MSEC):
301                                 return "0000-00-00 00:00:00.000";
302                                 break;
303                         case(TS_PREC_AUTO_USEC):
304                         case(TS_PREC_FIXED_USEC):
305                                 return "0000-00-00 00:00:00.000000";
306                                 break;
307                         case(TS_PREC_AUTO_NSEC):
308                         case(TS_PREC_FIXED_NSEC):
309                                 return "0000-00-00 00:00:00.000000000";
310                                 break;
311                         default:
312                                 g_assert_not_reached();
313                 }
314                         break;
315         case(TS_ABSOLUTE):
316                 switch(precision) {
317                         case(TS_PREC_AUTO_SEC):
318                         case(TS_PREC_FIXED_SEC):
319                                 return "00:00:00";
320                                 break;
321                         case(TS_PREC_AUTO_DSEC):
322                         case(TS_PREC_FIXED_DSEC):
323                                 return "00:00:00.0";
324                                 break;
325                         case(TS_PREC_AUTO_CSEC):
326                         case(TS_PREC_FIXED_CSEC):
327                                 return "00:00:00.00";
328                                 break;
329                         case(TS_PREC_AUTO_MSEC):
330                         case(TS_PREC_FIXED_MSEC):
331                                 return "00:00:00.000";
332                                 break;
333                         case(TS_PREC_AUTO_USEC):
334                         case(TS_PREC_FIXED_USEC):
335                                 return "00:00:00.000000";
336                                 break;
337                         case(TS_PREC_AUTO_NSEC):
338                         case(TS_PREC_FIXED_NSEC):
339                                 return "00:00:00.000000000";
340                                 break;
341                         default:
342                                 g_assert_not_reached();
343                 }
344                 break;
345         case(TS_RELATIVE):      /* fallthrough */
346         case(TS_DELTA):
347                 switch(precision) {
348                         case(TS_PREC_AUTO_SEC):
349                         case(TS_PREC_FIXED_SEC):
350                                 return "0000";
351                                 break;
352                         case(TS_PREC_AUTO_DSEC):
353                         case(TS_PREC_FIXED_DSEC):
354                                 return "0000.0";
355                                 break;
356                         case(TS_PREC_AUTO_CSEC):
357                         case(TS_PREC_FIXED_CSEC):
358                                 return "0000.00";
359                                 break;
360                         case(TS_PREC_AUTO_MSEC):
361                         case(TS_PREC_FIXED_MSEC):
362                                 return "0000.000";
363                                 break;
364                         case(TS_PREC_AUTO_USEC):
365                         case(TS_PREC_FIXED_USEC):
366                                 return "0000.000000";
367                                 break;
368                         case(TS_PREC_AUTO_NSEC):
369                         case(TS_PREC_FIXED_NSEC):
370                                 return "0000.000000000";
371                                 break;
372                         default:
373                                 g_assert_not_reached();
374                 }
375                 break;
376         case(TS_NOT_SET):
377                 return "0000.000000";
378                 break;
379         default:
380                 g_assert_not_reached();
381         }
382
383         /* never reached, satisfy compiler */
384         return "";
385 }
386
387 /* Returns a string representing the longest possible value for a
388    particular column type.
389
390    Except for the COL...SRC and COL...DST columns, these are used
391    only when a capture is being displayed while it's taking place;
392    they are arguably somewhat fragile, as changes to the code that
393    generates them don't cause these widths to change, but that's
394    probably not too big a problem, given that the sizes are
395    recomputed based on the actual data in the columns when the capture
396    is done, and given that the width for COL...SRC and COL...DST columns
397    is somewhat arbitrary in any case.  We should probably clean
398    that up eventually, though. */
399 const char *
400 get_column_longest_string(gint format)
401 {
402   switch (format) {
403     case COL_NUMBER:
404       return "0000000";
405       break;
406     case COL_CLS_TIME:
407       return get_timestamp_column_longest_string(timestamp_get_type(), timestamp_get_precision());
408       break;
409     case COL_ABS_DATE_TIME:
410       return get_timestamp_column_longest_string(TS_ABSOLUTE_WITH_DATE, timestamp_get_precision());
411       break;
412     case COL_ABS_TIME:
413       return get_timestamp_column_longest_string(TS_ABSOLUTE, timestamp_get_precision());
414       break;
415     case COL_REL_TIME:
416       return get_timestamp_column_longest_string(TS_RELATIVE, timestamp_get_precision());
417       break;
418     case COL_DELTA_TIME:
419       return get_timestamp_column_longest_string(TS_DELTA, timestamp_get_precision());
420       break;
421     case COL_DEF_SRC:
422     case COL_RES_SRC:
423     case COL_UNRES_SRC:
424     case COL_DEF_DL_SRC:
425     case COL_RES_DL_SRC:
426     case COL_UNRES_DL_SRC:
427     case COL_DEF_NET_SRC:
428     case COL_RES_NET_SRC:
429     case COL_UNRES_NET_SRC:
430     case COL_DEF_DST:
431     case COL_RES_DST:
432     case COL_UNRES_DST:
433     case COL_DEF_DL_DST:
434     case COL_RES_DL_DST:
435     case COL_UNRES_DL_DST:
436     case COL_DEF_NET_DST:
437     case COL_RES_NET_DST:
438     case COL_UNRES_NET_DST:
439       return "00000000.000000000000"; /* IPX-style */
440       break;
441     case COL_DEF_SRC_PORT:
442     case COL_RES_SRC_PORT:
443     case COL_UNRES_SRC_PORT:
444     case COL_DEF_DST_PORT:
445     case COL_RES_DST_PORT:
446     case COL_UNRES_DST_PORT:
447       return "000000";
448       break;
449     case COL_PROTOCOL:
450       return "Protocol";        /* not the longest, but the longest is too long */
451       break;
452     case COL_PACKET_LENGTH:
453       return "00000";
454       break;
455     case COL_CUMULATIVE_BYTES:
456       return "00000000";
457       break;
458     case COL_RXID:
459     case COL_OXID:
460       return "000000";
461       break;
462     case COL_IF_DIR:
463       return "i 00000000 I";
464       break;
465     case COL_CIRCUIT_ID:
466       return "000000";
467       break;
468     case COL_SRCIDX:
469     case COL_DSTIDX:
470       return "0000000";
471       break;
472     case COL_VSAN:
473      return "000000";
474       break;
475     case COL_TX_RATE:
476       return "108.0";
477       break;
478     case COL_RSSI:
479       return "100";
480       break;
481     case COL_HPUX_SUBSYS:
482       return "OTS9000-TRANSPORT";
483       break;
484     case COL_HPUX_DEVID:
485       return "0000";
486       break;
487     case COL_DCE_CALL:
488       return "0000";
489       break;
490     case COL_DCE_CTX:
491       return "0000";
492       break;
493     case COL_8021Q_VLAN_ID:
494       return "0000";
495       break;
496     case COL_TEI:
497       return "127";
498       break;
499     case COL_FR_DLCI:
500       return "8388608";
501       break;
502     case COL_BSSGP_TLLI:
503       return "0xffffffff";
504       break;
505     default: /* COL_INFO */
506       return "Source port: kerberos-master  Destination port: kerberos-master";
507       break;
508   }
509 }
510
511 /* Returns the longest possible width, in characters, for a particular
512    column type. */
513 gint
514 get_column_char_width(gint format)
515 {
516   return strlen(get_column_longest_string(format));
517 }
518
519 #define TIME_DEF      0
520 #define TIME_REL      1
521 #define TIME_ABS      2
522 #define DATE_TIME_ABS 3
523 #define TIME_DEL      4
524
525 #define RES_DEF  0
526 #define RES_DO   1
527 #define RES_DONT 2
528
529 #define ADDR_DEF 0
530 #define ADDR_DL  3
531 #define ADDR_NET 6
532
533 gint
534 get_column_format(gint col) {
535   GList    *clp = g_list_nth(prefs.col_list, col);
536   fmt_data *cfmt;
537
538   cfmt = (fmt_data *) clp->data;
539
540   return(get_column_format_from_str(cfmt->fmt));
541 }
542
543 gint
544 get_column_format_from_str(gchar *str) {
545   gchar *cptr = str;
546   gint      res_off = RES_DEF, addr_off = ADDR_DEF, time_off = TIME_DEF;
547   gint      prev_code = -1;
548
549   /* To do: Make this parse %-formatted strings "for real" */
550   while (*cptr != '\0') {
551     switch (*cptr) {
552       case 't':  /* To do: fix for absolute and delta */
553         return COL_CLS_TIME + time_off;
554         break;
555       case 'm':
556         return COL_NUMBER;
557         break;
558       case 's':
559         if (prev_code == COL_OXID) {
560           return COL_SRCIDX;
561         }
562         else {
563           return COL_DEF_SRC + res_off + addr_off;
564         }
565         break;
566       case 'd':
567         if (prev_code == COL_OXID) {
568           return COL_DSTIDX;
569         }
570         else {
571           return COL_DEF_DST + res_off + addr_off;
572         }
573         break;
574       case 'S':
575         return COL_DEF_SRC_PORT + res_off;
576         break;
577       case 'D':
578         return COL_DEF_DST_PORT + res_off;
579         break;
580       case 'p':
581         return COL_PROTOCOL;
582         break;
583       case 'i':
584         return COL_INFO;
585         break;
586       case 'r':
587         res_off = RES_DO;
588         break;
589       case 'u':
590         res_off = RES_DONT;
591         break;
592       case 'h':
593         addr_off = ADDR_DL;
594         break;
595       case 'n':
596         addr_off = ADDR_NET;
597         break;
598       case 'R':
599         if (prev_code == COL_OXID) {
600             return COL_RXID;
601         }
602         else {
603             time_off = TIME_REL;
604         }
605         break;
606       case 'A':
607         time_off = TIME_ABS;
608         break;
609       case 'Y':
610         time_off = DATE_TIME_ABS;
611         break;
612       case 'T':
613         time_off = TIME_DEL;
614         break;
615       case 'L':
616         return COL_PACKET_LENGTH;
617         break;
618       case 'B':
619         return COL_CUMULATIVE_BYTES;
620         break;
621       case 'X':
622         prev_code = COL_OXID;
623         break;
624       case 'O':
625         return COL_OXID;
626         break;
627       case 'I':
628         return COL_IF_DIR;
629         break;
630       case 'c':
631         return COL_CIRCUIT_ID;
632         break;
633       case 'V':
634         return COL_VSAN;
635         break;
636       case 'x':
637         return COL_TX_RATE;
638         break;
639       case 'e':
640         return COL_RSSI;
641         break;
642       case 'H':
643         return COL_HPUX_SUBSYS;
644         break;
645       case 'P':
646         return COL_HPUX_DEVID;
647         break;
648       case 'y':
649         return COL_DCE_CALL;
650         break;
651       case 'z':
652         return COL_DCE_CTX;
653         break;
654       case 'v':
655         return COL_8021Q_VLAN_ID;
656         break;
657       case 'E':
658         return COL_TEI;
659       case 'C':
660         return COL_FR_DLCI;
661       case 'l':
662         return COL_BSSGP_TLLI;
663         break;
664     }
665     cptr++;
666   }
667   return -1;    /* illegal */
668 }
669
670 gchar *
671 get_column_title(gint col) {
672   GList    *clp = g_list_nth(prefs.col_list, col);
673   fmt_data *cfmt;
674
675   cfmt = (fmt_data *) clp->data;
676
677   return(cfmt->title);
678 }