source: lib/link_wireless.c @ a81d2fc

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since a81d2fc was f0c639b, checked in by Scott Raynel <smr26@…>, 14 years ago
  • Remove trace_get_wireless_fcs as it is no longer part of the Radiotap standard.
  • Update trace_get_wire_length to account for the presence (or absence) of FCS bytes at the end of wireless frames. (only pcap and pcapfile for now)
  • Update radiotap libpacketdump decoder to no longer output non-standard FCS field.
  • Update test-wireless to ensure new length functions work correctly.
  • Property mode set to 100644
File size: 16.3 KB
RevLine 
[c4cf162]1/*
2 * This file is part of libtrace
3 *
4 * link_wireless.c
5 * Implements the trace_get_wireless_* methods defined in libtrace.h
6 *
[d5a27e8]7 * Copyright (c) 2007 The University of Waikato, Hamilton, New Zealand.
[c4cf162]8 * Authors: Scott Raynel
9 *          Perry Lorier
10 *         
11 * All rights reserved.
12 *
13 * This code has been developed by the University of Waikato WAND
14 * research group. For further information please see http://www.wand.net.nz/
15 *
16 * libtrace is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * libtrace is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with libtrace; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 *
30 */
31
32#include "libtrace.h"
33#include "libtrace_int.h"
34
35/* Used for Radiotap fields which must be naturally aligned */
36#define ALIGN_NATURAL_64(_p,_s) \
[52c7cda]37        while ( (_p - _s) % sizeof(uint64_t)) _p++
[c4cf162]38#define ALIGN_NATURAL_32(_p,_s) \
[52c7cda]39        while ( (_p - _s) % sizeof(uint32_t)) _p++
[c4cf162]40#define ALIGN_NATURAL_16(_p,_s) \
[52c7cda]41        while ( (_p - _s) % sizeof(uint16_t)) _p++
[c4cf162]42
43/** Gets a field from a Radiotap header.
44 * @param link the radiotap header
45 * @param field the radiotap field we want to access
46 * @return a void pointer to the field. It is up to the caller to cast to the
47 * appropriate type.
48 * @note Radiotap fields are always little-endian
49 */
[6df012d]50static void *trace_get_radiotap_field(void *link, libtrace_radiotap_field_t field)
[c4cf162]51{
[52c7cda]52        struct libtrace_radiotap_t *rtap = (struct libtrace_radiotap_t *)link;
53        uint8_t *p;
54        uint8_t *s;
55
56        /* Check if the field exists in the radiotap header before proceeding
57        */
[273a08e]58        if ((bswap_le_to_host32(rtap->it_present) & (1 << field)) == 0) return NULL;
[52c7cda]59
60        /* Skip over any extended bitmasks */
61        p = (uint8_t *) &(rtap->it_present);
62
[4bd8a5b]63        while ( bswap_le_to_host32(*((uint32_t*)p)) & (1U << TRACE_RADIOTAP_EXT) ) {
[52c7cda]64                p += sizeof (uint32_t);
65        }
66
67        /* Point p at the first field of radiotap data and remember it for later
68         * when we're doing field alignment
69         */
70        p += sizeof(uint32_t);
71        s = p;
72
73        if (field == TRACE_RADIOTAP_TSFT) 
74                /* Always aligned */
75                return (void*)p;
[273a08e]76        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_TSFT))
[52c7cda]77                p += sizeof (uint64_t);
78
79        if (field == TRACE_RADIOTAP_FLAGS)
80                /* Always aligned */
81                return (void*)p;
[273a08e]82        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_FLAGS))
[52c7cda]83                p += sizeof (uint8_t);
84
85        if (field == TRACE_RADIOTAP_RATE)
86                /* Always aligned */
87                return (void*)p;
[273a08e]88        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_RATE))
[52c7cda]89                p+= sizeof (uint8_t);
90
91        if (field == TRACE_RADIOTAP_CHANNEL)
92        {
93                ALIGN_NATURAL_16(p,s);
94                return (void *)p;
95        }
[273a08e]96        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_CHANNEL))
[52c7cda]97                p+= sizeof (uint32_t);
98
99        if (field == TRACE_RADIOTAP_FHSS)
100        {
101                ALIGN_NATURAL_16(p,s);
102                return (void *)p;
103        }
[273a08e]104        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_FHSS))
[52c7cda]105                p+= sizeof (uint16_t);
106
107        if (field == TRACE_RADIOTAP_DBM_ANTSIGNAL)
108                return (void *)p;
[273a08e]109        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_DBM_ANTSIGNAL))
[52c7cda]110                p+= sizeof (uint8_t);
111
112        if (field == TRACE_RADIOTAP_DBM_ANTNOISE)
113                return (void *)p;
[273a08e]114        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_DBM_ANTNOISE))
[52c7cda]115                p+= sizeof (uint8_t);
116
117        if (field == TRACE_RADIOTAP_LOCK_QUALITY)
118        {
119                ALIGN_NATURAL_16(p,s);
120                return (void *)p;
121        }
[273a08e]122        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_LOCK_QUALITY))
[52c7cda]123                p+= sizeof (uint16_t);
124
125        if (field == TRACE_RADIOTAP_TX_ATTENUATION)
126        {
127                ALIGN_NATURAL_16(p,s);
128                return (void *)p;
129        }
[273a08e]130        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_TX_ATTENUATION))
[52c7cda]131                p+= sizeof (uint16_t);
132
133        if (field == TRACE_RADIOTAP_DB_TX_ATTENUATION)
134        {
135                ALIGN_NATURAL_16(p,s);
136                return (void *)p;
137        }
[273a08e]138        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_DB_TX_ATTENUATION))
[52c7cda]139                p+= sizeof (uint16_t);
140
141        if (field == TRACE_RADIOTAP_DBM_TX_POWER)
142                return (void *)p;
[273a08e]143        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_DBM_TX_POWER))
[52c7cda]144                p+= sizeof (uint8_t);
145
146        if (field == TRACE_RADIOTAP_ANTENNA)
147                return (void *)p;
[273a08e]148        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_ANTENNA))
[52c7cda]149                p+= sizeof (uint8_t);
150
151        if (field == TRACE_RADIOTAP_DB_ANTSIGNAL)
152                return (void *)p;
[273a08e]153        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_DB_ANTSIGNAL))
[52c7cda]154                p+= sizeof (uint8_t);
155
156        if (field == TRACE_RADIOTAP_DB_ANTNOISE)
157                return (void *) p;
[f0c639b]158        /*
[273a08e]159        if (bswap_le_to_host32(rtap->it_present) & (1 << TRACE_RADIOTAP_DB_ANTNOISE))
[52c7cda]160                p+= sizeof (uint8_t);
[f0c639b]161        */
[52c7cda]162
163        /* Unknown field */
164        return NULL;
[c4cf162]165} 
[52c7cda]166
[c4cf162]167DLLEXPORT bool trace_get_wireless_tsft(void *link, 
[52c7cda]168                libtrace_linktype_t linktype, uint64_t *tsft)
[c4cf162]169{
[52c7cda]170        uint64_t *p;
171        void *l;
172        uint16_t type;
173        if (link == NULL || tsft == NULL) return false;
174
175        switch (linktype) {
176                case TRACE_TYPE_80211_RADIO:
177                        if( (p = (uint64_t *) trace_get_radiotap_field(link, 
178                                                        TRACE_RADIOTAP_TSFT))) {
179                                *tsft = bswap_le_to_host64(*p);
180                                return true;
181                        } else break;
182                case TRACE_TYPE_LINUX_SLL:
183                        l = trace_get_payload_from_linux_sll(link, &type, NULL );
184                        return trace_get_wireless_tsft(l, arphrd_type_to_libtrace(type), tsft);
185
186                case TRACE_TYPE_80211_PRISM:
187                        return false;
188                default:
189                        return false;
190        }
191        return false;
[c4cf162]192}
193
[5696294]194/*
195 * This function isn't portable across drivers, so has been left static
196 * for now. Maybe it will be included in the API later if it becomes useful
197 * and we come up with a suitable abstraction.
[f0c639b]198 * This function isn't marked static as the various format modules need to
199 * access it for get_wire_length(). It's not meant to be exported though.
[5696294]200 */
201bool trace_get_wireless_flags(void *link, 
[52c7cda]202                libtrace_linktype_t linktype, uint8_t *flags)
[c4cf162]203{
[52c7cda]204        uint8_t *p;
205        void *l;
206        uint16_t type;
207
208        if (link == NULL || flags == NULL) return false;
209
210        switch(linktype) {
211                case TRACE_TYPE_80211_RADIO:
212                        if (( p = (uint8_t *) trace_get_radiotap_field(link,
213                                                        TRACE_RADIOTAP_FLAGS))) {
214                                *flags = *p;
215                                return true;
216                        } else break;
217                case TRACE_TYPE_LINUX_SLL:
218                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
219                        return trace_get_wireless_flags(l, arphrd_type_to_libtrace(type), flags);
220                default:
221                        return false;
222        }
223        return false;
[c4cf162]224}
225
226DLLEXPORT bool trace_get_wireless_rate(void *link, 
[52c7cda]227                libtrace_linktype_t linktype, uint8_t *rate)
[c4cf162]228{
[52c7cda]229        uint8_t * p;
230        void *l;
231        uint16_t type;
232
233        if (link == NULL || rate == NULL) return false ;
234        switch (linktype) {
235                case TRACE_TYPE_80211_RADIO:
236                        if ( (p = (uint8_t *) trace_get_radiotap_field(link,
237                                                        TRACE_RADIOTAP_RATE))) {
238                                *rate = *p;
239                                return true;
240                        } else break;
241                case TRACE_TYPE_LINUX_SLL:
242                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
243                        return trace_get_wireless_rate(l, arphrd_type_to_libtrace(type), rate);
244                default:
245                        return false;
246        }
247        return false;
[c4cf162]248}
249
250DLLEXPORT bool trace_get_wireless_freq(void *link, 
[52c7cda]251                libtrace_linktype_t linktype, uint16_t *freq)
[c4cf162]252{
[52c7cda]253        uint16_t *p;
254        void *l;
255        uint16_t type;
256
257        if (link == NULL || freq == NULL) return false;
258        switch (linktype) {
259                case TRACE_TYPE_80211_RADIO:
260                        /* NB: The channel field is actually two 16 bit fields.
261                         * The chan_freq field is the first of those two, so we
262                         * just cast it to a uint16_t.
263                         */
264                        if (( p = (uint16_t *) trace_get_radiotap_field(link,
265                                                        TRACE_RADIOTAP_CHANNEL))) {
266                                *freq = bswap_le_to_host16(*p);
267                                return true;
268                        } else break;
269                case TRACE_TYPE_LINUX_SLL:
270                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
271                        return trace_get_wireless_freq(l, arphrd_type_to_libtrace(type), freq);
272                default:
273                        return false;
274        }
275        return false;
[c4cf162]276}
[52c7cda]277
[5696294]278/*
279 * This function isn't portable across drivers, so has been left static
280 * for now. Maybe it will be included in the API later if it becomes useful
281 * and we come up with a suitable abstraction.
282 */
283static
284bool trace_get_wireless_channel_flags(void *link,
[52c7cda]285                libtrace_linktype_t linktype, uint16_t *flags)
[c4cf162]286{
[52c7cda]287        uint16_t *p;
288        void *l;
289        uint16_t type;
290        if (link == NULL || flags == NULL) return false;
291        switch (linktype) {
292                case TRACE_TYPE_80211_RADIO:
293                        /* NB: The channel field is actually two 16 bit fields.
294                         * The chan_flags field is the second of the two, so we need
295                         * to take the pointer returned by getting the channel field
296                         * and increment it.
297                         */
298                        if ((p = (uint16_t *) trace_get_radiotap_field(link,
299                                                        TRACE_RADIOTAP_CHANNEL))) {
300                                *flags = bswap_le_to_host16(*(++p));
301                                return true;
302                        } else break;
303                case TRACE_TYPE_LINUX_SLL:
304                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
305                        return trace_get_wireless_channel_flags(l, arphrd_type_to_libtrace(type), flags);
306                default:
307                        return false;
308        }
309        return false;
[c4cf162]310}
311
[5696294]312/* Not sure that this function is useful for now - who uses FHSS?
313 * This might get exported in the future if it becomes useful
314 */
315static
316bool trace_get_wireless_fhss_hopset(void *link,
[52c7cda]317                libtrace_linktype_t linktype, uint8_t *hopset)
[c4cf162]318{
[52c7cda]319        uint8_t *p;
320        void *l;
321        uint16_t type;
322
323        if (link == NULL || hopset == NULL) return false;
324        switch(linktype) {
325                case TRACE_TYPE_80211_RADIO:
326                        /* NB: As above with the channel field, the fhss field is
327                         * similar.
328                         */
329                        if( (p = (uint8_t *) trace_get_radiotap_field(link,
330                                                        TRACE_RADIOTAP_FHSS))) {
331                                *hopset = *p;
332                                return true;
333                        } else break;
334                case TRACE_TYPE_LINUX_SLL:
335                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
336                        return trace_get_wireless_fhss_hopset(l, arphrd_type_to_libtrace(type), hopset);
337                default:
338                        return false;
339        }
340        return false;
[c4cf162]341}
342
[5696294]343/* Not sure that this function is useful for now - who uses FHSS?
344 * This might get exported in the future if it becomes useful
345 */
346static
347bool trace_get_wireless_fhss_hoppattern(void *link,
[52c7cda]348                libtrace_linktype_t linktype, uint8_t *hoppattern)
[c4cf162]349{
[52c7cda]350        uint8_t *p;
351        void *l;
352        uint16_t type;
353        if (link == NULL || hoppattern == NULL) return false;
354        switch (linktype) {
355                case TRACE_TYPE_80211_RADIO:
356                        if((p = (uint8_t *) trace_get_radiotap_field(link,
357                                                        TRACE_RADIOTAP_FHSS))) {
358                                *hoppattern = *(++p);
359                                return true;
360                        } else break;
361                case TRACE_TYPE_LINUX_SLL:
362                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
363                        return trace_get_wireless_fhss_hoppattern(l, arphrd_type_to_libtrace(type), hoppattern);
364                default:
365                        return false;
366        }
367        return false;
[c4cf162]368}
369
370DLLEXPORT bool trace_get_wireless_signal_strength_dbm(void *link,
[52c7cda]371                libtrace_linktype_t linktype, int8_t *strength)
[c4cf162]372{
[52c7cda]373        int8_t *p;
374        void *l;
375        uint16_t type;
376
377        if (link == NULL || strength == NULL) return false;
378        switch(linktype) {
379                case TRACE_TYPE_80211_RADIO:
380                        if ((p =  (int8_t *) trace_get_radiotap_field(link,
381                                                        TRACE_RADIOTAP_DBM_ANTSIGNAL))) {
382                                *strength = *p;
383                                return true;
384                        } else break;
385                case TRACE_TYPE_LINUX_SLL:
386                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
387                        return trace_get_wireless_signal_strength_dbm(l, arphrd_type_to_libtrace(type), strength);
388                default:
389                        return false;
390        }
391        return false;
[c4cf162]392}
393
394DLLEXPORT bool trace_get_wireless_noise_strength_dbm(void *link,
[52c7cda]395                libtrace_linktype_t linktype, int8_t *strength)
[c4cf162]396{
[52c7cda]397        uint8_t *p;
398        void *l;
399        uint16_t type;
400
401        if (link == NULL || strength == NULL) return false;
402        switch (linktype) {
403                case TRACE_TYPE_80211_RADIO:
[73da4ae]404                        if (( p = (uint8_t *) trace_get_radiotap_field(link,
405                                        TRACE_RADIOTAP_DBM_ANTNOISE))) {
[52c7cda]406                                *strength = *p;
407                                return true;
408                        } else break;
409                case TRACE_TYPE_LINUX_SLL:
410                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
411                        return trace_get_wireless_noise_strength_dbm(l, arphrd_type_to_libtrace(type), strength);
412                default:
413                        return false;
414        }
415        return false;
[c4cf162]416}
417
418DLLEXPORT bool trace_get_wireless_signal_strength_db(void *link,
[52c7cda]419                libtrace_linktype_t linktype, uint8_t *strength)
[c4cf162]420{
[52c7cda]421        uint8_t *p;
422        void *l;
423        uint16_t type;
424
425        if (link == NULL || strength == NULL) return false;
426        switch (linktype) {
427                case TRACE_TYPE_80211_RADIO:
428                        if ((p =  (uint8_t *) trace_get_radiotap_field(link,
429                                                        TRACE_RADIOTAP_DB_ANTSIGNAL))) {
430                                *strength = *p;
431                                return true;
432                        } else break;
433                case TRACE_TYPE_LINUX_SLL:
434                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
435                        return trace_get_wireless_signal_strength_db(l, arphrd_type_to_libtrace(type), strength);
436                default:
437                        return false;
438        }
439        return false ;
[c4cf162]440}
441
442DLLEXPORT bool trace_get_wireless_noise_strength_db(void *link,
[52c7cda]443                libtrace_linktype_t linktype, uint8_t *strength)
[c4cf162]444{
[52c7cda]445        uint8_t *p;
446        void *l;
447        uint16_t type;
448
449        if (link == NULL || strength == NULL) return false;
450        switch (linktype) {
451                case TRACE_TYPE_80211_RADIO:
452                        if ((p = (uint8_t *) trace_get_radiotap_field(link,
453                                                        TRACE_RADIOTAP_DB_ANTNOISE))) {
454                                *strength = *p;
455                                return true;
456                        } else break;
457                case TRACE_TYPE_LINUX_SLL:
458                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
459                        return trace_get_wireless_noise_strength_db(l, arphrd_type_to_libtrace(type), strength);
460                default:
461                        return false;
462        }
463        return false;
[c4cf162]464}
465
[5696294]466/* Not sure if this function is useful. As the radiotap documentation says,
467 * there's no set metric for defining the quality of the Barker Code Lock.
468 * Maybe it will be exported later if it becomes useful.
469 */
470static
471bool trace_get_wireless_lock_quality(void *link,
[52c7cda]472                libtrace_linktype_t linktype, uint16_t *quality)
[c4cf162]473{
[52c7cda]474        uint16_t *p;
475        void *l;
476        uint16_t type;
477
478        if (link == NULL || quality == NULL) return false;
479        switch (linktype) {
480                case TRACE_TYPE_80211_RADIO:
481                        if((p = (uint16_t *) trace_get_radiotap_field(link,
482                                                        TRACE_RADIOTAP_LOCK_QUALITY))) {
483                                *quality = bswap_le_to_host16(*p);
484                                return true;
485                        } else break;
486                case TRACE_TYPE_LINUX_SLL:
487                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
488                        return trace_get_wireless_lock_quality(l, arphrd_type_to_libtrace(type), quality);
489                default:
490                        return false;
491        }
492        return false;
[c4cf162]493}
494
495DLLEXPORT bool trace_get_wireless_tx_attenuation(void *link,
[52c7cda]496                libtrace_linktype_t linktype, uint16_t *attenuation)
[c4cf162]497{
[52c7cda]498        uint16_t *p;
499        void *l;
500        uint16_t type;
501
502        if (link == NULL || attenuation == 0) return false;
503        switch (linktype) {
504                case TRACE_TYPE_80211_RADIO:
505                        if ((p = (uint16_t *) trace_get_radiotap_field(link,
506                                                        TRACE_RADIOTAP_TX_ATTENUATION))) {
507                                *attenuation = bswap_le_to_host16(*p);
508                                return true;
509                        } else break;
510                case TRACE_TYPE_LINUX_SLL:
511                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
512                        return trace_get_wireless_tx_attenuation(l, arphrd_type_to_libtrace(type), attenuation);
513                default:
514                        return false;
515        }
516        return false;
[c4cf162]517}
518
519DLLEXPORT bool trace_get_wireless_tx_attenuation_db(void *link,
[52c7cda]520                libtrace_linktype_t linktype, uint16_t *attenuation)
[c4cf162]521{
[52c7cda]522        uint16_t *p;
523        void *l;
524        uint16_t type;
525
526        if (link == NULL || attenuation == NULL) return false;
527        switch (linktype) {
528                case TRACE_TYPE_80211_RADIO:
529                        if ((p = (uint16_t *) trace_get_radiotap_field(link,
530                                                        TRACE_RADIOTAP_DB_TX_ATTENUATION))) {
531                                *attenuation = bswap_le_to_host16(*p);
532                                return true;
533                        } else break;
534                case TRACE_TYPE_LINUX_SLL:
535                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
536                        return trace_get_wireless_tx_attenuation_db(l, arphrd_type_to_libtrace(type), attenuation);
537                default:
538                        return false;
539        }
540        return false;
[c4cf162]541}
542
543DLLEXPORT bool trace_get_wireless_tx_power_dbm(void *link,
[52c7cda]544                libtrace_linktype_t linktype, int8_t *txpower)
[c4cf162]545{
[52c7cda]546        int8_t *p;
547        void *l;
548        uint16_t type;
549
550        if (link == NULL || txpower == NULL) return false;
551        switch (linktype) {
552                case TRACE_TYPE_80211_RADIO:
553                        if ((p=(int8_t *) trace_get_radiotap_field(link,
554                                                        TRACE_RADIOTAP_DBM_TX_POWER))) {
555                                *txpower = *p;
556                                return true;
557                        } else break;
558                case TRACE_TYPE_LINUX_SLL:
559                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
560                        return trace_get_wireless_tx_power_dbm(l, arphrd_type_to_libtrace(type), txpower);
561                default:
562                        return false;
563        }
564        return false;
[c4cf162]565}
566
567
568DLLEXPORT bool trace_get_wireless_antenna(void *link,
[52c7cda]569                libtrace_linktype_t linktype, uint8_t *antenna)
[c4cf162]570{
[52c7cda]571        uint8_t *p;
572        void *l;
573        uint16_t type;
574
575        if (link == NULL || antenna == NULL) return false;
576        switch (linktype) {
577                case TRACE_TYPE_80211_RADIO:
578                        if ((p = (uint8_t *) trace_get_radiotap_field(link,
579                                                        TRACE_RADIOTAP_ANTENNA))) {
580                                *antenna = *p;
581                                return true;
582                        } else break;
583                case TRACE_TYPE_LINUX_SLL:
584                        l = trace_get_payload_from_linux_sll(link, &type, NULL);
585                        return trace_get_wireless_antenna(l, arphrd_type_to_libtrace(type), antenna);
586                default:
587                        return false;
588        }
589        return false;
[c4cf162]590}
591
Note: See TracBrowser for help on using the repository browser.