#include <netinet/ip.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <syslog.h> #include <fcntl.h> #include <net/if_arp.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <errno.h> #include <time.h> #include <sys/uio.h> #include <bits/sockaddr.h> #include <asm/types.h> #include <linux/rtnetlink.h> FILE *ip4to6; char ipv4[INET_ADDRSTRLEN]; char ipv6[INET6_ADDRSTRLEN]; unsigned long long lladdr; int injectmacipv4() { int fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); struct sockaddr_nl la; memset(&la, 0, sizeof(la)); la.nl_family = AF_NETLINK; la.nl_pad = 0; la.nl_pid = getpid(); la.nl_groups = 0; bind(fd, (struct sockaddr*) &la, sizeof(la)); struct { struct nlmsghdr n; struct ndmsg r; char buf[1024]; } req2; memset(&req2, 0, sizeof(req2)); int ndmsglen = NLMSG_LENGTH(sizeof(struct ndmsg)); // create the IP attribute struct rtattr *dstattr; dstattr = (struct rtattr *) req2.buf; dstattr->rta_type = NDA_DST; dstattr->rta_len = sizeof(struct rtattr) + 4; int intip; inet_pton(AF_INET, ipv4, ((char *)dstattr) + sizeof(struct rtattr)); ndmsglen += dstattr->rta_len; // create the MAC attribute //struct rtattr *dstattr; dstattr = (struct rtattr *) req2.buf + 2; dstattr->rta_type = NDA_LLADDR; dstattr->rta_len = sizeof(struct rtattr) + 6; memcpy(((char *)dstattr) + sizeof(struct rtattr), &lladdr, 6); ndmsglen += dstattr->rta_len; // fill in the netlink message header req2.n.nlmsg_len = ndmsglen; //48; req2.n.nlmsg_type = RTM_NEWNEIGH; req2.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; //1537 req2.n.nlmsg_seq; req2.n.nlmsg_pid; // fill in the netlink message NEWNEIGH req2.r.ndm_family = AF_INET; req2.r.ndm_pad1; req2.r.ndm_pad2; req2.r.ndm_ifindex = 2; // /sys/class/net/eth2/ifindex req2.r.ndm_state = NUD_PERMANENT; req2.r.ndm_flags; req2.r.ndm_type; // debug stuff about the packet to be send via NETLINK /* printf("The sent packet:\n\n"); printf("NLMSG HEADER:\nnlmsg_len = %i\nnlmsg_type = %i\nnlmsg_flags = %i\nnlmsg_seq = %i\nnlmsg_pid = %i\n\n", req2.n.nlmsg_len, req2.n.nlmsg_type, req2.n.nlmsg_flags, req2.n.nlmsg_seq, req2.n.nlmsg_pid); printf("NLMSG MESSAGE:\nndm_family = %i\nndm_pad1 = %i\nndm_pad2 = %i\nndm_ifindex = %i\nndm_state = %i\nndm_flags = %i\nndm_type = %i\n\n", req2.r.ndm_family, req2.r.ndm_pad1, req2.r.ndm_pad2, req2.r.ndm_ifindex, req2.r.ndm_state, req2.r.ndm_flags, req2.r.ndm_type); printf("BUF:\n"); int bufteller = 0; while(bufteller < 256) { printf ("%i ", req2.buf[bufteller]); bufteller++; } printf("\n\n"); */ int status2; status2 = send(fd, &req2, req2.n.nlmsg_len, 0); close (fd); return 1; } int getmacipv6() { int fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); struct sockaddr_nl la; memset(&la, 0, sizeof(la)); la.nl_family = AF_NETLINK; la.nl_pad = 0; la.nl_pid = getpid(); la.nl_groups = 0; bind(fd, (struct sockaddr*) &la, sizeof(la)); //send request via netlink, the message is in req struct { struct nlmsghdr n; struct ndmsg r; } req; memset(&req, 0, sizeof(req)); // fill in the netlink message header req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); req.n.nlmsg_type = RTM_GETNEIGH; req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; req.n.nlmsg_seq; req.n.nlmsg_pid;// = getpid(); // fill in the netlink message GETNEIGH req.r.ndm_family = AF_INET6; req.r.ndm_pad1; req.r.ndm_pad2; req.r.ndm_ifindex; req.r.ndm_state;// = NUD_PERMANENT; req.r.ndm_flags; req.r.ndm_type; int status; status = send(fd, &req, req.n.nlmsg_len, 0); if (status < 0) printf("RFC 5549: Problem sending to netlink\n"); //receive data and put it in buf char buf[256]; char *p; struct nlmsghdr *nlp; memset(buf, 0, sizeof(buf)); p = buf; int nll = 0; struct ndmsg *ndp; struct rtattr *ndap; int ndl; while(1) { status = recv(fd, p, sizeof(buf) - nll, 0); if (status < 0) printf("RFC 5549: Problem receiving from netlink\n"); close(fd); nlp = (struct nlmsghdr *) p; if(nlp->nlmsg_type == NLMSG_DONE) { break; } while(1) { ndp = (struct ndmsg *) NLMSG_DATA(nlp); // get RTNETLINK message header ndap = (struct rtattr *) RTM_RTA(ndp); // get start of attributes ndl = RTM_PAYLOAD(nlp); while(1) { if (ndap->rta_type == NDA_DST) { char dstp[INET6_ADDRSTRLEN]; memset(dstp, 0, sizeof(dstp)); //long long *intippoint = RTA_DATA(ndap); //long long intip = *intippoint; //printf("intip = %lli\n", intip); inet_ntop(AF_INET6, RTA_DATA(ndap), dstp, INET6_ADDRSTRLEN); //printf("dstp = %s, ipv6 = %s\n", dstp, ipv6); if (strcmp(dstp, ipv6) == 0) { ndap = RTA_NEXT(ndap, ndl); long long *macpoint = RTA_DATA(ndap); lladdr = *macpoint; //printf("lladdr = %llx\n", lladdr); return 2; } } ndap = RTA_NEXT(ndap, ndl); if (RTA_OK(ndap, ndl) != 1) { break; } } p += status; nll += status; nlp = NLMSG_NEXT(nlp, nll); if (NLMSG_OK(nlp, nll) != 1) { break; } } } return 1; } int readfile(int teller) { ip4to6 = fopen("/usr/local/sbin/ip4to6","r"); char line[100]; while (1) { int teller2 = 0; while (teller2 <= teller) { fgets(line, 100, ip4to6); teller2++; } char *word; word = strtok(line, " "); memcpy(ipv6, word, INET6_ADDRSTRLEN); word = strtok(NULL, " "); word[strlen(word) - 1] = word[strlen(word)]; // remove the last \n in the ipv4 address memcpy(ipv4, word, INET_ADDRSTRLEN); break; } fclose(ip4to6); return 1; } int countlines() { ip4to6 = fopen("/usr/local/sbin/ip4to6","r"); char c; int teller = 0; while ((c = fgetc(ip4to6)) != EOF) { if (c == '\n') { teller++; } } fclose(ip4to6); return teller; } void main() { while(1) { int lines = countlines(); int teller = 0; while (teller < lines) { lladdr = 0; readfile(teller); getmacipv6(); // printf("\n"); if (lladdr != 0) { injectmacipv4(); } teller++; } sleep(5); } }
netlink ARP table
最新推荐文章于 2022-05-17 09:56:31 发布