ring_tx: handle EINTR from sendto
[netsniff-ng-new.git] / proto_ethernet.c
blobbd84accf00e005dc87f67ced64366926e4086fb9
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Copyright 2014 Tobias Klauser
5 * Subject to the GPL, version 2.
6 */
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <netinet/in.h>
11 #include <linux/if_ether.h>
13 #include "proto.h"
14 #include "dissector_eth.h"
15 #include "lookup.h"
16 #include "pkt_buff.h"
18 static inline bool is_multicast_ether_addr(const uint8_t *mac)
20 return mac[0] & 0x01;
23 static inline bool is_broadcast_ether_addr(const uint8_t *mac)
25 return (mac[0] & mac[1] & mac[2] & mac[3] & mac[4] & mac[5]) == 0xff;
28 static inline bool is_local_ether_addr(const u8 *mac)
30 return 0x02 & mac[0];
33 static const char *ether_lookup_addr(const uint8_t *mac)
35 if (is_multicast_ether_addr(mac)) {
36 if (is_broadcast_ether_addr(mac))
37 return "Broadcast";
38 else
39 return "Multicast";
40 } else if (is_local_ether_addr(mac)) {
41 return "Locally Administered";
44 /* found no matching address, so look up the vendor from OUI */
45 return lookup_vendor_str((mac[0] << 16) | (mac[1] << 8) | mac[2]);
48 static void ethernet(struct pkt_buff *pkt)
50 const char *type;
51 uint8_t *src_mac, *dst_mac;
52 struct ethhdr *eth = (struct ethhdr *) pkt_pull(pkt, sizeof(*eth));
54 if (eth == NULL)
55 return;
57 src_mac = eth->h_source;
58 dst_mac = eth->h_dest;
60 tprintf(" [ Eth ");
61 tprintf("MAC (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x => ",
62 src_mac[0], src_mac[1], src_mac[2],
63 src_mac[3], src_mac[4], src_mac[5]);
64 tprintf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x), ",
65 dst_mac[0], dst_mac[1], dst_mac[2],
66 dst_mac[3], dst_mac[4], dst_mac[5]);
67 tprintf("Proto (0x%.4x", ntohs(eth->h_proto));
69 type = lookup_ether_type(ntohs(eth->h_proto));
70 if (type)
71 tprintf(", %s%s%s", colorize_start(bold), type, colorize_end());
73 tprintf(") ]\n");
74 tprintf(" [ Vendor ");
75 tprintf("(%s => %s)", ether_lookup_addr(src_mac), ether_lookup_addr(dst_mac));
76 tprintf(" ]\n");
78 pkt_set_dissector(pkt, &eth_lay2, ntohs(eth->h_proto));
81 static void ethernet_less(struct pkt_buff *pkt)
83 uint8_t *src_mac, *dst_mac;
84 struct ethhdr *eth = (struct ethhdr *) pkt_pull(pkt, sizeof(*eth));
86 if (eth == NULL)
87 return;
89 src_mac = eth->h_source;
90 dst_mac = eth->h_dest;
91 tprintf(" %s => %s ", ether_lookup_addr(src_mac),
92 ether_lookup_addr(dst_mac));
93 tprintf("%s%s%s", colorize_start(bold),
94 lookup_ether_type(ntohs(eth->h_proto)), colorize_end());
96 pkt_set_dissector(pkt, &eth_lay2, ntohs(eth->h_proto));
99 struct protocol ethernet_ops = {
100 .key = 0,
101 .print_full = ethernet,
102 .print_less = ethernet_less,