180 likes | 505 Views
Datalink Access. Datalink Access . Provides access to the datalink layer for an application Capabilities Ability to watch the packets received by the datalink layer Run certain programs as applications instead of kernel. Ex: RARP. Access Methods . 3 common methods
E N D
Datalink Access • Provides access to the datalink layer for an application • Capabilities • Ability to watch the packets received by the datalink layer • Run certain programs as applications instead of kernel. Ex: RARP
Access Methods • 3 common methods • BSD Packet Filter (BPF) • SVR4 Datalink Provider Interface (DLPI) • Linux SOCK_PACKET interface • Libpcap library • Publicly available packet capture library • Works with all the above three methods. • Writing programs with this makes them OS independent
BSD Packet Filter (BPF) • Each datalink driver calls BPF • right before a packet is transmitted • Right after a packet is received • Filter capability • Each application opens BPF device • Can load its own filter • Applied by BPF to each packet • Filter can be as detailed as “only TCP segments to or from 80, only SYN, FIN or RST
BSD Packet Filter (BPF) • Three techniques to reduce overhead: • Filters within kernel. Avoids data copy into user appl. • Only a portion of each packet is copied. (14+40+20+22=96 bytes) • BPF buffers the data. It is copied to appl buffer only when full or read timeout expires.
Datalink Provider Interface (DLPI) • Similar to BPF • Differences: • Filter implementation in BPF is 3 to 20 times faster than DLPI. Directed acyclic control flow graph an boolean expression tree. • BPF always make the filtering decision before copying the packet. DLPI may first copy the packet to pfmod and then make the decision.
Linux • Two methods: • Socket of type:SOCK_PACKET • Socket of family: PF_PACKET • Third argument must specify the frame type. • PF_PACKET: • Type is SOCK_RAW to receive complete link layer packet. • Socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
Linux • Differences with BPF and DLPI: • Provides no kernel buffering. Filtering is avaialble only with PF_PACKET. • Multiple frames can’t be buffered together. So it increase no. of sys calls.
libpcap • Provides implementation independent access to the underlying packet capture facility.
Libpcap example int main(intargc, char *argv[]) { pcap_t *handle; /* Session handle */ char *dev; /* The device to sniff on */ char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */ structbpf_programfp; /* The compiled filter */ char filter_exp[] = "port 23"; /* The filter expression */ bpf_u_int32 mask; /* Our netmask */ bpf_u_int32 net; /* Our IP */ structpcap_pkthdr header; /* The header that pcap gives us */ const u_char *packet; /* The actual packet */ /* Define the device */ dev = pcap_lookupdev(errbuf); if (dev == NULL) { fprintf(stderr, "Couldn't find default device: %s\n", errbuf); return(2); }
Libpcap example[1] /* Find the properties for the device */ if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf); net = 0; mask = 0; } /* Open the session in promiscuous mode */ handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf); if (handle == NULL) { fprintf(stderr, "Couldn't open device %s: %s\n", somedev, errbuf); return(2); } /* Compile and apply the filter */ if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); return(2); }
Libpcap example[2] if (pcap_setfilter(handle, &fp) == -1) { fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle)); return(2); } /* Grab a packet */ packet = pcap_next(handle, &header); /* Print its length */ printf(“Got a packet with length of [%d]\n", header.len); /* And close the session */ pcap_close(handle); return(0); }