| /* vi: set sw=4 ts=4: */ |
| /* |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License |
| * as published by the Free Software Foundation; either version |
| * 2 of the License, or (at your option) any later version. |
| * |
| * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |
| */ |
| #include "libbb.h" |
| #include "rt_names.h" |
| #include "utils.h" |
| |
| #include <netinet/if_ether.h> |
| |
| /* Please conditionalize exotic protocols on CONFIG_something */ |
| |
| static const uint16_t llproto_ids[] ALIGN2 = { |
| #define __PF(f,n) ETH_P_##f, |
| __PF(LOOP,loop) |
| __PF(PUP,pup) |
| #ifdef ETH_P_PUPAT |
| __PF(PUPAT,pupat) |
| #endif |
| __PF(IP,ip) |
| __PF(X25,x25) |
| __PF(ARP,arp) |
| __PF(BPQ,bpq) |
| #ifdef ETH_P_IEEEPUP |
| __PF(IEEEPUP,ieeepup) |
| #endif |
| #ifdef ETH_P_IEEEPUPAT |
| __PF(IEEEPUPAT,ieeepupat) |
| #endif |
| __PF(DEC,dec) |
| __PF(DNA_DL,dna_dl) |
| __PF(DNA_RC,dna_rc) |
| __PF(DNA_RT,dna_rt) |
| __PF(LAT,lat) |
| __PF(DIAG,diag) |
| __PF(CUST,cust) |
| __PF(SCA,sca) |
| __PF(RARP,rarp) |
| __PF(ATALK,atalk) |
| __PF(AARP,aarp) |
| __PF(IPX,ipx) |
| __PF(IPV6,ipv6) |
| #ifdef ETH_P_PPP_DISC |
| __PF(PPP_DISC,ppp_disc) |
| #endif |
| #ifdef ETH_P_PPP_SES |
| __PF(PPP_SES,ppp_ses) |
| #endif |
| #ifdef ETH_P_ATMMPOA |
| __PF(ATMMPOA,atmmpoa) |
| #endif |
| #ifdef ETH_P_ATMFATE |
| __PF(ATMFATE,atmfate) |
| #endif |
| |
| __PF(802_3,802_3) |
| __PF(AX25,ax25) |
| __PF(ALL,all) |
| __PF(802_2,802_2) |
| __PF(SNAP,snap) |
| __PF(DDCMP,ddcmp) |
| __PF(WAN_PPP,wan_ppp) |
| __PF(PPP_MP,ppp_mp) |
| __PF(LOCALTALK,localtalk) |
| __PF(PPPTALK,ppptalk) |
| __PF(TR_802_2,tr_802_2) |
| __PF(MOBITEX,mobitex) |
| __PF(CONTROL,control) |
| __PF(IRDA,irda) |
| #ifdef ETH_P_ECONET |
| __PF(ECONET,econet) |
| #endif |
| |
| 0x8100, |
| ETH_P_IP |
| }; |
| #undef __PF |
| |
| /* Keep declarations above and below in sync! */ |
| |
| static const char llproto_names[] ALIGN1 = |
| #define __PF(f,n) #n "\0" |
| __PF(LOOP,loop) |
| __PF(PUP,pup) |
| #ifdef ETH_P_PUPAT |
| __PF(PUPAT,pupat) |
| #endif |
| __PF(IP,ip) |
| __PF(X25,x25) |
| __PF(ARP,arp) |
| __PF(BPQ,bpq) |
| #ifdef ETH_P_IEEEPUP |
| __PF(IEEEPUP,ieeepup) |
| #endif |
| #ifdef ETH_P_IEEEPUPAT |
| __PF(IEEEPUPAT,ieeepupat) |
| #endif |
| __PF(DEC,dec) |
| __PF(DNA_DL,dna_dl) |
| __PF(DNA_RC,dna_rc) |
| __PF(DNA_RT,dna_rt) |
| __PF(LAT,lat) |
| __PF(DIAG,diag) |
| __PF(CUST,cust) |
| __PF(SCA,sca) |
| __PF(RARP,rarp) |
| __PF(ATALK,atalk) |
| __PF(AARP,aarp) |
| __PF(IPX,ipx) |
| __PF(IPV6,ipv6) |
| #ifdef ETH_P_PPP_DISC |
| __PF(PPP_DISC,ppp_disc) |
| #endif |
| #ifdef ETH_P_PPP_SES |
| __PF(PPP_SES,ppp_ses) |
| #endif |
| #ifdef ETH_P_ATMMPOA |
| __PF(ATMMPOA,atmmpoa) |
| #endif |
| #ifdef ETH_P_ATMFATE |
| __PF(ATMFATE,atmfate) |
| #endif |
| |
| __PF(802_3,802_3) |
| __PF(AX25,ax25) |
| __PF(ALL,all) |
| __PF(802_2,802_2) |
| __PF(SNAP,snap) |
| __PF(DDCMP,ddcmp) |
| __PF(WAN_PPP,wan_ppp) |
| __PF(PPP_MP,ppp_mp) |
| __PF(LOCALTALK,localtalk) |
| __PF(PPPTALK,ppptalk) |
| __PF(TR_802_2,tr_802_2) |
| __PF(MOBITEX,mobitex) |
| __PF(CONTROL,control) |
| __PF(IRDA,irda) |
| #ifdef ETH_P_ECONET |
| __PF(ECONET,econet) |
| #endif |
| |
| "802.1Q" "\0" |
| "ipv4" "\0" |
| ; |
| #undef __PF |
| |
| |
| const char* FAST_FUNC ll_proto_n2a(unsigned short id, char *buf, int len) |
| { |
| unsigned i; |
| id = ntohs(id); |
| for (i = 0; i < ARRAY_SIZE(llproto_ids); i++) { |
| if (llproto_ids[i] == id) |
| return nth_string(llproto_names, i); |
| } |
| snprintf(buf, len, "[%u]", id); |
| return buf; |
| } |
| |
| int FAST_FUNC ll_proto_a2n(unsigned short *id, char *buf) |
| { |
| unsigned i; |
| const char *name = llproto_names; |
| for (i = 0; i < ARRAY_SIZE(llproto_ids); i++) { |
| if (strcasecmp(name, buf) == 0) { |
| i = llproto_ids[i]; |
| goto good; |
| } |
| name += strlen(name) + 1; |
| } |
| errno = 0; |
| i = bb_strtou(buf, NULL, 0); |
| if (errno || i > 0xffff) |
| return -1; |
| good: |
| *id = htons(i); |
| return 0; |
| } |