Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #include "base/os.h"
7 : #include <netinet/icmp6.h>
8 : #include <boost/assign/list_of.hpp>
9 : #include <pkt/pkt_handler.h>
10 : #include <oper/mirror_table.h>
11 : #include <oper/vn.h>
12 : #include <pkt/pkt_init.h>
13 : #include <services/services_init.h>
14 : #include <services/dhcp_proto.h>
15 : #include <services/dhcpv6_proto.h>
16 : #include <services/arp_proto.h>
17 : #include <services/bfd_proto.h>
18 : #include <services/dns_proto.h>
19 : #include <services/icmp_proto.h>
20 : #include <services/igmp_proto.h>
21 : #include <services/icmpv6_proto.h>
22 : #include <services/metadata_proxy.h>
23 : #include <services/services_types.h>
24 : #include <services/services_sandesh.h>
25 : #include <bind/bind_resolver.h>
26 : #include <vr_defs.h>
27 :
28 : #define SET_ICMPV6_INTERFACE_STATS(it, list) \
29 : InterfaceIcmpv6Stats entry; \
30 : VmInterface *vmi = it->first; \
31 : const Icmpv6Proto::Icmpv6Stats &stats = it->second; \
32 : entry.set_interface_index(vmi->id()); \
33 : entry.set_icmpv6_router_solicit(stats.icmpv6_router_solicit_); \
34 : entry.set_icmpv6_router_advert(stats.icmpv6_router_advert_); \
35 : entry.set_icmpv6_ping_request(stats.icmpv6_ping_request_); \
36 : entry.set_icmpv6_ping_response(stats.icmpv6_ping_response_); \
37 : entry.set_icmpv6_neighbor_solicit(stats.icmpv6_neighbor_solicit_); \
38 : entry.set_icmpv6_neighbor_solicited(stats.icmpv6_neighbor_solicited_); \
39 : entry.set_icmpv6_neighbor_advert_solicited \
40 : (stats.icmpv6_neighbor_advert_solicited_); \
41 : entry.set_icmpv6_neighbor_advert_unsolicited \
42 : (stats.icmpv6_neighbor_advert_unsolicited_); \
43 : list.push_back(entry);
44 :
45 : std::map<uint16_t, std::string> g_ip_protocol_map =
46 : boost::assign::map_list_of<uint16_t, std::string>
47 : (1, "icmp")
48 : (2, "igmp")
49 : (4, "ipv4")
50 : (6, "tcp")
51 : (17, "udp")
52 : (41, "ipv6")
53 : (47, "gre");
54 :
55 : std::map<uint32_t, std::string> g_dhcp_msg_types =
56 : boost::assign::map_list_of<uint32_t, std::string>
57 : (DHCP_UNKNOWN, "Unknown")
58 : (DHCP_DISCOVER, "Discover")
59 : (DHCP_OFFER, "Offer")
60 : (DHCP_REQUEST, "Request")
61 : (DHCP_ACK, "Ack")
62 : (DHCP_NAK, "Nack")
63 : (DHCP_INFORM, "Inform")
64 : (DHCP_DECLINE, "Decline")
65 : (DHCP_RELEASE, "Release")
66 : (DHCP_LEASE_QUERY, "Lease Query")
67 : (DHCP_LEASE_UNASSIGNED, "Lease Unassigned")
68 : (DHCP_LEASE_UNKNOWN, "Lease Unknown")
69 : (DHCP_LEASE_ACTIVE, "Lease Active");
70 :
71 : std::map<uint32_t, std::string> g_dhcpv6_msg_types =
72 : boost::assign::map_list_of<uint32_t, std::string>
73 : (DHCPV6_UNKNOWN, "Unknown")
74 : (DHCPV6_SOLICIT, "Solicit")
75 : (DHCPV6_ADVERTISE, "Advertise")
76 : (DHCPV6_REQUEST, "Request")
77 : (DHCPV6_CONFIRM, "Confirm")
78 : (DHCPV6_RENEW, "Renew")
79 : (DHCPV6_REBIND, "Rebind")
80 : (DHCPV6_REPLY, "Reply")
81 : (DHCPV6_RELEASE, "Release")
82 : (DHCPV6_DECLINE, "Decline")
83 : (DHCPV6_RECONFIGURE, "Reconfigure")
84 : (DHCPV6_INFORMATION_REQUEST, "Information Request");
85 :
86 0 : void ServicesSandesh::MacToString(const unsigned char *mac, std::string &mac_str) {
87 : char mstr[32];
88 0 : snprintf(mstr, 32, "%02x:%02x:%02x:%02x:%02x:%02x",
89 0 : mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
90 0 : mac_str.assign(mstr);
91 0 : }
92 :
93 0 : std::string ServicesSandesh::IntToString(uint32_t val) {
94 0 : std::ostringstream str;
95 0 : str << val;
96 0 : return str.str();
97 0 : }
98 :
99 0 : std::string ServicesSandesh::IntToHexString(uint32_t val) {
100 0 : std::ostringstream str;
101 0 : str << "0x" << std::hex << val;
102 0 : return str.str();
103 0 : }
104 :
105 0 : void ServicesSandesh::PktToHexString(uint8_t *pkt, int32_t len,
106 : std::string &msg) {
107 0 : for (int32_t i = 0; i < len; i++) {
108 : char val[4];
109 0 : snprintf(val, 4, "%02x ", pkt[i]);
110 0 : msg.append(val);
111 : }
112 0 : }
113 :
114 0 : std::string ServicesSandesh::IpProtocol(uint16_t prot) {
115 0 : std::map<uint16_t, std::string>::iterator it = g_ip_protocol_map.find(prot);
116 0 : if (it == g_ip_protocol_map.end()) {
117 0 : return IntToString(prot);
118 : }
119 0 : return it->second;
120 : }
121 :
122 0 : std::string &ServicesSandesh::DhcpMsgType(uint32_t msg_type) {
123 0 : std::map<uint32_t, std::string>::iterator it = g_dhcp_msg_types.find(msg_type);
124 0 : if (it == g_dhcp_msg_types.end())
125 0 : return DhcpMsgType(DHCP_UNKNOWN);
126 0 : return it->second;
127 : }
128 :
129 0 : std::string &ServicesSandesh::Dhcpv6MsgType(uint32_t msg_type) {
130 0 : std::map<uint32_t, std::string>::iterator it = g_dhcpv6_msg_types.find(msg_type);
131 0 : if (it == g_dhcpv6_msg_types.end())
132 0 : return Dhcpv6MsgType(DHCPV6_OPTION_UNKNOWN);
133 0 : return it->second;
134 : }
135 :
136 0 : void ServicesSandesh::PktStatsSandesh(std::string ctxt, bool more) {
137 0 : PktStats *resp = new PktStats();
138 0 : const PktHandler::PktStats &stats = Agent::GetInstance()->pkt()->pkt_handler()->GetStats();
139 0 : uint32_t total_rcvd = 0;
140 0 : uint32_t total_sent = 0;
141 0 : for (int i = 0; i < PktHandler::MAX_MODULES; ++i) {
142 0 : total_rcvd += stats.received[i];
143 0 : total_sent += stats.sent[i];
144 : }
145 0 : resp->set_total_rcvd(total_rcvd);
146 0 : resp->set_dhcp_rcvd(stats.received[PktHandler::DHCP]);
147 0 : resp->set_arp_rcvd(stats.received[PktHandler::ARP]);
148 0 : resp->set_dns_rcvd(stats.received[PktHandler::DNS]);
149 0 : resp->set_icmp_rcvd(stats.received[PktHandler::ICMP]);
150 0 : resp->set_flow_rcvd(stats.received[PktHandler::FLOW]);
151 0 : resp->set_mac_learning_msg_rcvd(stats.received[PktHandler::MAC_LEARNING]);
152 0 : resp->set_dropped(stats.dropped);
153 0 : resp->set_total_sent(total_sent);
154 0 : resp->set_dhcp_sent(stats.sent[PktHandler::DHCP]);
155 0 : resp->set_arp_sent(stats.sent[PktHandler::ARP]);
156 0 : resp->set_dns_sent(stats.sent[PktHandler::DNS]);
157 0 : resp->set_icmp_sent(stats.sent[PktHandler::ICMP]);
158 0 : resp->set_dhcp_q_threshold_exceeded(stats.q_threshold_exceeded[PktHandler::DHCP]);
159 0 : resp->set_arp_q_threshold_exceeded(stats.q_threshold_exceeded[PktHandler::ARP]);
160 0 : resp->set_dns_q_threshold_exceeded(stats.q_threshold_exceeded[PktHandler::DNS]);
161 0 : resp->set_icmp_q_threshold_exceeded(stats.q_threshold_exceeded[PktHandler::ICMP]);
162 0 : resp->set_flow_q_threshold_exceeded(stats.q_threshold_exceeded[PktHandler::FLOW]);
163 0 : resp->set_context(ctxt);
164 0 : resp->set_more(more);
165 0 : resp->Response();
166 0 : }
167 :
168 0 : void ServicesSandesh::DhcpStatsSandesh(std::string ctxt, bool more) {
169 0 : DhcpStats *dhcp = new DhcpStats();
170 : const DhcpProto::DhcpStats &dstats =
171 0 : Agent::GetInstance()->GetDhcpProto()->GetStats();
172 0 : dhcp->set_dhcp_discover(dstats.discover);
173 0 : dhcp->set_dhcp_request(dstats.request);
174 0 : dhcp->set_dhcp_inform(dstats.inform);
175 0 : dhcp->set_dhcp_decline(dstats.decline);
176 0 : dhcp->set_dhcp_other(dstats.other);
177 0 : dhcp->set_dhcp_errors(dstats.errors);
178 0 : dhcp->set_offers_sent(dstats.offers);
179 0 : dhcp->set_acks_sent(dstats.acks);
180 0 : dhcp->set_nacks_sent(dstats.nacks);
181 0 : dhcp->set_relay_request(dstats.relay_req);
182 0 : dhcp->set_relay_response(dstats.relay_resp);
183 0 : dhcp->set_unknown_msg_drop(dstats.unknown_msg_drop);
184 0 : dhcp->set_dhcp_disabled_drop(dstats.dhcp_disabled_drop);
185 0 : dhcp->set_incorrect_mac(dstats.incorrect_mac);
186 0 : dhcp->set_context(ctxt);
187 0 : dhcp->set_more(more);
188 0 : dhcp->Response();
189 0 : }
190 :
191 0 : void ServicesSandesh::Dhcpv6StatsSandesh(std::string ctxt, bool more) {
192 0 : Dhcpv6Stats *dhcp = new Dhcpv6Stats();
193 : const Dhcpv6Proto::DhcpStats &dstats =
194 0 : Agent::GetInstance()->dhcpv6_proto()->GetStats();
195 0 : dhcp->set_dhcp_solicit(dstats.solicit);
196 0 : dhcp->set_dhcp_advertise(dstats.advertise);
197 0 : dhcp->set_dhcp_request(dstats.request);
198 0 : dhcp->set_dhcp_confirm(dstats.confirm);
199 0 : dhcp->set_dhcp_renew(dstats.renew);
200 0 : dhcp->set_dhcp_rebind(dstats.rebind);
201 0 : dhcp->set_dhcp_reply(dstats.reply);
202 0 : dhcp->set_dhcp_release(dstats.release);
203 0 : dhcp->set_dhcp_decline(dstats.decline);
204 0 : dhcp->set_dhcp_reconfigure(dstats.reconfigure);
205 0 : dhcp->set_information_request(dstats.information_request);
206 0 : dhcp->set_dhcp_error(dstats.error);
207 0 : dhcp->set_context(ctxt);
208 0 : dhcp->set_more(more);
209 0 : dhcp->Response();
210 0 : }
211 :
212 0 : void ServicesSandesh::ArpStatsSandesh(std::string ctxt, bool more) {
213 0 : ArpProto *arp_proto = Agent::GetInstance()->GetArpProto();
214 0 : ArpStats *arp = new ArpStats();
215 0 : const ArpProto::ArpStats &astats = arp_proto->GetStats();
216 0 : arp->set_arp_entries(arp_proto->GetArpCacheSize());
217 0 : arp->set_arp_requests(astats.arp_req);
218 0 : arp->set_arp_replies(astats.arp_replies);
219 0 : arp->set_arp_gratuitous(astats.arp_gratuitous);
220 0 : arp->set_arp_resolved(astats.resolved);
221 0 : arp->set_arp_max_retries_exceeded(astats.max_retries_exceeded);
222 0 : arp->set_arp_errors(astats.errors);
223 0 : arp->set_arp_invalid_packets(astats.arp_invalid_packets);
224 0 : arp->set_arp_invalid_interface(astats.arp_invalid_interface);
225 0 : arp->set_arp_invalid_vrf(astats.arp_invalid_vrf);
226 0 : arp->set_arp_invalid_address(astats.arp_invalid_address);
227 0 : arp->set_context(ctxt);
228 0 : arp->set_more(more);
229 0 : arp->Response();
230 0 : }
231 :
232 0 : void ServicesSandesh::BfdStatsSandesh(std::string ctxt, bool more) {
233 0 : BfdProto *bfd_proto = Agent::GetInstance()->GetBfdProto();
234 0 : BfdStats *bfd = new BfdStats();
235 0 : const BfdProto::BfdStats &stats = bfd_proto->GetStats();
236 0 : bfd->set_bfd_sent(stats.bfd_sent);
237 0 : bfd->set_bfd_received(stats.bfd_received);
238 0 : bfd->set_bfd_receive_drop_count(stats.bfd_rx_drop_count);
239 0 : bfd->set_bfd_receive_ka_enqueue_count(stats.bfd_rx_ka_enqueue_count);
240 0 : bfd->set_bfd_active_sessions(bfd_proto->ActiveSessions());
241 :
242 : std::vector<BfdSandeshSessions> &bfd_list =
243 0 : const_cast<std::vector<BfdSandeshSessions>&>(bfd->get_bfd_sessions());
244 0 : BFD::Server *server = bfd_proto->bfd_communicator().GetServer();
245 0 : BFD::Sessions *sessions = server->GetSessions();
246 0 : BFD::Sessions::iterator it = sessions->begin();
247 0 : while (it != sessions->end()) {
248 0 : BFD::SessionKey key = *it;
249 0 : BfdSandeshSessions session;
250 0 : session.local_address = key.local_address.to_string();
251 0 : session.remote_address = key.remote_address.to_string();
252 0 : session.index = key.index.to_string();
253 0 : session.remote_port = key.remote_port;
254 :
255 0 : BFD::Session *bfd_session = server->SessionByKey(key);
256 0 : std::ostringstream ss, rem_ss;
257 0 : ss << bfd_session->local_state();
258 0 : session.local_status = ss.str();
259 0 : rem_ss << bfd_session->remote_state().state;
260 0 : session.remote_status = rem_ss.str();
261 :
262 0 : session.stats.rx_count = bfd_session->Stats().rx_count;
263 0 : session.stats.tx_count = bfd_session->Stats().tx_count;
264 0 : session.stats.rx_error_count = bfd_session->Stats().rx_error_count;
265 0 : session.stats.tx_error_count = bfd_session->Stats().tx_error_count;
266 0 : session.stats.receive_timer_expired_count =
267 0 : bfd_session->Stats().receive_timer_expired_count;
268 0 : session.stats.send_timer_expired_count =
269 0 : bfd_session->Stats().send_timer_expired_count;
270 :
271 0 : bfd_list.push_back(session);
272 0 : it++;
273 0 : }
274 :
275 0 : bfd->set_context(ctxt);
276 0 : bfd->set_more(more);
277 0 : bfd->Response();
278 0 : }
279 :
280 0 : void ServicesSandesh::DnsStatsSandesh(std::string ctxt, bool more) {
281 0 : DnsStats *dns = new DnsStats();
282 0 : const DnsProto::DnsStats &nstats = Agent::GetInstance()->GetDnsProto()->GetStats();
283 0 : uint8_t count = 0;
284 : std::vector<string> &list =
285 0 : const_cast<std::vector<string>&>(dns->get_dns_resolver());
286 :
287 0 : std::vector<string>dns_servers;
288 0 : uint8_t resolver_count = Agent::GetInstance()->GetDnslist().size();
289 0 : while (count < resolver_count) {
290 0 : boost::split(dns_servers, Agent::GetInstance()->GetDnslist()[count],
291 0 : boost::is_any_of(":"));
292 0 : list.push_back(dns_servers[0]);
293 0 : count++;
294 : }
295 :
296 0 : BindResolver *resolv = BindResolver::Resolver();
297 0 : uint16_t dscp = 0;
298 0 : if (resolv) {
299 0 : dscp = resolv->GetDscpValue();
300 : }
301 0 : dns->set_dscp(dscp);
302 :
303 0 : dns->set_dns_requests(nstats.requests);
304 0 : dns->set_dns_resolved(nstats.resolved);
305 0 : dns->set_dns_retransmit_reqs(nstats.retransmit_reqs);
306 0 : dns->set_dns_unsupported(nstats.unsupported);
307 0 : dns->set_dns_failures(nstats.fail);
308 0 : dns->set_dns_drops(nstats.drop);
309 0 : dns->set_context(ctxt);
310 0 : dns->set_more(more);
311 0 : dns->Response();
312 0 : }
313 :
314 0 : void ServicesSandesh::IcmpStatsSandesh(std::string ctxt, bool more) {
315 0 : IcmpStats *icmp = new IcmpStats();
316 0 : const IcmpProto::IcmpStats &istats = Agent::GetInstance()->GetIcmpProto()->GetStats();
317 0 : icmp->set_icmp_gw_ping(istats.icmp_gw_ping);
318 0 : icmp->set_icmp_gw_ping_err(istats.icmp_gw_ping_err);
319 0 : icmp->set_icmp_drop(istats.icmp_drop);
320 0 : icmp->set_context(ctxt);
321 0 : icmp->set_more(more);
322 0 : icmp->Response();
323 0 : }
324 :
325 0 : void ServicesSandesh::Icmpv6StatsSandesh(std::string ctxt, bool more) {
326 0 : Icmpv6Stats *icmp = new Icmpv6Stats();
327 : const Icmpv6Proto::Icmpv6Stats &istats =
328 0 : Agent::GetInstance()->icmpv6_proto()->GetStats();
329 0 : icmp->set_icmpv6_router_solicit(istats.icmpv6_router_solicit_);
330 0 : icmp->set_icmpv6_router_advert(istats.icmpv6_router_advert_);
331 0 : icmp->set_icmpv6_ping_request(istats.icmpv6_ping_request_);
332 0 : icmp->set_icmpv6_ping_response(istats.icmpv6_ping_response_);
333 0 : icmp->set_icmpv6_drop(istats.icmpv6_drop_);
334 0 : icmp->set_icmpv6_neighbor_solicit(istats.icmpv6_neighbor_solicit_);
335 0 : icmp->set_icmpv6_neighbor_solicited(istats.icmpv6_neighbor_solicited_);
336 : icmp->set_icmpv6_neighbor_advert_solicited
337 0 : (istats.icmpv6_neighbor_advert_solicited_);
338 : icmp->set_icmpv6_neighbor_advert_unsolicited
339 0 : (istats.icmpv6_neighbor_advert_unsolicited_);
340 0 : icmp->set_context(ctxt);
341 0 : icmp->set_more(more);
342 0 : icmp->Response();
343 0 : }
344 :
345 0 : void ServicesSandesh::IgmpStatsSandesh(std::string ctxt, bool more) {
346 0 : IgmpStatsResponse *igmp = new IgmpStatsResponse();
347 0 : const IgmpProto::IgmpStats &istats = Agent::GetInstance()->GetIgmpProto()->GetStats();
348 0 : igmp->set_bad_length(istats.bad_length);
349 0 : igmp->set_bad_cksum(istats.bad_cksum);
350 0 : igmp->set_bad_interface(istats.bad_interface);
351 0 : igmp->set_not_local(istats.not_local);
352 0 : igmp->set_rx_unknown(istats.rx_unknown);
353 0 : igmp->set_rejected_pkt(istats.rejected_pkt);
354 0 : igmp->set_context(ctxt);
355 0 : igmp->set_more(more);
356 0 : igmp->Response();
357 0 : }
358 :
359 0 : void ServicesSandesh::FillPktData(PktTrace::Pkt &pkt, PktData &resp) {
360 0 : switch (pkt.dir) {
361 0 : case PktTrace::In:
362 0 : resp.direction = "in";
363 0 : break;
364 0 : case PktTrace::Out:
365 0 : resp.direction = "out";
366 0 : break;
367 0 : default:
368 0 : resp.direction = "error";
369 0 : break;
370 : }
371 0 : resp.len = pkt.len;
372 0 : }
373 :
374 0 : uint16_t ServicesSandesh::FillVrouterHdr(PktTrace::Pkt &pkt, VrouterHdr &resp) {
375 : boost::array<std::string, MAX_AGENT_HDR_COMMANDS> commands =
376 : { { "switch", "route", "arp", "l2-protocol", "trap-nexthop",
377 : "trap-resolve", "trap-flow-miss", "trap-l3-protocol",
378 : "trap-diag", "trap-ecmp-resolve", "trap_source_mismatch",
379 : "trap-dont-fragment", "trap-zero-ttl", "tor-control",
380 : "trap-icmp-error", "trap-flow-hold-action",
381 0 : "trap-route-alert", "trap-mac-learn", "trap-mac-move" } };
382 0 : uint8_t *ptr = pkt.pkt;
383 0 : AgentHdr *hdr = reinterpret_cast<AgentHdr *>(ptr);
384 0 : resp.ifindex = hdr->ifindex;
385 0 : resp.vrf = hdr->vrf;
386 0 : uint16_t cmd = hdr->cmd;
387 0 : if (cmd < MAX_AGENT_HDR_COMMANDS)
388 0 : resp.cmd = commands.at(cmd);
389 : else
390 0 : resp.cmd = "unknown";
391 0 : resp.cmd_param = hdr->cmd_param;
392 0 : resp.nh = hdr->nh;
393 0 : return sizeof(AgentHdr);
394 0 : }
395 :
396 0 : int ServicesSandesh::FillMacHdr(struct ether_header *eth, MacHdr &resp) {
397 0 : int len = sizeof(struct ether_header);
398 0 : MacToString(eth->ether_dhost, resp.dest_mac);
399 0 : MacToString(eth->ether_shost, resp.src_mac);
400 0 : uint16_t type = ntohs(eth->ether_type);
401 0 : uint8_t *ptr = (uint8_t *)eth + 12;
402 0 : while (type == ETHERTYPE_VLAN) {
403 0 : len += 4;
404 0 : ptr += 4;
405 0 : type = ntohs(*(uint16_t *)ptr);
406 : }
407 0 : resp.type = (type == 0x800) ? "ip" :
408 0 : (type == 0x806) ? "arp" : IntToString(type);
409 0 : return len;
410 : }
411 :
412 0 : static uint32_t get_val(void *data) {
413 : union {
414 : uint8_t data[sizeof(uint32_t)];
415 : uint32_t addr;
416 : } bytes;
417 0 : memcpy(bytes.data, data, sizeof(uint32_t));
418 0 : return ntohl(bytes.addr);
419 : }
420 :
421 0 : void ServicesSandesh::FillArpHdr(ether_arp *arp, ArpHdr &resp) {
422 0 : uint16_t val = ntohs(arp->arp_hrd);
423 0 : resp.htype = (val == 1) ? "ethernet" : IntToString(val);
424 0 : val = ntohs(arp->arp_pro);
425 0 : resp.protocol = (val == 0x800) ? "ip" : IntToString(val);
426 0 : resp.hw_size = arp->arp_hln;
427 0 : resp.prot_size = arp->arp_pln;
428 0 : val = ntohs(arp->arp_op);
429 0 : resp.opcode = (val == 1) ? "request" :
430 0 : (val == 2) ? "response" : IntToString(val);
431 0 : MacToString(arp->arp_sha, resp.sender_mac);
432 0 : MacToString(arp->arp_tha, resp.target_mac);
433 0 : Ip4Address spa(get_val(arp->arp_spa));
434 0 : Ip4Address tpa(get_val(arp->arp_tpa));
435 0 : resp.sender_ip = spa.to_string();
436 0 : resp.target_ip = tpa.to_string();
437 0 : }
438 :
439 0 : void ServicesSandesh::FillIpv4Hdr(struct ip *ip, Ipv4Hdr &resp) {
440 0 : resp.vers = ip->ip_v;
441 0 : resp.hdrlen = ip->ip_hl;
442 0 : resp.tos = ip->ip_tos;
443 0 : resp.len = ntohs(ip->ip_len);
444 0 : resp.id = IntToHexString(ntohs(ip->ip_id));
445 0 : resp.frag = IntToHexString(ntohs(ip->ip_off));
446 0 : resp.ttl = ip->ip_ttl;
447 0 : resp.protocol = IpProtocol(ip->ip_p);
448 0 : resp.csum = IntToHexString(ntohs(ip->ip_sum));
449 0 : Ip4Address sa(ntohl(ip->ip_src.s_addr));
450 0 : Ip4Address da(ntohl(ip->ip_dst.s_addr));
451 0 : resp.src_ip = sa.to_string();
452 0 : resp.dest_ip = da.to_string();
453 0 : }
454 :
455 0 : void ServicesSandesh::FillIpv6Hdr(ip6_hdr *ip, Ipv6Hdr &resp) {
456 0 : resp.flow = ntohl(ip->ip6_flow);
457 0 : resp.plen = ntohs(ip->ip6_plen);
458 0 : resp.next_hdr = ip->ip6_nxt;
459 0 : resp.hlim = ip->ip6_hlim;
460 :
461 0 : boost::system::error_code ec;
462 : boost::asio::ip::address_v6::bytes_type src_addr;
463 0 : memcpy(&src_addr[0], ip->ip6_src.s6_addr, 16);
464 0 : boost::asio::ip::address_v6 src(src_addr);
465 0 : resp.src_ip = src.to_string(ec);
466 :
467 : boost::asio::ip::address_v6::bytes_type dest_addr;
468 0 : memcpy(&dest_addr[0], ip->ip6_dst.s6_addr, 16);
469 0 : boost::asio::ip::address_v6 dest(dest_addr);
470 0 : resp.dest_ip = dest.to_string(ec);
471 0 : }
472 :
473 0 : void ServicesSandesh::FillIcmpv4Hdr(struct icmp *icmp, Icmpv4Hdr &resp) {
474 0 : resp.type = (icmp->icmp_type == ICMP_ECHO) ? "echo request":
475 0 : (icmp->icmp_type == ICMP_ECHOREPLY) ? "echo reply" :
476 0 : IntToString(icmp->icmp_type);
477 0 : resp.code = icmp->icmp_code;
478 0 : resp.csum = IntToHexString(ntohs(icmp->icmp_cksum));
479 0 : }
480 :
481 0 : void ServicesSandesh::FillIcmpv6Hdr(icmp6_hdr *icmp, Icmpv6Hdr &resp,
482 : int32_t len) {
483 0 : switch (icmp->icmp6_type) {
484 0 : case ICMP6_ECHO_REQUEST:
485 0 : resp.type = "echo request";
486 0 : break;
487 :
488 0 : case ICMP6_ECHO_REPLY:
489 0 : resp.type = "echo reply";
490 0 : break;
491 :
492 0 : case ND_ROUTER_SOLICIT:
493 0 : resp.type = "router solicit";
494 0 : break;
495 :
496 0 : case ND_ROUTER_ADVERT:
497 0 : resp.type = "router advertisement";
498 0 : break;
499 :
500 0 : default:
501 0 : resp.type = IntToString(icmp->icmp6_type);
502 0 : break;
503 : }
504 0 : resp.code = icmp->icmp6_code;
505 0 : resp.csum = IntToHexString(ntohs(icmp->icmp6_cksum));
506 0 : PktToHexString((uint8_t *)icmp->icmp6_data8, len - 4, resp.rest);
507 0 : }
508 :
509 0 : void ServicesSandesh::FillUdpHdr(udphdr *udp, UdpHdr &resp) {
510 0 : resp.src_port = ntohs(udp->uh_sport);
511 0 : resp.dest_port = ntohs(udp->uh_dport);
512 0 : resp.length = ntohs(udp->uh_ulen);
513 0 : resp.csum = IntToHexString(ntohs(udp->uh_sum));
514 0 : }
515 :
516 : std::string
517 0 : ServicesSandesh::FillOptionString(char *data, int32_t len, std::string msg) {
518 0 : std::string str;
519 0 : if (len > 0)
520 0 : str.assign(data, len);
521 0 : return (msg + str + "; ");
522 0 : }
523 :
524 : std::string
525 0 : ServicesSandesh::FillOptionInteger(uint32_t data, std::string msg) {
526 0 : std::stringstream str;
527 0 : str << msg << data << "; ";
528 0 : return str.str();
529 0 : }
530 :
531 : std::string
532 0 : ServicesSandesh::FillOptionIp(uint32_t data, std::string msg) {
533 0 : Ip4Address addr(data);
534 0 : return msg + addr.to_string() + "; ";
535 : }
536 :
537 : void
538 0 : ServicesSandesh::FillHostRoutes(uint8_t *data, int len,
539 : std::string &resp) {
540 0 : std::stringstream routes;
541 0 : int parsed = 0;
542 0 : uint8_t *ptr = data;
543 0 : while (parsed < len) {
544 0 : uint32_t addr = 0;
545 0 : int plen = *ptr++;
546 0 : parsed++;
547 : int j;
548 0 : for (j = 0; plen && j <= (plen - 1) / 8; ++j) {
549 0 : addr = (addr << 8) | *ptr++;
550 0 : parsed++;
551 : }
552 0 : addr = addr << (4 - j) * 8;
553 0 : Ip4Address prefix(addr);
554 0 : Ip4Address route(get_val(ptr));
555 0 : routes << prefix.to_string() << "/" << plen << " -> "
556 0 : << route.to_string() << ";";
557 0 : ptr += 4;
558 0 : parsed += 4;
559 : }
560 0 : resp += routes.str();
561 0 : }
562 :
563 0 : void ServicesSandesh::FillDhcpv4Options(Dhcpv4Options *opt, std::string &resp,
564 : std::string &other, int32_t len) {
565 0 : while (opt->code != DHCP_OPTION_END && len > 0) {
566 0 : switch (opt->code) {
567 0 : case DHCP_OPTION_PAD:
568 0 : len -= 1;
569 0 : opt = (Dhcpv4Options *)((uint8_t *)opt + 1);
570 0 : continue;
571 :
572 0 : case DHCP_OPTION_MSG_TYPE:
573 0 : if (len >= (2 + opt->len))
574 0 : resp += DhcpMsgType(*(uint8_t *)opt->data) + "; ";
575 0 : break;
576 :
577 0 : case DHCP_OPTION_REQ_IP_ADDRESS: {
578 0 : if (len >= (2 + opt->len)) {
579 0 : Ip4Address addr(get_val(opt->data));
580 0 : resp += "Requested IP : " + addr.to_string() + "; ";
581 : }
582 0 : break;
583 : }
584 :
585 0 : case DHCP_OPTION_HOST_NAME:
586 0 : if (len >= (2 + opt->len))
587 0 : resp += FillOptionString((char *)opt->data, opt->len,
588 0 : "Host Name : ");
589 0 : break;
590 :
591 0 : case DHCP_OPTION_DOMAIN_NAME:
592 0 : if (len >= (2 + opt->len))
593 0 : resp += FillOptionString((char *)opt->data, opt->len,
594 0 : "Domain Name : ");
595 0 : break;
596 :
597 0 : case DHCP_OPTION_MESSAGE:
598 0 : if (len >= (2 + opt->len))
599 0 : resp += FillOptionString((char *)opt->data, opt->len,
600 0 : "Msg : ");
601 0 : break;
602 :
603 0 : case DHCP_OPTION_IP_LEASE_TIME:
604 0 : if (len >= (2 + opt->len))
605 0 : resp += FillOptionInteger(get_val(opt->data), "Lease time : ");
606 0 : break;
607 :
608 0 : case DHCP_OPTION_SUBNET_MASK:
609 0 : if (len >= (2 + opt->len))
610 0 : resp += FillOptionIp(get_val(opt->data), "Subnet mask : ");
611 0 : break;
612 :
613 0 : case DHCP_OPTION_BCAST_ADDRESS:
614 0 : if (len >= (2 + opt->len))
615 0 : resp += FillOptionIp(get_val(opt->data), "Broadcast : ");
616 0 : break;
617 :
618 0 : case DHCP_OPTION_ROUTER:
619 0 : if (len >= (2 + opt->len)) {
620 0 : int16_t optlen = 0;
621 0 : while (optlen < opt->len) {
622 0 : resp += FillOptionIp(get_val(opt->data + optlen),
623 0 : "Gateway : ");
624 0 : optlen += 4;
625 : }
626 : }
627 0 : break;
628 :
629 0 : case DHCP_OPTION_DNS:
630 0 : if (len >= (2 + opt->len))
631 0 : resp += FillOptionIp(get_val(opt->data), "DNS : ");
632 0 : break;
633 :
634 0 : case DHCP_OPTION_TIME_SERVER:
635 0 : if (len >= (2 + opt->len))
636 0 : resp += FillOptionIp(get_val(opt->data), "Time Server : ");
637 0 : break;
638 :
639 0 : case DHCP_OPTION_SERVER_IDENTIFIER:
640 0 : if (len >= (2 + opt->len))
641 0 : resp += FillOptionIp(get_val(opt->data), "Server : ");
642 0 : break;
643 :
644 0 : case DHCP_OPTION_CLASSLESS_ROUTE:
645 0 : if (len >= (2 + opt->len)) {
646 0 : resp += "Host Routes : ";
647 0 : FillHostRoutes(opt->data, opt->len, resp);
648 : }
649 0 : break;
650 :
651 0 : default:
652 0 : PktToHexString((uint8_t *)opt, opt->len + 2, other);
653 0 : break;
654 0 : }
655 0 : len -= (2 + opt->len);
656 0 : opt = (Dhcpv4Options *)((uint8_t *)opt + 2 + opt->len);
657 : }
658 0 : }
659 :
660 0 : void ServicesSandesh::FillDhcpv4Hdr(dhcphdr *dhcp, Dhcpv4Hdr &resp,
661 : int32_t len) {
662 0 : resp.op = (dhcp->op == 1) ? "request" : "reply";
663 0 : resp.htype = (dhcp->htype == 1) ? "ethernet" : IntToString(dhcp->htype);
664 0 : resp.hlen = dhcp->hlen;
665 0 : resp.hops = dhcp->hops;
666 0 : resp.xid = IntToHexString(dhcp->xid);
667 0 : resp.secs = ntohs(dhcp->secs);
668 : resp.flags =
669 0 : (ntohs(dhcp->flags) & DHCP_BCAST_FLAG) ? "broadcast" : "unicast";
670 0 : Ip4Address ciaddr(ntohl(dhcp->ciaddr));
671 0 : Ip4Address yiaddr(ntohl(dhcp->yiaddr));
672 0 : Ip4Address siaddr(ntohl(dhcp->siaddr));
673 0 : Ip4Address giaddr(ntohl(dhcp->giaddr));
674 0 : resp.ciaddr = ciaddr.to_string();
675 0 : resp.yiaddr = yiaddr.to_string();
676 0 : resp.siaddr = siaddr.to_string();
677 0 : resp.giaddr = giaddr.to_string();
678 0 : PktToHexString(dhcp->chaddr, DHCP_CHADDR_LEN, resp.chaddr);
679 0 : PktToHexString(dhcp->sname, DHCP_NAME_LEN, resp.sname);
680 0 : PktToHexString(dhcp->file, DHCP_FILE_LEN, resp.file);
681 0 : PktToHexString(dhcp->options, 4, resp.cookie);
682 0 : len -= (DHCP_FIXED_LEN + 4);
683 0 : FillDhcpv4Options((Dhcpv4Options *)(dhcp->options + 4),
684 0 : resp.dhcp_options, resp.other_options, len);
685 0 : }
686 :
687 0 : void ServicesSandesh::FillDhcpv6Hdr(Dhcpv6Hdr *dhcp, Dhcpv6Header &resp,
688 : int32_t len) {
689 0 : resp.type = Dhcpv6MsgType(dhcp->type);
690 0 : PktToHexString(dhcp->xid, 3, resp.xid);
691 0 : PktToHexString((uint8_t *)dhcp + DHCPV6_FIXED_LEN, len - 4, resp.options);
692 0 : }
693 :
694 0 : void ServicesSandesh::FillDnsHdr(dnshdr *dns, DnsHdr &resp, int32_t dnslen) {
695 0 : if (dnslen < (int32_t)sizeof(dnshdr))
696 0 : return;
697 :
698 0 : resp.xid = ntohs(dns->xid);
699 0 : if (dns->flags.rd)
700 0 : resp.flags += "recursion desired; ";
701 0 : if (dns->flags.trunc)
702 0 : resp.flags += "truncated; ";
703 0 : if (dns->flags.auth)
704 0 : resp.flags += "authoritative answer; ";
705 0 : resp.flags += (!dns->flags.op) ? "query; " :
706 0 : ((dns->flags.op == DNS_OPCODE_UPDATE)? "update; " :
707 0 : "other op; ");
708 0 : if (dns->flags.req) {
709 0 : resp.flags += "response; ";
710 0 : if (dns->flags.ret)
711 0 : resp.flags += "failure response : " +
712 0 : IntToString(dns->flags.ret) + "; ";
713 : else
714 0 : resp.flags += "success response; ";
715 : } else {
716 0 : resp.flags += "request; ";
717 : }
718 0 : if (dns->flags.cd)
719 0 : resp.flags += "checking disabled; ";
720 0 : if (dns->flags.ad)
721 0 : resp.flags += "answer authenticated; ";
722 0 : if (dns->flags.ra)
723 0 : resp.flags += "recursion available; ";
724 0 : resp.ques = ntohs(dns->ques_rrcount);
725 0 : resp.ans = ntohs(dns->ans_rrcount);
726 0 : resp.auth = ntohs(dns->auth_rrcount);
727 0 : resp.add = ntohs(dns->add_rrcount);
728 0 : dnslen -= sizeof(dnshdr);
729 0 : ServicesSandesh::PktToHexString((uint8_t *)(dns + 1), dnslen, resp.rest);
730 : }
731 :
732 0 : void ServicesSandesh::ArpPktTrace(PktTrace::Pkt &pkt, ArpPktSandesh *resp) {
733 0 : ArpPkt data;
734 0 : FillPktData(pkt, data.info);
735 0 : uint16_t hdr_len = FillVrouterHdr(pkt, data.agent_hdr);
736 0 : uint8_t *ptr = pkt.pkt + hdr_len;
737 0 : ptr += FillMacHdr((struct ether_header *)ptr, data.mac_hdr);
738 0 : FillArpHdr((ether_arp *)ptr, data.arp_hdr);
739 : std::vector<ArpPkt> &list =
740 0 : const_cast<std::vector<ArpPkt>&>(resp->get_pkt_list());
741 0 : list.push_back(data);
742 0 : }
743 :
744 0 : void ServicesSandesh::DhcpPktTrace(PktTrace::Pkt &pkt, DhcpPktSandesh *resp) {
745 0 : DhcpPkt data;
746 0 : FillPktData(pkt, data.info);
747 0 : uint16_t hdr_len = FillVrouterHdr(pkt, data.agent_hdr);
748 0 : uint8_t *ptr = pkt.pkt + hdr_len;
749 0 : ptr += FillMacHdr((struct ether_header *)ptr, data.mac_hdr);
750 0 : FillIpv4Hdr((struct ip *)ptr, data.ip_hdr);
751 0 : ptr += (data.ip_hdr.hdrlen * 4);
752 0 : FillUdpHdr((udphdr *)ptr, data.udp_hdr);
753 0 : ptr += sizeof(udphdr);
754 0 : PktHandler *pkt_handler = Agent::GetInstance()->pkt()->pkt_handler();
755 0 : std::size_t trace_size = pkt_handler->PktTraceSize(PktHandler::DHCP);
756 0 : int32_t remaining = std::min(pkt.len, trace_size) -
757 : (sizeof(struct ether_header) +
758 0 : data.ip_hdr.hdrlen * 4 + sizeof(udphdr));
759 0 : FillDhcpv4Hdr((dhcphdr *)ptr, data.dhcp_hdr, remaining);
760 : std::vector<DhcpPkt> &list =
761 0 : const_cast<std::vector<DhcpPkt>&>(resp->get_pkt_list());
762 0 : list.push_back(data);
763 0 : }
764 :
765 0 : void ServicesSandesh::Dhcpv6PktTrace(PktTrace::Pkt &pkt, Dhcpv6PktSandesh *resp) {
766 0 : Dhcpv6Pkt data;
767 0 : FillPktData(pkt, data.info);
768 0 : uint16_t hdr_len = FillVrouterHdr(pkt, data.agent_hdr);
769 0 : uint8_t *ptr = pkt.pkt + hdr_len;
770 0 : ptr += FillMacHdr((struct ether_header *)ptr, data.mac_hdr);
771 0 : FillIpv6Hdr((ip6_hdr *)ptr, data.ip_hdr);
772 0 : ptr += sizeof(ip6_hdr);
773 0 : FillUdpHdr((udphdr *)ptr, data.udp_hdr);
774 0 : ptr += sizeof(udphdr);
775 0 : PktHandler *pkt_handler = Agent::GetInstance()->pkt()->pkt_handler();
776 0 : std::size_t trace_size = pkt_handler->PktTraceSize(PktHandler::DHCPV6);
777 0 : int32_t remaining = std::min(pkt.len, trace_size) -
778 0 : (sizeof(struct ether_header) + sizeof(ip6_hdr) + sizeof(udphdr));
779 0 : FillDhcpv6Hdr((Dhcpv6Hdr *)ptr, data.dhcp_hdr, remaining);
780 : std::vector<Dhcpv6Pkt> &list =
781 0 : const_cast<std::vector<Dhcpv6Pkt>&>(resp->get_pkt_list());
782 0 : list.push_back(data);
783 0 : }
784 :
785 0 : void ServicesSandesh::DnsPktTrace(PktTrace::Pkt &pkt, DnsPktSandesh *resp) {
786 0 : DnsPkt data;
787 0 : FillPktData(pkt, data.info);
788 0 : uint16_t hdr_len = FillVrouterHdr(pkt, data.agent_hdr);
789 0 : uint8_t *ptr = pkt.pkt + hdr_len;
790 0 : ptr += FillMacHdr((struct ether_header *)ptr, data.mac_hdr);
791 0 : FillIpv4Hdr((struct ip *)ptr, data.ip_hdr);
792 0 : ptr += (data.ip_hdr.hdrlen * 4);
793 0 : FillUdpHdr((udphdr *)ptr, data.udp_hdr);
794 0 : ptr += sizeof(udphdr);
795 0 : PktHandler *pkt_handler = Agent::GetInstance()->pkt()->pkt_handler();
796 0 : std::size_t trace_size = pkt_handler->PktTraceSize(PktHandler::DNS);
797 0 : int32_t remaining = std::min(pkt.len, trace_size) -
798 : (sizeof(struct ether_header) +
799 0 : data.ip_hdr.hdrlen * 4 + sizeof(udphdr));
800 0 : FillDnsHdr((dnshdr *)ptr, data.dns_hdr, remaining);
801 : std::vector<DnsPkt> &list =
802 0 : const_cast<std::vector<DnsPkt>&>(resp->get_pkt_list());
803 0 : list.push_back(data);
804 0 : }
805 :
806 0 : void ServicesSandesh::IcmpPktTrace(PktTrace::Pkt &pkt, IcmpPktSandesh *resp) {
807 0 : IcmpPkt data;
808 0 : FillPktData(pkt, data.info);
809 0 : uint16_t hdr_len = FillVrouterHdr(pkt, data.agent_hdr);
810 0 : uint8_t *ptr = pkt.pkt + hdr_len;
811 0 : ptr += FillMacHdr((struct ether_header *)ptr, data.mac_hdr);
812 0 : FillIpv4Hdr((struct ip *)ptr, data.ip_hdr);
813 0 : ptr += (data.ip_hdr.hdrlen * 4);
814 0 : FillIcmpv4Hdr((struct icmp *)ptr, data.icmp_hdr);
815 : std::vector<IcmpPkt> &list =
816 0 : const_cast<std::vector<IcmpPkt>&>(resp->get_pkt_list());
817 0 : list.push_back(data);
818 0 : }
819 :
820 0 : void ServicesSandesh::Icmpv6PktTrace(PktTrace::Pkt &pkt, Icmpv6PktSandesh *resp) {
821 0 : Icmpv6Pkt data;
822 0 : FillPktData(pkt, data.info);
823 0 : uint16_t hdr_len = FillVrouterHdr(pkt, data.agent_hdr);
824 0 : uint8_t *ptr = pkt.pkt + hdr_len;
825 0 : ptr += FillMacHdr((struct ether_header *)ptr, data.mac_hdr);
826 0 : FillIpv6Hdr((ip6_hdr *)ptr, data.ip_hdr);
827 0 : ptr += sizeof(ip6_hdr);
828 0 : PktHandler *pkt_handler = Agent::GetInstance()->pkt()->pkt_handler();
829 0 : std::size_t trace_size = pkt_handler->PktTraceSize(PktHandler::ICMPV6);
830 0 : int32_t remaining = std::min(pkt.len, trace_size) -
831 0 : (sizeof(struct ether_header) + sizeof(ip6_hdr));
832 0 : FillIcmpv6Hdr((icmp6_hdr *)ptr, data.icmp_hdr, remaining);
833 : std::vector<Icmpv6Pkt> &list =
834 0 : const_cast<std::vector<Icmpv6Pkt>&>(resp->get_pkt_list());
835 0 : list.push_back(data);
836 0 : }
837 :
838 0 : void ServicesSandesh::OtherPktTrace(PktTrace::Pkt &pkt, PktSandesh *resp) {
839 0 : PktDump data;
840 0 : FillPktData(pkt, data.info);
841 0 : uint16_t hdr_len = FillVrouterHdr(pkt, data.agent_hdr);
842 0 : uint8_t *ptr = pkt.pkt + hdr_len;
843 0 : ptr += FillMacHdr((struct ether_header *)ptr, data.mac_hdr);
844 0 : PktHandler *pkt_handler = Agent::GetInstance()->pkt()->pkt_handler();
845 0 : std::size_t trace_size = pkt_handler->PktTraceSize(PktHandler::FLOW);
846 0 : int32_t remaining = std::min(pkt.len, trace_size) - sizeof(struct ether_header);
847 0 : PktToHexString(ptr, remaining, data.pkt);
848 : std::vector<PktDump> &list =
849 0 : const_cast<std::vector<PktDump>&>(resp->get_pkt_list());
850 0 : list.push_back(data);
851 0 : }
852 :
853 0 : void ServicesSandesh::HandleRequest(PktHandler::PktModuleName mod,
854 : std::string ctxt, bool more = false) {
855 0 : SandeshResponse *resp = NULL;
856 0 : boost::function<void(PktTrace::Pkt &)> cb;
857 : boost::array<std::string, PktHandler::MAX_MODULES> names =
858 : { { "Invalid", "Flow", "Arp", "Dhcp", "Dhcpv6", "Dns",
859 : "Icmp", "Icmpv6", "Diagnostics", "IcmpError", "RxPacket",
860 0 : "MacLearning" } };
861 :
862 0 : switch (mod) {
863 0 : case PktHandler::ARP:
864 0 : resp = new ArpPktSandesh();
865 0 : ArpStatsSandesh(ctxt, true);
866 0 : static_cast<ArpPktSandesh *>(resp)->set_type(names.at(mod));
867 : cb = boost::bind(&ServicesSandesh::ArpPktTrace, this, _1,
868 0 : static_cast<ArpPktSandesh *>(resp));
869 0 : break;
870 :
871 0 : case PktHandler::BFD:
872 0 : BfdStatsSandesh(ctxt, false);
873 0 : return;
874 :
875 0 : case PktHandler::DHCP:
876 0 : resp = new DhcpPktSandesh();
877 0 : DhcpStatsSandesh(ctxt, true);
878 0 : static_cast<DhcpPktSandesh *>(resp)->set_type(names.at(mod));
879 : cb = boost::bind(&ServicesSandesh::DhcpPktTrace, this, _1,
880 0 : static_cast<DhcpPktSandesh *>(resp));
881 0 : break;
882 :
883 0 : case PktHandler::DHCPV6:
884 0 : resp = new Dhcpv6PktSandesh();
885 0 : Dhcpv6StatsSandesh(ctxt, true);
886 0 : static_cast<Dhcpv6PktSandesh *>(resp)->set_type(names.at(mod));
887 : cb = boost::bind(&ServicesSandesh::Dhcpv6PktTrace, this, _1,
888 0 : static_cast<Dhcpv6PktSandesh *>(resp));
889 0 : break;
890 :
891 0 : case PktHandler::DNS:
892 0 : resp = new DnsPktSandesh();
893 0 : DnsStatsSandesh(ctxt, true);
894 0 : static_cast<DnsPktSandesh *>(resp)->set_type(names.at(mod));
895 : cb = boost::bind(&ServicesSandesh::DnsPktTrace, this, _1,
896 0 : static_cast<DnsPktSandesh *>(resp));
897 0 : break;
898 :
899 0 : case PktHandler::ICMP:
900 0 : resp = new IcmpPktSandesh();
901 0 : IcmpStatsSandesh(ctxt, true);
902 0 : static_cast<IcmpPktSandesh *>(resp)->set_type(names.at(mod));
903 : cb = boost::bind(&ServicesSandesh::IcmpPktTrace, this, _1,
904 0 : static_cast<IcmpPktSandesh *>(resp));
905 0 : break;
906 :
907 0 : case PktHandler::ICMPV6:
908 0 : resp = new Icmpv6PktSandesh();
909 0 : Icmpv6StatsSandesh(ctxt, true);
910 0 : static_cast<Icmpv6PktSandesh *>(resp)->set_type(names.at(mod));
911 : cb = boost::bind(&ServicesSandesh::Icmpv6PktTrace, this, _1,
912 0 : static_cast<Icmpv6PktSandesh *>(resp));
913 0 : break;
914 :
915 0 : case PktHandler::IGMP:
916 0 : IgmpStatsSandesh(ctxt, false);
917 0 : return;
918 :
919 0 : case PktHandler::FLOW:
920 : case PktHandler::DIAG:
921 : case PktHandler::INVALID:
922 : case PktHandler::MAC_LEARNING:
923 0 : resp = new PktSandesh();
924 0 : static_cast<PktSandesh *>(resp)->set_type(names.at(mod));
925 : cb = boost::bind(&ServicesSandesh::OtherPktTrace, this, _1,
926 0 : static_cast<PktSandesh *>(resp));
927 0 : break;
928 :
929 0 : default:
930 0 : break;
931 : }
932 :
933 0 : Agent::GetInstance()->pkt()->pkt_handler()->PktTraceIterate(mod, cb);
934 0 : resp->set_context(ctxt);
935 0 : resp->set_more(more);
936 0 : resp->Response();
937 0 : }
938 :
939 0 : void ServicesSandesh::MetadataHandleRequest(std::string ctxt, bool more = false) {
940 0 : MetadataResponse *resp = new MetadataResponse();
941 0 : resp->set_metadata_server_port(
942 0 : Agent::GetInstance()->metadata_server_port());
943 : const MetadataProxy::MetadataStats &stats =
944 0 : Agent::GetInstance()->services()->metadataproxy()->metadatastats();
945 0 : resp->set_metadata_requests(stats.requests);
946 0 : resp->set_metadata_responses(stats.responses);
947 0 : resp->set_metadata_proxy_sessions(stats.proxy_sessions);
948 0 : resp->set_metadata_internal_errors(stats.internal_errors);
949 0 : resp->set_context(ctxt);
950 0 : resp->set_more(more);
951 0 : resp->Response();
952 0 : }
953 :
954 : ///////////////////////////////////////////////////////////////////////////////
955 :
956 0 : void DhcpInfo::HandleRequest() const {
957 0 : ServicesSandesh ssandesh;
958 0 : ssandesh.HandleRequest(PktHandler::DHCP, context());
959 0 : }
960 :
961 0 : void Dhcpv6Info::HandleRequest() const {
962 0 : ServicesSandesh ssandesh;
963 0 : ssandesh.HandleRequest(PktHandler::DHCPV6, context());
964 0 : }
965 :
966 0 : void ArpInfo::HandleRequest() const {
967 0 : ServicesSandesh ssandesh;
968 0 : ssandesh.HandleRequest(PktHandler::ARP, context());
969 0 : }
970 :
971 0 : void BfdInfo::HandleRequest() const {
972 0 : ServicesSandesh ssandesh;
973 0 : ssandesh.HandleRequest(PktHandler::BFD, context());
974 0 : }
975 :
976 0 : void DnsInfo::HandleRequest() const {
977 0 : ServicesSandesh ssandesh;
978 0 : ssandesh.HandleRequest(PktHandler::DNS, context());
979 0 : }
980 :
981 0 : void IcmpInfo::HandleRequest() const {
982 0 : ServicesSandesh ssandesh;
983 0 : ssandesh.HandleRequest(PktHandler::ICMP, context());
984 0 : }
985 :
986 0 : void Icmpv6Info::HandleRequest() const {
987 0 : ServicesSandesh ssandesh;
988 0 : ssandesh.HandleRequest(PktHandler::ICMPV6, context());
989 0 : }
990 :
991 0 : void IgmpStatsReq::HandleRequest() const {
992 0 : ServicesSandesh ssandesh;
993 0 : ssandesh.HandleRequest(PktHandler::IGMP, context());
994 0 : }
995 :
996 0 : void GmpStatsReq::HandleRequest() const {
997 0 : GmpStatsResponse *gmp = new GmpStatsResponse();
998 0 : GmpProto *gmp_proto_ = Agent::GetInstance()->GetIgmpProto()->GetGmpProto();
999 0 : const GmpProto::GmpStats &stats = gmp_proto_->GetStats();
1000 0 : gmp->set_gmp_g_add_count(stats.gmp_g_add_count_);
1001 0 : gmp->set_gmp_g_del_count(stats.gmp_g_del_count_);
1002 0 : gmp->set_gmp_sg_add_count(stats.gmp_sg_add_count_);
1003 0 : gmp->set_gmp_sg_del_count(stats.gmp_sg_del_count_);
1004 0 : gmp->set_context(context());
1005 0 : gmp->set_more(false);
1006 0 : gmp->Response();
1007 0 : }
1008 :
1009 0 : static void SandeshError(const std::string msg, const std::string &context) {
1010 0 : IgmpErrorResp *resp = new IgmpErrorResp();
1011 0 : resp->set_resp(msg);
1012 0 : resp->set_context(context);
1013 0 : resp->set_more(false);
1014 0 : resp->Response();
1015 0 : }
1016 :
1017 0 : void InterfaceIgmpStatsReq::HandleRequest() const {
1018 0 : std::string vn_uuid = get_vn_uuid();
1019 0 : std::string gw = get_ipam_gateway();
1020 0 : InterfaceIgmpStatsResponse *igmp = new InterfaceIgmpStatsResponse();
1021 0 : IgmpStats rx_badpacket_stats;
1022 0 : IgmpStats rx_okpacket_stats;
1023 0 : IgmpInfo::IgmpItfStats stats;
1024 :
1025 0 : if (vn_uuid.empty() || gw.empty()) {
1026 0 : SandeshError("Empty vn_uuid or gateway !!", context());
1027 0 : return;
1028 : }
1029 :
1030 : VnEntry *vn =
1031 0 : Agent::GetInstance()->vn_table()->Find(StringToUuid(vn_uuid));
1032 0 : if (!vn ) {
1033 0 : SandeshError("Invalid UUID !!", context());
1034 0 : return;
1035 : }
1036 :
1037 0 : boost::system::error_code ec;
1038 0 : IpAddress gateway = IpAddress(Ip4Address::from_string(gw, ec));
1039 0 : if (Agent::GetInstance()->GetIgmpProto()->GetItfStats(vn, gateway,
1040 0 : stats) == false ) {
1041 0 : SandeshError("Stats not found !!", context());
1042 0 : return;
1043 : }
1044 :
1045 0 : igmp->set_rx_unknown(stats.rx_unknown);
1046 0 : igmp->set_tx_packet(stats.tx_packet);
1047 0 : igmp->set_tx_drop_packet(stats.tx_drop_packet);
1048 :
1049 0 : rx_badpacket_stats.undefined =
1050 0 : stats.rx_badpacket[IGMP_UNDEFINED - 1];
1051 0 : rx_badpacket_stats.igmp_membership_query =
1052 0 : stats.rx_badpacket[IGMP_MEMBERSHIP_QUERY - 1];
1053 0 : rx_badpacket_stats.igmp_v1_membership_report =
1054 0 : stats.rx_badpacket[IGMP_V1_MEMBERSHIP_REPORT - 1];
1055 0 : rx_badpacket_stats.igmp_proto_dvmrp =
1056 0 : stats.rx_badpacket[IGMP_PROTO_DVMRP - 1];
1057 0 : rx_badpacket_stats.igmp_proto_pim =
1058 0 : stats.rx_badpacket[IGMP_PROTO_PIM - 1];
1059 0 : rx_badpacket_stats.igmp_cisco_trace =
1060 0 : stats.rx_badpacket[IGMP_CISCO_TRACE - 1];
1061 0 : rx_badpacket_stats.igmp_v2_membership_report =
1062 0 : stats.rx_badpacket[IGMP_V2_MEMBERSHIP_REPORT - 1];
1063 0 : rx_badpacket_stats.igmp_group_leave =
1064 0 : stats.rx_badpacket[IGMP_GROUP_LEAVE - 1];
1065 0 : rx_badpacket_stats.igmp_mtrace_response =
1066 0 : stats.rx_badpacket[IGMP_MTRACE_RESPONSE - 1];
1067 0 : rx_badpacket_stats.igmp_mtrace_request =
1068 0 : stats.rx_badpacket[IGMP_MTRACE_REQUEST - 1];
1069 0 : rx_badpacket_stats.igmp_dwr =
1070 0 : stats.rx_badpacket[IGMP_DWR - 1];
1071 0 : rx_badpacket_stats.igmp_v3_membership_report =
1072 0 : stats.rx_badpacket[IGMP_V3_MEMBERSHIP_REPORT - 1];
1073 0 : igmp->set_rx_badpacket_stats(rx_badpacket_stats);
1074 :
1075 0 : rx_okpacket_stats.undefined =
1076 0 : stats.rx_okpacket[IGMP_UNDEFINED - 1];
1077 0 : rx_okpacket_stats.igmp_membership_query =
1078 0 : stats.rx_okpacket[IGMP_MEMBERSHIP_QUERY - 1];
1079 0 : rx_okpacket_stats.igmp_v1_membership_report =
1080 0 : stats.rx_okpacket[IGMP_V1_MEMBERSHIP_REPORT - 1];
1081 0 : rx_okpacket_stats.igmp_proto_dvmrp =
1082 0 : stats.rx_okpacket[IGMP_PROTO_DVMRP - 1];
1083 0 : rx_okpacket_stats.igmp_proto_pim =
1084 0 : stats.rx_okpacket[IGMP_PROTO_PIM - 1];
1085 0 : rx_okpacket_stats.igmp_cisco_trace =
1086 0 : stats.rx_okpacket[IGMP_CISCO_TRACE - 1];
1087 0 : rx_okpacket_stats.igmp_v2_membership_report =
1088 0 : stats.rx_okpacket[IGMP_V2_MEMBERSHIP_REPORT - 1];
1089 0 : rx_okpacket_stats.igmp_group_leave =
1090 0 : stats.rx_okpacket[IGMP_GROUP_LEAVE - 1];
1091 0 : rx_okpacket_stats.igmp_mtrace_response =
1092 0 : stats.rx_okpacket[IGMP_MTRACE_RESPONSE - 1];
1093 0 : rx_okpacket_stats.igmp_mtrace_request =
1094 0 : stats.rx_okpacket[IGMP_MTRACE_REQUEST - 1];
1095 0 : rx_okpacket_stats.igmp_dwr =
1096 0 : stats.rx_okpacket[IGMP_DWR - 1];
1097 0 : rx_okpacket_stats.igmp_v3_membership_report =
1098 0 : stats.rx_okpacket[IGMP_V3_MEMBERSHIP_REPORT - 1];
1099 0 : igmp->set_rx_okpacket_stats(rx_okpacket_stats);
1100 :
1101 0 : igmp->set_context(context());
1102 0 : igmp->Response();
1103 0 : }
1104 :
1105 0 : void MetadataInfo::HandleRequest() const {
1106 0 : ServicesSandesh ssandesh;
1107 0 : ssandesh.MetadataHandleRequest(context());
1108 0 : }
1109 :
1110 0 : void MacLearningInfo::HandleRequest() const {
1111 0 : ServicesSandesh ssandesh;
1112 0 : ssandesh.HandleRequest(PktHandler::MAC_LEARNING, context());
1113 0 : }
1114 :
1115 0 : void ShowAllInfo::HandleRequest() const {
1116 0 : ServicesSandesh ssandesh;
1117 0 : ssandesh.PktStatsSandesh(context(), true);
1118 0 : ssandesh.HandleRequest(PktHandler::DHCP, context(), true);
1119 0 : ssandesh.HandleRequest(PktHandler::ARP, context(), true);
1120 0 : ssandesh.HandleRequest(PktHandler::DNS, context(), true);
1121 0 : ssandesh.HandleRequest(PktHandler::ICMP, context(), true);
1122 0 : ssandesh.HandleRequest(PktHandler::FLOW, context(), true);
1123 0 : ssandesh.HandleRequest(PktHandler::DIAG, context(), true);
1124 0 : ssandesh.HandleRequest(PktHandler::INVALID, context(), true);
1125 0 : ssandesh.HandleRequest(PktHandler::MAC_LEARNING, context(), true);
1126 0 : ssandesh.MetadataHandleRequest(context(), false);
1127 0 : }
1128 :
1129 0 : void ClearAllInfo::HandleRequest() const {
1130 0 : Agent *agent = Agent::GetInstance();
1131 0 : PktHandler *pkt_handler = agent->pkt()->pkt_handler();
1132 0 : pkt_handler->PktTraceClear(PktHandler::DHCP);
1133 0 : pkt_handler->PktTraceClear(PktHandler::DHCPV6);
1134 0 : pkt_handler->PktTraceClear(PktHandler::ARP);
1135 0 : pkt_handler->PktTraceClear(PktHandler::DNS);
1136 0 : pkt_handler->PktTraceClear(PktHandler::ICMP);
1137 0 : pkt_handler->PktTraceClear(PktHandler::ICMPV6);
1138 0 : pkt_handler->PktTraceClear(PktHandler::FLOW);
1139 0 : pkt_handler->PktTraceClear(PktHandler::DIAG);
1140 0 : pkt_handler->PktTraceClear(PktHandler::INVALID);
1141 0 : pkt_handler->PktTraceClear(PktHandler::MAC_LEARNING);
1142 0 : pkt_handler->ClearStats();
1143 0 : agent->GetDhcpProto()->ClearStats();
1144 0 : agent->dhcpv6_proto()->ClearStats();
1145 0 : agent->GetArpProto()->ClearStats();
1146 0 : agent->GetDnsProto()->ClearStats();
1147 0 : agent->GetIcmpProto()->ClearStats();
1148 0 : agent->icmpv6_proto()->ClearStats();
1149 0 : agent->services()->metadataproxy()->ClearStats();
1150 :
1151 0 : PktErrorResp *resp = new PktErrorResp();
1152 0 : resp->set_context(context());
1153 0 : resp->Response();
1154 0 : }
1155 :
1156 0 : void PktTraceInfo::HandleRequest() const {
1157 0 : uint32_t buffers = get_num_buffers();
1158 0 : uint32_t flow_buffers = get_flow_num_buffers();
1159 0 : PktTraceInfoResponse *resp = new PktTraceInfoResponse();
1160 0 : PktHandler *handler = Agent::GetInstance()->pkt()->pkt_handler();
1161 0 : if (buffers > PktTrace::kPktMaxNumBuffers ||
1162 : flow_buffers > PktTrace::kPktMaxNumBuffers) {
1163 0 : resp->set_resp("Invalid Input !!");
1164 0 : buffers = handler->PktTraceBuffers(PktHandler::INVALID);
1165 0 : flow_buffers = handler->PktTraceBuffers(PktHandler::FLOW);
1166 : } else {
1167 0 : handler->PktTraceBuffers(PktHandler::FLOW, flow_buffers);
1168 0 : for (uint32_t i = 0; i < PktHandler::MAX_MODULES; ++i) {
1169 0 : if (i == PktHandler::FLOW)
1170 0 : continue;
1171 0 : handler->PktTraceBuffers((PktHandler::PktModuleName)i, buffers);
1172 : }
1173 : }
1174 0 : resp->set_num_buffers(buffers);
1175 0 : resp->set_flow_num_buffers(flow_buffers);
1176 0 : resp->set_context(context());
1177 0 : resp->Response();
1178 0 : }
1179 :
1180 : ///////////////////////////////////////////////////////////////////////////////
1181 :
1182 0 : void ShowDnsEntries::HandleRequest() const {
1183 0 : AgentDnsEntries *resp = new AgentDnsEntries();
1184 0 : std::vector<VmDnsSandesh> dns_list;
1185 : const DnsProto::DnsUpdateSet &dns_update_set =
1186 0 : Agent::GetInstance()->GetDnsProto()->update_set();
1187 0 : for (DnsProto::DnsUpdateSet::const_iterator it = dns_update_set.begin();
1188 0 : it != dns_update_set.end(); ++it) {
1189 0 : VmDnsSandesh vmdata;
1190 0 : vmdata.vm = (*it)->itf->name();
1191 0 : vmdata.is_floating = ((*it)->floatingIp ? "yes" : "no");
1192 0 : if ((*it)->xmpp_data) {
1193 0 : vmdata.virtual_dns = (*it)->xmpp_data->virtual_dns;
1194 0 : vmdata.zone = (*it)->xmpp_data->zone;
1195 0 : for (DnsItems::iterator item = (*it)->xmpp_data->items.begin();
1196 0 : item != (*it)->xmpp_data->items.end(); ++item) {
1197 0 : VmDnsRecord record;
1198 0 : record.name = (*item).name;
1199 0 : record.type = BindUtil::DnsType((*item).type);
1200 0 : record.data = (*item).data;
1201 0 : record.ttl = (*item).ttl;
1202 0 : record.eclass = BindUtil::DnsClass((*item).eclass);
1203 0 : vmdata.records.push_back(record);
1204 0 : }
1205 : }
1206 0 : dns_list.push_back(vmdata);
1207 0 : }
1208 0 : resp->set_dns_list(dns_list);
1209 0 : resp->set_context(context());
1210 0 : resp->Response();
1211 0 : }
1212 :
1213 0 : void VmVdnsListReq::HandleRequest() const {
1214 0 : VmVdnsListResponse *resp = new VmVdnsListResponse();
1215 0 : resp->set_context(context());
1216 :
1217 0 : const DnsProto::VmDataMap& vm_list = Agent::GetInstance()->GetDnsProto()->all_vms();
1218 : std::vector<VmVdnsListEntry> &list =
1219 0 : const_cast<std::vector<VmVdnsListEntry>&>(resp->get_rlist());
1220 0 : DnsProto::VmDataMap::const_iterator it = vm_list.begin();
1221 0 : while (it != vm_list.end()) {
1222 0 : const VmInterface *itf = it->first;
1223 0 : VmVdnsListEntry entry;
1224 0 : entry.set_name(itf->name());
1225 0 : entry.set_vm_interface_index(itf->id());
1226 0 : list.push_back(entry);
1227 0 : ++it;
1228 0 : }
1229 0 : resp->Response();
1230 0 : }
1231 :
1232 0 : void VmVdnsDataReq::HandleRequest() const {
1233 0 : VmVdnsDataResponse *resp = new VmVdnsDataResponse();
1234 0 : resp->set_context(context());
1235 :
1236 0 : Agent *agent = Agent::GetInstance();
1237 : const VmInterface *vmi = static_cast<const VmInterface *>
1238 0 : (agent->interface_table()->FindInterface(get_vm_interface_index()));
1239 0 : if (vmi == NULL) {
1240 0 : resp->Response();
1241 0 : return;
1242 : }
1243 0 : const DnsProto::VmDataMap& all_vms = agent->GetDnsProto()->all_vms();
1244 0 : DnsProto::VmDataMap::const_iterator it = all_vms.find(vmi);
1245 0 : if (it == all_vms.end()) {
1246 0 : resp->Response();
1247 0 : return;
1248 : }
1249 0 : const DnsProto::IpVdnsMap &ip_list = it->second;
1250 0 : DnsProto::IpVdnsMap::const_iterator ip_it = ip_list.begin();
1251 : std::vector<VmVdnsDataEntry> &list =
1252 0 : const_cast<std::vector<VmVdnsDataEntry>&>(resp->get_rlist());
1253 0 : while (ip_it != ip_list.end()) {
1254 0 : VmVdnsDataEntry entry;
1255 0 : Ip4Address ip4(ip_it->first);
1256 0 : entry.set_ip(ip4.to_string());
1257 0 : entry.set_vdns_name(ip_it->second);
1258 0 : list.push_back(entry);
1259 0 : ++ip_it;
1260 0 : }
1261 0 : resp->Response();
1262 : }
1263 :
1264 0 : void FipVdnsDataReq::HandleRequest() const {
1265 0 : FipVdnsDataResponse *resp = new FipVdnsDataResponse();
1266 0 : resp->set_context(context());
1267 : const DnsProto::DnsFipSet& fip_list = Agent::GetInstance()->GetDnsProto()
1268 0 : ->fip_list();
1269 : std::vector<FipVdnsEntry> &list =
1270 0 : const_cast<std::vector<FipVdnsEntry>&>(resp->get_rlist());
1271 0 : DnsProto::DnsFipSet::const_iterator it = fip_list.begin();
1272 0 : while (it != fip_list.end()) {
1273 0 : FipVdnsEntry entry;
1274 0 : const DnsProto::DnsFipEntry *fip = (*it).get();
1275 0 : IpAddress ip(fip->floating_ip_);
1276 0 : entry.set_vn(fip->vn_->GetName());
1277 0 : entry.set_ip(ip.to_string());
1278 0 : entry.set_vm_interface(fip->interface_->name());
1279 0 : entry.set_vdns_name(fip->vdns_name_);
1280 0 : list.push_back(entry);
1281 0 : ++it;
1282 0 : }
1283 :
1284 0 : resp->Response();
1285 0 : }
1286 :
1287 : ///////////////////////////////////////////////////////////////////////////////
1288 :
1289 0 : void ShowArpCache::HandleRequest() const {
1290 0 : ArpCacheResp *resp = new ArpCacheResp();
1291 0 : resp->set_context(context());
1292 0 : ArpSandesh *arp_sandesh = new ArpSandesh(resp);
1293 : const ArpProto::ArpCache &cache =
1294 0 : (Agent::GetInstance()->GetArpProto()->arp_cache());
1295 0 : for (ArpProto::ArpCache::const_iterator it = cache.begin();
1296 0 : it != cache.end(); it++) {
1297 0 : if (!arp_sandesh->SetArpEntry(it->first, it->second))
1298 0 : break;
1299 : }
1300 0 : arp_sandesh->Response();
1301 0 : delete arp_sandesh;
1302 0 : }
1303 :
1304 0 : void ShowGratuitousArpCache::HandleRequest() const {
1305 0 : ArpCacheResp *resp = new ArpCacheResp();
1306 0 : resp->set_context(context());
1307 0 : ArpSandesh *arp_sandesh = new ArpSandesh(resp);
1308 : const ArpProto::GratuitousArpCache &cache =
1309 0 : (Agent::GetInstance()->GetArpProto()->gratuitous_arp_cache());
1310 0 : for (ArpProto::GratuitousArpCache::const_iterator it = cache.begin();
1311 0 : it != cache.end(); it++) {
1312 0 : for (ArpProto::ArpEntrySet::iterator sit = it->second.begin();
1313 0 : sit != it->second.end(); sit++) {
1314 0 : arp_sandesh->SetArpEntry(it->first, *sit);
1315 : }
1316 : }
1317 :
1318 0 : arp_sandesh->Response();
1319 0 : delete arp_sandesh;
1320 0 : }
1321 :
1322 0 : bool ArpSandesh::SetArpEntry(const ArpKey &key, const ArpEntry *entry) {
1323 0 : ArpCacheResp *vresp = static_cast<ArpCacheResp *>(resp_);
1324 0 : ArpSandeshData data;
1325 0 : boost::asio::ip::address_v4 ip(key.ip);
1326 0 : data.set_ip(ip.to_string());
1327 0 : data.set_vrf(key.vrf->GetName());
1328 0 : if (entry->get_interface())
1329 0 : data.set_interface_name(entry->get_interface()->name());
1330 0 : std::string mac_str;
1331 0 : ServicesSandesh::MacToString(entry->mac_address(), mac_str);
1332 0 : data.set_mac(mac_str);
1333 0 : switch (entry->state()) {
1334 0 : case ArpEntry::INITING:
1335 0 : data.set_state("initing");
1336 0 : break;
1337 0 : case ArpEntry::RESOLVING:
1338 0 : data.set_state("resolving");
1339 0 : break;
1340 0 : case ArpEntry::ACTIVE:
1341 0 : data.set_state("active");
1342 0 : break;
1343 0 : case ArpEntry::RERESOLVING:
1344 0 : data.set_state("re-resolving");
1345 0 : break;
1346 : }
1347 :
1348 : std::vector<ArpSandeshData> &list =
1349 0 : const_cast<std::vector<ArpSandeshData>&>(vresp->get_arp_list());
1350 0 : list.push_back(data);
1351 0 : iter_++;
1352 0 : if (!(iter_ % ArpSandesh::entries_per_sandesh)) {
1353 : // send partial sandesh
1354 0 : ArpCacheResp *resp = new ArpCacheResp();
1355 0 : resp->set_context(resp_->context());
1356 0 : resp_->set_context(resp_->context());
1357 0 : resp_->set_more(true);
1358 0 : resp_->Response();
1359 0 : resp_ = resp;
1360 : }
1361 0 : return true;
1362 0 : }
1363 :
1364 0 : void ArpSandesh::SetInterfaceArpStatsEntry(
1365 : ArpProto::InterfaceArpMap::const_iterator &it,
1366 : std::vector<InterfaceArpStats> &list) {
1367 0 : InterfaceArpStats data;
1368 0 : data.set_interface_index(it->first);
1369 0 : data.set_arp_requests(it->second.stats.arp_req);
1370 0 : data.set_arp_replies(it->second.stats.arp_replies);
1371 0 : data.set_arp_resolved(it->second.stats.resolved);
1372 0 : list.push_back(data);
1373 0 : }
1374 :
1375 0 : void InterfaceArpStatsReq::HandleRequest() const {
1376 0 : InterfaceArpStatsResponse *resp = new InterfaceArpStatsResponse();
1377 0 : resp->set_context(context());
1378 0 : ArpSandesh arp_sandesh(resp);
1379 : const ArpProto::InterfaceArpMap &imap =
1380 0 : (Agent::GetInstance()->GetArpProto()->interface_arp_map());
1381 : std::vector<InterfaceArpStats> &list =
1382 0 : const_cast<std::vector<InterfaceArpStats>&>(resp->get_stats_list());
1383 0 : if (get_interface_index() != -1) {
1384 : ArpProto::InterfaceArpMap::const_iterator it = imap.find
1385 0 : (get_interface_index());
1386 0 : if (it != imap.end()) {
1387 0 : arp_sandesh.SetInterfaceArpStatsEntry(it, list);
1388 : }
1389 0 : arp_sandesh.Response();
1390 0 : return;
1391 : }
1392 0 : for (ArpProto::InterfaceArpMap::const_iterator it = imap.begin();
1393 0 : it != imap.end(); it++) {
1394 0 : arp_sandesh.SetInterfaceArpStatsEntry(it, list);
1395 : }
1396 0 : arp_sandesh.Response();
1397 : }
1398 :
1399 0 : void InterfaceIcmpv6StatsReq::HandleRequest() const {
1400 0 : Agent * agent = Agent::GetInstance();
1401 0 : InterfaceIcmpv6StatsResponse *resp = new InterfaceIcmpv6StatsResponse();
1402 0 : resp->set_context(context());
1403 : const Icmpv6Proto::VmInterfaceMap &imap =
1404 0 : (agent->icmpv6_proto()->vm_interfaces());
1405 : std::vector<InterfaceIcmpv6Stats> &list =
1406 0 : const_cast<std::vector<InterfaceIcmpv6Stats>&>(resp->get_stats_list());
1407 0 : if (get_interface_index() != -1) {
1408 : VmInterface *vm_intf = static_cast<VmInterface *>(
1409 0 : agent->interface_table()->FindInterface(get_interface_index()));
1410 0 : if (vm_intf) {
1411 0 : Icmpv6Proto::VmInterfaceMap::const_iterator it = imap.find(vm_intf);
1412 0 : if (it != imap.end()) {
1413 0 : SET_ICMPV6_INTERFACE_STATS(it, list);
1414 0 : }
1415 : }
1416 : } else {
1417 0 : for (Icmpv6Proto::VmInterfaceMap::const_iterator it = imap.begin();
1418 0 : it != imap.end(); it++) {
1419 0 : SET_ICMPV6_INTERFACE_STATS(it, list);
1420 0 : }
1421 : }
1422 0 : resp->Response();
1423 0 : }
|