The Assimilation Project
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lldp.c
Go to the documentation of this file.
1 
25 #include <stdio.h>
26 #include <string.h>
27 #include <lldp.h>
28 #include <lldp.h>
29 #include <server_dump.h>
30 #define DIMOF(a) (sizeof(a)/sizeof(a[0]))
31 
32 #define NETTLV_INITPKTOFFSET 14
33 #define NETTLV_HDRSZ 2
34 unsigned get_oui(const void* ouiptr);
35 const char * get_oui_string(unsigned oui);
36 const char * get_lldp_type_string(unsigned lldptype);
37 void dump_lldp_packet(const void*, const void*);
38 
39 static const char * lldptypenames[] =
40 { "end"
41 , "chassis_id"
42 , "port_id"
43 , "ttl"
44 , "port description"
45 , "system_name"
46 , "system_description"
47 , "capabilities"
48 , "mgmt_address"
49 };
50 
53 unsigned
54 get_oui(const void* ouiptr)
55 {
56  const unsigned char* ucptr = ouiptr;
57  unsigned ret = 0;
58  int j;
59  for (j=0; j < 3; j++) {
60  ret <<= 8;
61  ret |= *ucptr;
62  ++ucptr;
63  }
64  return ret;
65 }
66 static struct {
67  unsigned oui;
68  const char* string;
69 }ouimap[] =
70 { {0x000FAC, "IEEE 802.11"}
71 , {0x00120F, "IEEE 802.3"}
72 , {0x00190D, "IEEE 1394c"}
73 , {0x001B19, "IEEE I&M Society TC9"}
74 , {0x001BC5, "IEEE Registration Authority"}
75 , {0x0050C2, "IEEE REGISTRATION AUTHORITY"}
76 , {0x0080C2, "IEEE 802.1"}
77 , {0x1C129D, "IEEE PES PSRC/SUB"}
78 , {0x58D08F, "IEEE 1904.1"}
79 , {0x90E0F0, "IEEE P1722"}
80 };
81 
87 const char *
88 get_oui_string(unsigned oui)
89 {
90  unsigned j;
91  static char ret[64];
92 
93  for (j=0; j < DIMOF(ouimap); ++j) {
94  if (oui == ouimap[j].oui) {
95  return ouimap[j].string;
96  }
97  }
98  g_snprintf(ret, sizeof(ret), "OUI 0x%06x", oui);
99  return ret;
100 }
101 
102 
107 const char *
108 get_lldp_type_string(unsigned lldptype)
109 {
110  if (lldptype < DIMOF(lldptypenames)) {
111  return lldptypenames[lldptype];
112  }
113  if (lldptype == LLDP_TLV_ORG_SPECIFIC) {
114  return "org_specific";
115  }
116  return "UnknownLLDPtype";
117 }
119 void
120 dump_lldp_packet(const void* tlv_vpv,
121  const void* tlv_vpendv)
122 {
123  const guchar* tlv_vp = tlv_vpv;
124  const guchar* tlv_vpend = tlv_vpendv;
125  if (tlv_vp == NULL || !is_valid_lldp_packet(tlv_vp, tlv_vpend)) {
126  fprintf(stdout, "%ld byte lldptlv structure at address %p is not valid.\n"
127  , (long)(tlv_vpend-tlv_vp), tlv_vp);
128  return;
129  }
130  for (tlv_vp = get_lldptlv_first(tlv_vp, tlv_vpend)
131  ; NULL != tlv_vp
132  ; tlv_vp = get_lldptlv_next(tlv_vp, tlv_vpend)) {
133  unsigned ttype = get_lldptlv_type(tlv_vp, tlv_vpend);
134  gsize tlen = get_lldptlv_len(tlv_vp, tlv_vpend);
135  const unsigned char* tbody = get_lldptlv_body(tlv_vp, tlv_vpend);
136 
137 
138  if (ttype == LLDP_TLV_ORG_SPECIFIC) {
139  unsigned oui = get_oui(tbody);
140  unsigned subtype = tbody[3];
141  fprintf(stdout, "Org Specific TLV, %s subtype=%d sublength: %"G_GSIZE_FORMAT", values: "
142  , get_oui_string(oui), subtype, tlen-4);
143  dump_mem(tbody+4, tbody+tlen);
144  fprintf(stdout, "\n");
145  continue;
146  }
147 
148  fprintf(stdout, "TLV type: %s, length: %d, values: "
149  , get_lldp_type_string(ttype), (int)tlen);
150  dump_mem(tbody, tbody+tlen);
151  fprintf(stdout, "\n");
152  }
153 }