Skip to content

Instantly share code, notes, and snippets.

@geraint0923
Last active August 29, 2015 14:17
Show Gist options
  • Select an option

  • Save geraint0923/c0d6603da1145447a999 to your computer and use it in GitHub Desktop.

Select an option

Save geraint0923/c0d6603da1145447a999 to your computer and use it in GitHub Desktop.
Parse the label from the packet
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <linux/tcp.h>
struct my_ip {
u_int8_t ip_vhl; /* header length, version */
#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4)
#define IP_HL(ip) ((ip)->ip_vhl & 0x0f)
u_int8_t ip_tos; /* type of service */
u_int16_t ip_len; /* total length */
u_int16_t ip_id; /* identification */
u_int16_t ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_int8_t ip_ttl; /* time to live */
u_int8_t ip_p; /* protocol */
u_int16_t ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
u_int16_t handle_ethernet(u_char *args,const struct pcap_pkthdr* pkthdr,u_char* packet) {
struct ether_header *eptr; /* net/ethernet.h */
/* lets start with the ether header... */
eptr = (struct ether_header *) packet;
fprintf(stdout,"ethernet header source: %s"
,ether_ntoa((const struct ether_addr *)&eptr->ether_shost));
fprintf(stdout," destination: %s "
,ether_ntoa((const struct ether_addr *)&eptr->ether_dhost));
/* check to see if we have an ip packet */
if (ntohs (eptr->ether_type) == ETHERTYPE_IP)
{
fprintf(stdout,"(IP)");
}else if (ntohs (eptr->ether_type) == ETHERTYPE_ARP)
{
fprintf(stdout,"(ARP)");
}else if (ntohs (eptr->ether_type) == ETHERTYPE_REVARP)
{
fprintf(stdout,"(RARP)");
}else {
fprintf(stdout,"(?)");
exit(1);
}
fprintf(stdout,"\n");
return eptr->ether_type;
}
u_char* handle_IP(u_char *args,const struct pcap_pkthdr* pkthdr, u_char* packet) {
const struct my_ip* ip;
u_int length = pkthdr->len;
u_int hlen,off,version;
uint8_t *res = packet;
int i;
int len;
/* jump pass the ethernet header */
ip = (struct my_ip*)(packet + sizeof(struct ether_header));
length -= sizeof(struct ether_header);
/* check to see we have a packet of valid length */
if (length < sizeof(struct my_ip))
{
printf("truncated ip %d",length);
return NULL;
}
len = ntohs(ip->ip_len);
hlen = IP_HL(ip); /* header length */
version = IP_V(ip);/* ip version */
/* check version */
if(version != 4)
{
fprintf(stdout,"Unknown version %d\n",version);
return NULL;
}
/* check header length */
if(hlen < 5 )
{
fprintf(stdout,"bad-hlen %d \n",hlen);
}
fprintf(stdout,"hlen %d \n",hlen);
/* see if we have as much packet as we should */
if(length < len)
printf("\ntruncated IP - %d bytes missing\n",len - length);
/* Check to see if we have the first fragment */
off = ntohs(ip->ip_off);
if((off & 0x1fff) == 0 )/* aka no 1's in first 13 bits */
{/* print SOURCE DESTINATION hlen version len offset */
fprintf(stdout,"IP: ");
fprintf(stdout,"%s ",
inet_ntoa(ip->ip_src));
fprintf(stdout,"%s %d %d %d %d\n",
inet_ntoa(ip->ip_dst),
hlen,version,len,off);
}
return res + sizeof(struct ether_header) + hlen * 4;
}
uint8_t *handle_TCP(uint8_t *args, const struct pcap_pkthdr *pkthdr, uint8_t *packet) {
struct tcphdr *hdr = (struct tcphdr*)packet;
fprintf(stdout, "srcport: %d dstport: %d len: %d\n", ntohs(hdr->source), ntohs(hdr->dest), hdr->doff);
return packet + 4 * hdr->doff;
}
inline uint32_t mpls_get_label(uint32_t mpls) {
return (mpls & 0xfffff000) >> 12;
}
/*
inline uint8_t mpls_get_exp(uint32_t mpls) {
return (mpls & 0x00000700) >> 11;
}
inline uint8_t mpls_get_s(uint32_t mpls) {
return (mpls & 0x00000800) >> 8;
}
inline uint8_t mpls_get_ttl(uint32_t mpls) {
return (mpls & 0x000000ff) >> 0;
}
*/
/* callback function that is passed to pcap_loop(..) and called each time
* a packet is recieved */
void my_callback(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet) {
struct ether_header *eptr; /* net/ethernet.h */
uint32_t mh = *(uint32_t*)(packet + sizeof(struct ether_header));
mh = htonl(mh);
eptr = (const struct ether_header *) packet;
if(ntohs(eptr->ether_type) == ETH_P_MPLS_UC && pkthdr->len >= 59) {
/* lets start with the ether header... */
/*
fprintf(stdout,"ethernet header source: %s"
,ether_ntoa((const struct ether_addr *)&eptr->ether_shost));
fprintf(stdout," destination: %s "
,ether_ntoa((const struct ether_addr *)&eptr->ether_dhost));
fprintf(stdout,"type: %04x", ntohs(eptr->ether_type));
*/
fprintf(stdout, "label:%05x value:%d\n", mpls_get_label(mh), packet[58]);
}
// uint16_t type = handle_ethernet(args, pkthdr,packet);
/*
uint8_t *ptr = handle_IP(args, pkthdr,packet);
if(ptr + sizeof(struct tcphdr) -packet <= pkthdr->len)
return;
ptr= handle_TCP(args,pkthdr, ptr);
if(ptr - packet > pkthdr->len)
return;
*/
fflush(stdout);
}
int main(int argc,char **argv)
{
int i;
char *dev = argv[2];
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
const u_char *packet;
struct pcap_pkthdr hdr; /* pcap.h */
struct ether_header *eptr; /* net/ethernet.h */
if(argc != 3){ fprintf(stdout,"Usage: %s (nic|file) {nic/file name}\n",argv[0]);return 0;}
/* grab a device to peak into... */
//dev = pcap_lookupdev(errbuf);
if(dev == NULL)
{ printf("%s\n",errbuf); exit(1); }
/* open device for reading */
//descr = pcap_open_live(dev,BUFSIZ,0,-1,errbuf);
if(strcmp(argv[1], "nic") == 0) {
descr = pcap_open_live(dev,BUFSIZ,0,-1,errbuf);
} else if(strcmp(argv[1], "file") == 0) {
descr = pcap_open_offline(dev,errbuf);
} else {
fprintf(stdout, "uknown command: %s\n", argv[1]);
exit(-1);
}
if(descr == NULL)
{ printf("pcap_open_live(): %s\n",errbuf); exit(1); }
/* allright here we call pcap_loop(..) and pass in our callback function */
/* int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)*/
/* If you are wondering what the user argument is all about, so am I!! */
//pcap_loop(descr,atoi(argv[2]),my_callback,NULL);
pcap_loop(descr,0,my_callback,NULL);
//fprintf(stdout,"\nDone processing packets... wheew!\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment