If we don't get any OS information, remove the old OS information.
[metze/wireshark/wip.git] / wiretap / iptrace.c
1 /* iptrace.c
2  *
3  * Wiretap Library
4  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  */
21 #include "config.h"
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <string.h>
25 #include "wtap-int.h"
26 #include "file_wrappers.h"
27 #include "atm.h"
28 #include "iptrace.h"
29
30 #define IPTRACE_IFT_HF  0x3d    /* Support for PERCS IP-HFI*/
31 #define IPTRACE_IFT_IB  0xc7    /* IP over Infiniband. Number by IANA */
32
33 static gboolean iptrace_read_1_0(wtap *wth, int *err, gchar **err_info,
34     gint64 *data_offset);
35 static gboolean iptrace_seek_read_1_0(wtap *wth, gint64 seek_off,
36     struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
37
38 static gboolean iptrace_read_2_0(wtap *wth, int *err, gchar **err_info,
39     gint64 *data_offset);
40 static gboolean iptrace_seek_read_2_0(wtap *wth, gint64 seek_off,
41     struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
42
43 static gboolean iptrace_read_rec_data(FILE_T fh, Buffer *buf,
44     struct wtap_pkthdr *phdr, int *err, gchar **err_info);
45 static void fill_in_pseudo_header(int encap,
46     union wtap_pseudo_header *pseudo_header, guint8 *header);
47 static int wtap_encap_ift(unsigned int  ift);
48
49 #define NAME_SIZE 11
50
51 wtap_open_return_val iptrace_open(wtap *wth, int *err, gchar **err_info)
52 {
53         char name[NAME_SIZE+1];
54
55         if (!wtap_read_bytes(wth->fh, name, NAME_SIZE, err, err_info)) {
56                 if (*err != WTAP_ERR_SHORT_READ)
57                         return WTAP_OPEN_ERROR;
58                 return WTAP_OPEN_NOT_MINE;
59         }
60         name[NAME_SIZE] = '\0';
61
62         if (strcmp(name, "iptrace 1.0") == 0) {
63                 wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_IPTRACE_1_0;
64                 wth->subtype_read = iptrace_read_1_0;
65                 wth->subtype_seek_read = iptrace_seek_read_1_0;
66                 wth->file_tsprec = WTAP_TSPREC_SEC;
67         }
68         else if (strcmp(name, "iptrace 2.0") == 0) {
69                 wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_IPTRACE_2_0;
70                 wth->subtype_read = iptrace_read_2_0;
71                 wth->subtype_seek_read = iptrace_seek_read_2_0;
72                 wth->file_tsprec = WTAP_TSPREC_NSEC;
73         }
74         else {
75                 return WTAP_OPEN_NOT_MINE;
76         }
77
78         return WTAP_OPEN_MINE;
79 }
80
81 /***********************************************************
82  * iptrace 1.0                                             *
83  ***********************************************************/
84
85 /*
86  * iptrace 1.0, discovered through inspection
87  *
88  * Packet record contains:
89  *
90  *      an initial header, with a length field and a time stamp, in
91  *      seconds since the Epoch;
92  *
93  *      data, with the specified length.
94  *
95  * The data contains:
96  *
97  *      a bunch of information about the packet;
98  *
99  *      padding, at least for FDDI;
100  *
101  *      the raw packet data.
102  */
103 typedef struct {
104 /* 0-3 */       guint32         pkt_length;     /* packet length + 0x16 */
105 /* 4-7 */       guint32         tv_sec;         /* time stamp, seconds since the Epoch */
106 /* 8-11 */      guint32         junk1;          /* ???, not time */
107 /* 12-15 */     char            if_name[4];     /* null-terminated */
108 /* 16-27 */     char            junk2[12];      /* ??? */
109 /* 28 */        guint8          if_type;        /* BSD net/if_types.h */
110 /* 29 */        guint8          tx_flag;        /* 0=receive, 1=transmit */
111 } iptrace_1_0_phdr;
112
113 #define IPTRACE_1_0_PHDR_SIZE   30      /* initial header plus packet data */
114 #define IPTRACE_1_0_PDATA_SIZE  22      /* packet data */
115
116 static gboolean
117 iptrace_read_rec_1_0(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
118     int *err, gchar **err_info)
119 {
120         guint8                  header[IPTRACE_1_0_PHDR_SIZE];
121         iptrace_1_0_phdr        pkt_hdr;
122         guint32                 packet_size;
123
124         if (!wtap_read_bytes_or_eof(fh, header, sizeof header, err, err_info)) {
125                 /* Read error or EOF */
126                 return FALSE;
127         }
128
129         /*
130          * Byte 28 of the frame header appears to be a BSD-style IFT_xxx
131          * value giving the type of the interface.  Check out the
132          * <net/if_types.h> header file.
133          */
134         pkt_hdr.if_type = header[28];
135         phdr->pkt_encap = wtap_encap_ift(pkt_hdr.if_type);
136         if (phdr->pkt_encap == WTAP_ENCAP_UNKNOWN) {
137                 *err = WTAP_ERR_UNSUPPORTED;
138                 *err_info = g_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
139                     pkt_hdr.if_type);
140                 return FALSE;
141         }
142
143         /* Read the packet metadata */
144         packet_size = pntoh32(&header[0]);
145         if (packet_size < IPTRACE_1_0_PDATA_SIZE) {
146                 /*
147                  * Uh-oh, the record isn't big enough to even have a
148                  * packet meta-data header.
149                  */
150                 *err = WTAP_ERR_BAD_FILE;
151                 *err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
152                     packet_size);
153                 return FALSE;
154         }
155         packet_size -= IPTRACE_1_0_PDATA_SIZE;
156
157         /*
158          * AIX appears to put 3 bytes of padding in front of FDDI
159          * frames; strip that crap off.
160          */
161         if (phdr->pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
162                 /*
163                  * The packet size is really a record size and includes
164                  * the padding.
165                  */
166                 if (packet_size < 3) {
167                         /*
168                          * Uh-oh, the record isn't big enough to even have
169                          * the padding.
170                          */
171                         *err = WTAP_ERR_BAD_FILE;
172                         *err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
173                             packet_size + IPTRACE_1_0_PDATA_SIZE);
174                         return FALSE;
175                 }
176                 packet_size -= 3;
177
178                 /*
179                  * Skip the padding.
180                  */
181                 if (!file_skip(fh, 3, err))
182                         return FALSE;
183         }
184         if (packet_size > WTAP_MAX_PACKET_SIZE) {
185                 /*
186                  * Probably a corrupt capture file; don't blow up trying
187                  * to allocate space for an immensely-large packet.
188                  */
189                 *err = WTAP_ERR_BAD_FILE;
190                 *err_info = g_strdup_printf("iptrace: File has %u-byte packet, bigger than maximum of %u",
191                     packet_size, WTAP_MAX_PACKET_SIZE);
192                 return FALSE;
193         }
194
195         phdr->rec_type = REC_TYPE_PACKET;
196         phdr->presence_flags = WTAP_HAS_TS;
197         phdr->len = packet_size;
198         phdr->caplen = packet_size;
199         phdr->ts.secs = pntoh32(&header[4]);
200         phdr->ts.nsecs = 0;
201
202         /* Fill in the pseudo-header. */
203         fill_in_pseudo_header(phdr->pkt_encap, &phdr->pseudo_header, header);
204
205         /* Get the packet data */
206         return iptrace_read_rec_data(fh, buf, phdr, err, err_info);
207 }
208
209 /* Read the next packet */
210 static gboolean iptrace_read_1_0(wtap *wth, int *err, gchar **err_info,
211     gint64 *data_offset)
212 {
213         *data_offset = file_tell(wth->fh);
214
215         /* Read the packet */
216         if (!iptrace_read_rec_1_0(wth->fh, &wth->phdr, wth->frame_buffer,
217             err, err_info)) {
218                 /* Read error or EOF */
219                 return FALSE;
220         }
221
222         /* If the per-file encapsulation isn't known, set it to this
223            packet's encapsulation.
224
225            If it *is* known, and it isn't this packet's encapsulation,
226            set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
227            have a single encapsulation for all packets in the file. */
228         if (wth->file_encap == WTAP_ENCAP_UNKNOWN)
229                 wth->file_encap = wth->phdr.pkt_encap;
230         else {
231                 if (wth->file_encap != wth->phdr.pkt_encap)
232                         wth->file_encap = WTAP_ENCAP_PER_PACKET;
233         }
234
235         return TRUE;
236 }
237
238 static gboolean iptrace_seek_read_1_0(wtap *wth, gint64 seek_off,
239     struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
240 {
241         if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
242                 return FALSE;
243
244         /* Read the packet */
245         if (!iptrace_read_rec_1_0(wth->random_fh, phdr, buf, err, err_info)) {
246                 if (*err == 0)
247                         *err = WTAP_ERR_SHORT_READ;
248                 return FALSE;
249         }
250         return TRUE;
251 }
252
253 /***********************************************************
254  * iptrace 2.0                                             *
255  ***********************************************************/
256
257 /*
258  * iptrace 2.0, discovered through inspection
259  *
260  * Packet record contains:
261  *
262  *      an initial header, with a length field and a time stamp, in
263  *      seconds since the Epoch;
264  *
265  *      data, with the specified length.
266  *
267  * The data contains:
268  *
269  *      a bunch of information about the packet;
270  *
271  *      padding, at least for FDDI;
272  *
273  *      the raw packet data.
274  */
275 typedef struct {
276 /* 0-3 */       guint32         pkt_length;     /* packet length + 32 */
277 /* 4-7 */       guint32         tv_sec0;        /* time stamp, seconds since the Epoch */
278 /* 8-11 */      guint32         junk1;          /* ?? */
279 /* 12-15 */     char            if_name[4];     /* null-terminated */
280 /* 16-27 */     char            if_desc[12];    /* interface description. */
281 /* 28 */        guint8          if_type;        /* BSD net/if_types.h */
282 /* 29 */        guint8          tx_flag;        /* 0=receive, 1=transmit */
283 /* 30-31 */     guint16         junk3;
284 /* 32-35 */     guint32         tv_sec;         /* time stamp, seconds since the Epoch */
285 /* 36-39 */     guint32         tv_nsec;        /* nanoseconds since that second */
286 } iptrace_2_0_phdr;
287
288 #define IPTRACE_2_0_PHDR_SIZE   40      /* initial header plus packet data */
289 #define IPTRACE_2_0_PDATA_SIZE  32      /* packet data */
290
291 static gboolean
292 iptrace_read_rec_2_0(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
293     int *err, gchar **err_info)
294 {
295         guint8                  header[IPTRACE_2_0_PHDR_SIZE];
296         iptrace_2_0_phdr        pkt_hdr;
297         guint32                 packet_size;
298
299         if (!wtap_read_bytes_or_eof(fh, header, sizeof header, err, err_info)) {
300                 /* Read error or EOF */
301                 return FALSE;
302         }
303
304         /*
305          * Byte 28 of the frame header appears to be a BSD-style IFT_xxx
306          * value giving the type of the interface.  Check out the
307          * <net/if_types.h> header file.
308          */
309         pkt_hdr.if_type = header[28];
310         phdr->pkt_encap = wtap_encap_ift(pkt_hdr.if_type);
311 #if 0
312         /*
313          * We used to error out if the interface type in iptrace was
314          * unknown/unhandled, but an iptrace may contain packets
315          * from a variety of interfaces, some known, and others
316          * unknown.
317          *
318          * It is better to display the data even for unknown interface
319          * types, isntead of erroring out. In the future, it would be
320          * nice to be able to flag which frames are shown as data
321          * because their interface type is unknown, and also present
322          * the interface type number to the user so that it can be
323          * reported easily back to the Wireshark developer.
324          *
325          * XXX - what types are there that are used in files but
326          * that we don't handle?
327          */
328         if (phdr->pkt_encap == WTAP_ENCAP_UNKNOWN) {
329                 *err = WTAP_ERR_UNSUPPORTED;
330                 *err_info = g_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
331                     pkt_hdr.if_type);
332                 return FALSE;
333         }
334 #endif
335
336         /* Read the packet metadata */
337         packet_size = pntoh32(&header[0]);
338         if (packet_size < IPTRACE_2_0_PDATA_SIZE) {
339                 /*
340                  * Uh-oh, the record isn't big enough to even have a
341                  * packet meta-data header.
342                  */
343                 *err = WTAP_ERR_BAD_FILE;
344                 *err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
345                     packet_size);
346                 return FALSE;
347         }
348         packet_size -= IPTRACE_2_0_PDATA_SIZE;
349
350         /*
351          * AIX appears to put 3 bytes of padding in front of FDDI
352          * frames; strip that crap off.
353          */
354         if (phdr->pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
355                 /*
356                  * The packet size is really a record size and includes
357                  * the padding.
358                  */
359                 if (packet_size < 3) {
360                         /*
361                          * Uh-oh, the record isn't big enough to even have
362                          * the padding.
363                          */
364                         *err = WTAP_ERR_BAD_FILE;
365                         *err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
366                             packet_size + IPTRACE_2_0_PDATA_SIZE);
367                         return FALSE;
368                 }
369                 packet_size -= 3;
370
371                 /*
372                  * Skip the padding.
373                  */
374                 if (!file_skip(fh, 3, err))
375                         return FALSE;
376         }
377         if (packet_size > WTAP_MAX_PACKET_SIZE) {
378                 /*
379                  * Probably a corrupt capture file; don't blow up trying
380                  * to allocate space for an immensely-large packet.
381                  */
382                 *err = WTAP_ERR_BAD_FILE;
383                 *err_info = g_strdup_printf("iptrace: File has %u-byte packet, bigger than maximum of %u",
384                     packet_size, WTAP_MAX_PACKET_SIZE);
385                 return FALSE;
386         }
387
388         phdr->rec_type = REC_TYPE_PACKET;
389         phdr->presence_flags = WTAP_HAS_TS;
390         phdr->len = packet_size;
391         phdr->caplen = packet_size;
392         phdr->ts.secs = pntoh32(&header[32]);
393         phdr->ts.nsecs = pntoh32(&header[36]);
394
395         /* Fill in the pseudo_header. */
396         fill_in_pseudo_header(phdr->pkt_encap, &phdr->pseudo_header, header);
397
398         /* Get the packet data */
399         return iptrace_read_rec_data(fh, buf, phdr, err, err_info);
400 }
401
402 /* Read the next packet */
403 static gboolean iptrace_read_2_0(wtap *wth, int *err, gchar **err_info,
404     gint64 *data_offset)
405 {
406         *data_offset = file_tell(wth->fh);
407
408         /* Read the packet */
409         if (!iptrace_read_rec_2_0(wth->fh, &wth->phdr, wth->frame_buffer,
410             err, err_info)) {
411                 /* Read error or EOF */
412                 return FALSE;
413         }
414
415         /* If the per-file encapsulation isn't known, set it to this
416            packet's encapsulation.
417
418            If it *is* known, and it isn't this packet's encapsulation,
419            set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
420            have a single encapsulation for all packets in the file. */
421         if (wth->file_encap == WTAP_ENCAP_UNKNOWN)
422                 wth->file_encap = wth->phdr.pkt_encap;
423         else {
424                 if (wth->file_encap != wth->phdr.pkt_encap)
425                         wth->file_encap = WTAP_ENCAP_PER_PACKET;
426         }
427
428         return TRUE;
429 }
430
431 static gboolean iptrace_seek_read_2_0(wtap *wth, gint64 seek_off,
432     struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
433 {
434         if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
435                 return FALSE;
436
437         /* Read the packet */
438         if (!iptrace_read_rec_2_0(wth->random_fh, phdr, buf, err, err_info)) {
439                 if (*err == 0)
440                         *err = WTAP_ERR_SHORT_READ;
441                 return FALSE;
442         }
443         return TRUE;
444 }
445
446 static gboolean
447 iptrace_read_rec_data(FILE_T fh, Buffer *buf, struct wtap_pkthdr *phdr,
448     int *err, gchar **err_info)
449 {
450         if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info))
451                 return FALSE;
452
453         if (phdr->pkt_encap == WTAP_ENCAP_ATM_PDUS) {
454                 /*
455                  * Attempt to guess from the packet data, the VPI,
456                  * and the VCI information about the type of traffic.
457                  */
458                 atm_guess_traffic_type(phdr, ws_buffer_start_ptr(buf));
459         }
460
461         return TRUE;
462 }
463
464 /*
465  * Fill in the pseudo-header information we can.
466  *
467  * For ATM traffic, "iptrace", alas, doesn't tell us what type of traffic
468  * is in the packet - it was presumably run on a machine that was one of
469  * the endpoints of the connection, so in theory it could presumably have
470  * told us, but, for whatever reason, it failed to do so - perhaps the
471  * low-level mechanism that feeds the presumably-AAL5 frames to us doesn't
472  * have access to that information (e.g., because it's in the ATM driver,
473  * and the ATM driver merely knows that stuff on VPI/VCI X.Y should be
474  * handed up to some particular client, it doesn't know what that client is).
475  *
476  * We let our caller try to figure out what kind of traffic it is, either
477  * by guessing based on the VPI/VCI, guessing based on the header of the
478  * packet, seeing earlier traffic that set up the circuit and specified
479  * in some fashion what sort of traffic it is, or being told by the user.
480  */
481 static void
482 fill_in_pseudo_header(int encap, union wtap_pseudo_header *pseudo_header,
483     guint8 *header)
484 {
485         char    if_text[9];
486         char    *decimal;
487         int     Vpi = 0;
488         int     Vci = 0;
489
490         switch (encap) {
491
492         case WTAP_ENCAP_ATM_PDUS:
493                 /* Rip apart the "x.y" text into Vpi/Vci numbers */
494                 memcpy(if_text, &header[20], 8);
495                 if_text[8] = '\0';
496                 decimal = strchr(if_text, '.');
497                 if (decimal) {
498                         *decimal = '\0';
499                         Vpi = (int)strtoul(if_text, NULL, 10);
500                         decimal++;
501                         Vci = (int)strtoul(decimal, NULL, 10);
502                 }
503
504                 /*
505                  * OK, which value means "DTE->DCE" and which value means
506                  * "DCE->DTE"?
507                  */
508                 pseudo_header->atm.channel = header[29];
509
510                 pseudo_header->atm.vpi = Vpi;
511                 pseudo_header->atm.vci = Vci;
512
513                 /* We don't have this information */
514                 pseudo_header->atm.flags = 0;
515                 pseudo_header->atm.cells = 0;
516                 pseudo_header->atm.aal5t_u2u = 0;
517                 pseudo_header->atm.aal5t_len = 0;
518                 pseudo_header->atm.aal5t_chksum = 0;
519                 break;
520
521         case WTAP_ENCAP_ETHERNET:
522                 /* We assume there's no FCS in this frame. */
523                 pseudo_header->eth.fcs_len = 0;
524                 break;
525         }
526 }
527
528 /* Given an RFC1573 (SNMP ifType) interface type,
529  * return the appropriate Wiretap Encapsulation Type.
530  */
531 static int
532 wtap_encap_ift(unsigned int  ift)
533 {
534
535         static const int ift_encap[] = {
536 /* 0x0 */       WTAP_ENCAP_UNKNOWN,     /* nothing */
537 /* 0x1 */       WTAP_ENCAP_UNKNOWN,     /* IFT_OTHER */
538 /* 0x2 */       WTAP_ENCAP_UNKNOWN,     /* IFT_1822 */
539 /* 0x3 */       WTAP_ENCAP_UNKNOWN,     /* IFT_HDH1822 */
540 /* 0x4 */       WTAP_ENCAP_RAW_IP,      /* IFT_X25DDN */
541 /* 0x5 */       WTAP_ENCAP_UNKNOWN,     /* IFT_X25 */
542 /* 0x6 */       WTAP_ENCAP_ETHERNET,    /* IFT_ETHER */
543 /* 0x7 */       WTAP_ENCAP_ETHERNET,    /* IFT_ISO88023 */
544 /* 0x8 */       WTAP_ENCAP_UNKNOWN,     /* IFT_ISO88024 */
545 /* 0x9 */       WTAP_ENCAP_TOKEN_RING,  /* IFT_ISO88025 */
546 /* 0xa */       WTAP_ENCAP_UNKNOWN,     /* IFT_ISO88026 */
547 /* 0xb */       WTAP_ENCAP_UNKNOWN,     /* IFT_STARLAN */
548 /* 0xc */       WTAP_ENCAP_RAW_IP,      /* IFT_P10, IBM SP switch */
549 /* 0xd */       WTAP_ENCAP_UNKNOWN,     /* IFT_P80 */
550 /* 0xe */       WTAP_ENCAP_UNKNOWN,     /* IFT_HY */
551 /* 0xf */       WTAP_ENCAP_FDDI_BITSWAPPED,     /* IFT_FDDI */
552 /* 0x10 */      WTAP_ENCAP_LAPB,        /* IFT_LAPB */  /* no data to back this up */
553 /* 0x11 */      WTAP_ENCAP_UNKNOWN,     /* IFT_SDLC */
554 /* 0x12 */      WTAP_ENCAP_UNKNOWN,     /* IFT_T1 */
555 /* 0x13 */      WTAP_ENCAP_UNKNOWN,     /* IFT_CEPT */
556 /* 0x14 */      WTAP_ENCAP_UNKNOWN,     /* IFT_ISDNBASIC */
557 /* 0x15 */      WTAP_ENCAP_UNKNOWN,     /* IFT_ISDNPRIMARY */
558 /* 0x16 */      WTAP_ENCAP_UNKNOWN,     /* IFT_PTPSERIAL */
559 /* 0x17 */      WTAP_ENCAP_UNKNOWN,     /* IFT_PPP */
560 /* 0x18 */      WTAP_ENCAP_RAW_IP,      /* IFT_LOOP */
561 /* 0x19 */      WTAP_ENCAP_UNKNOWN,     /* IFT_EON */
562 /* 0x1a */      WTAP_ENCAP_UNKNOWN,     /* IFT_XETHER */
563 /* 0x1b */      WTAP_ENCAP_UNKNOWN,     /* IFT_NSIP */
564 /* 0x1c */      WTAP_ENCAP_UNKNOWN,     /* IFT_SLIP */
565 /* 0x1d */      WTAP_ENCAP_UNKNOWN,     /* IFT_ULTRA */
566 /* 0x1e */      WTAP_ENCAP_UNKNOWN,     /* IFT_DS3 */
567 /* 0x1f */      WTAP_ENCAP_UNKNOWN,     /* IFT_SIP */
568 /* 0x20 */      WTAP_ENCAP_UNKNOWN,     /* IFT_FRELAY */
569 /* 0x21 */      WTAP_ENCAP_UNKNOWN,     /* IFT_RS232 */
570 /* 0x22 */      WTAP_ENCAP_UNKNOWN,     /* IFT_PARA */
571 /* 0x23 */      WTAP_ENCAP_UNKNOWN,     /* IFT_ARCNET */
572 /* 0x24 */      WTAP_ENCAP_UNKNOWN,     /* IFT_ARCNETPLUS */
573 /* 0x25 */      WTAP_ENCAP_ATM_PDUS,    /* IFT_ATM */
574         };
575         #define NUM_IFT_ENCAPS (sizeof ift_encap / sizeof ift_encap[0])
576
577         if (ift < NUM_IFT_ENCAPS) {
578                 return ift_encap[ift];
579         }
580         else {
581                 switch(ift) {
582                         /* Infiniband*/
583                         case IPTRACE_IFT_IB:
584                                 return WTAP_ENCAP_INFINIBAND;
585                                 break;
586
587                         /* Host Fabric Interface */
588                         case IPTRACE_IFT_HF:
589                                 /* The HFI interface on AIX provides raw IP
590                                 in the packet trace. It's unclear if the HFI
591                                 can be configured for any other protocol, and if
592                                 any field in the iptrace header indicates what
593                                 that protocol is. For now, we are hard-coding
594                                 this as RAW_IP, but if we find another iptrace file
595                                 using HFI that provides another protocol, we will
596                                 have to figure out which field in the iptrace file
597                                 encodes it. */
598                                 return WTAP_ENCAP_RAW_IP;
599                                 break;
600
601                         default:
602                                 return WTAP_ENCAP_UNKNOWN;
603                 }
604         }
605 }
606
607 /*
608  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
609  *
610  * Local variables:
611  * c-basic-offset: 8
612  * tab-width: 8
613  * indent-tabs-mode: t
614  * End:
615  *
616  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
617  * :indentSize=8:tabSize=8:noTabs=false:
618  */