/* netdump.c : network hexdump framework for writing tests */ /* Jon Mayo - PUBLIC DOMAIN - July 17, 2007 */ #include #include #include #include #include #include #ifdef __MINGW32__ #include #define socklen_t int #else #include #include #include #include #include #include #endif static int verbose_fl=1; static int net_lookup(const char *host, const char *sport, const char *pname, int (*foreach)(void *p, struct addrinfo *ai, const char *addr, const char *serv), void *p) { struct protoent *pe; struct addrinfo *ai=0, hint, *curr; int proto; int res; assert(foreach != NULL); if(verbose_fl) { fprintf(stderr, "net_lookup(\"%s\", \"%s\", \"%s\")\n", host, sport, pname); } if(pname && pname[0]) { pe=getprotobyname(pname); proto=pe ? pe->p_proto : 0; } else { proto=0; } if(host && !host[0]) host=0; if(sport && !sport[0]) sport=0; hint.ai_flags=AI_ADDRCONFIG|AI_PASSIVE; hint.ai_family=PF_UNSPEC; hint.ai_protocol=proto; hint.ai_socktype=0; hint.ai_addrlen=0; hint.ai_addr=0; hint.ai_canonname=0; hint.ai_next=0; if((res=getaddrinfo(host, sport, &hint, &ai))) { fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(res)); if(res==EAI_SYSTEM) { perror("getaddrinfo()"); } return 0; } curr=ai; if(!curr) { fprintf(stderr, "no entries!\n"); return 0; } for(; curr; curr=curr->ai_next) { char addr[NI_MAXHOST]; char serv[NI_MAXSERV]; /* Mac OS X 10.4 getnameinfo() is buggy without NI_NUMERICSERV */ if((res=getnameinfo(curr->ai_addr, curr->ai_addrlen, addr, sizeof addr, serv, sizeof serv, NI_NUMERICHOST|NI_NUMERICSERV))) { /* Failed */ if(res==EAI_SYSTEM) { perror("getnameinfo()"); } else { fprintf(stderr, "getnameinfo(): %s\n", gai_strerror(res)); } continue; } if(!foreach(p, curr, addr, serv)) { freeaddrinfo(ai); return 0; } } freeaddrinfo(ai); return 1; } static int connect_foreach(void *p, struct addrinfo *ai, const char *addr, const char *serv) { int fd; assert(p!=NULL); assert(ai!=NULL); assert(addr!=NULL); assert(serv!=NULL); if(verbose_fl) { char buf[64]; if(inet_ntop(ai->ai_family, ai->ai_addr->sa_data, buf, sizeof buf)) { printf("Connecting %s ... ", buf); } } fd=socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if(fd<0) { fprintf(stderr, "Failure: socket():%s\n", strerror(errno)); return 1; /* try another selection */ } if(connect(fd, ai->ai_addr, ai->ai_addrlen)<0) { fprintf(stderr, "Failure: connect():%s\n", strerror(errno)); close(fd); return 1; /* try another selection */ } printf("Success\n"); *(int*)p=fd; return 0; /* we're done processing */ } int sockConnect(const char *host, const char *service) { int fd; fd=-1; net_lookup(host, service, "tcp", connect_foreach, &fd); return fd; } /* read everything and dump it in a nice hexdump format */ void sockDump(int fd, FILE *out) { unsigned char buf[1], last[16]; int len, ofs=0, i, n; n=0; while((len=read(fd, buf, sizeof buf))>0) { for(i=0;i"); /* output the response */ sockDump(sock, stdout); close(sock); return EXIT_SUCCESS; }