Skip to content

Instantly share code, notes, and snippets.

@optman
Last active August 25, 2016 06:42
Show Gist options
  • Save optman/2882dd8879e39e5af05f to your computer and use it in GitHub Desktop.
Save optman/2882dd8879e39e5af05f to your computer and use it in GitHub Desktop.
test tproxy
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
int main(){
int fd = socket(AF_INET, SOCK_DGRAM, 0);
int value = 1;
int ret;
ret = setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value));
if (ret != 0)
{
fprintf (stderr, "error setting transparency for listening socket. err (#%d %s)\n",
errno, strerror(errno));
close (fd);
return -4;
}
ret = setsockopt(fd, SOL_IP, IP_RECVORIGDSTADDR, &value, sizeof(value));
if (ret != 0)
{
fprintf (stderr, "error setting transparency for listening socket. err (#%d %s)\n",
errno, strerror(errno));
close (fd);
return -4;
}
struct sockaddr_in name;
name.sin_family = AF_INET;
name.sin_port = htons(3333);
name.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(fd, (const struct sockaddr*)&name, sizeof(name))<0)
{
fprintf (stderr, "error calling bind()\n");
return -6;
}
while(1){
char cntrlbuf[64];
char buffer[548];
struct sockaddr_storage src_addr;
struct iovec iov[1];
iov[0].iov_base=buffer;
iov[0].iov_len=sizeof(buffer);
struct msghdr message;
message.msg_name=&src_addr;
message.msg_namelen=sizeof(src_addr);
message.msg_iov=iov;
message.msg_iovlen=1;
message.msg_control=cntrlbuf;
message.msg_controllen=sizeof(cntrlbuf);
ssize_t count=recvmsg(fd,&message,0);
if (count==-1) {
printf("%s\n",strerror(errno));
} else if (message.msg_flags & MSG_TRUNC) {
printf("datagram too large for buffer: truncated");
} else {
buffer[count] = 0;
printf("src_addr %s data(%d) %s", inet_ntoa(((struct sockaddr_in*)&src_addr)->sin_addr),
(int)count, (const char*)buffer);
struct sockaddr_in *clntaddr;
struct sockaddr_in dstaddr={0,};
struct cmsghdr *cmsg;
int ret;
int found=0;
struct msghdr* msg = &message;
/* get original destination address */
for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg))
{
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVORIGDSTADDR)
{
memcpy (&dstaddr, CMSG_DATA(cmsg), sizeof (struct sockaddr_in));
dstaddr.sin_family = AF_INET;
printf ("original dst address %s:%d\n",
inet_ntoa(dstaddr.sin_addr),
ntohs(dstaddr.sin_port));
}
}
}//if
}//while
}