//this program was written to be used on NetBSD. YMMV. #include #include #include #include #include #include #include #include #include #include #include #include #include //ripped from NetBSD's identd.c (found mine in /usr/src/libexec/identd/identd.c) static int sysctl_getuid(struct sockaddr_storage *ss, socklen_t len, uid_t *uid) { int mib[4]; uid_t myuid; size_t uidlen; uidlen = sizeof(myuid); mib[0] = CTL_NET; mib[1] = ss->ss_family; mib[2] = IPPROTO_TCP; mib[3] = TCPCTL_IDENT; if (sysctl(mib, sizeof(mib)/ sizeof(int), &myuid, &uidlen, ss, len) < 0) return -1; *uid = myuid; return 0; } //for debugging void dump_sockaddr(struct sockaddr_in *sin,int len) { unsigned char *p=(void *)sin; for(;len;len--,p++) { printf("%02x ",*p); } printf("\n"); } int main(int argc,char *argv[]) { uid_t myuid=-1; int len=sizeof(struct sockaddr_storage); struct sockaddr_storage mine[2]; //future IPv6 support? struct sockaddr_in *inA=(struct sockaddr_in *)(&mine[0]); // struct sockaddr_in6 *in6A=(struct sockaddr_in6 *)(&mine[0]); struct sockaddr_in *inB=(struct sockaddr_in *)(&mine[1]); // struct sockaddr_in6 *in6B=(struct sockaddr_in6 *)(&mine[1]); if(argc <= 4) return -2; memset(inA,0,len); memset(inB,0,len); inA->sin_len=16; inB->sin_len=16; inA->sin_family=AF_INET; inB->sin_family=AF_INET; inA->sin_addr.s_addr=(inet_addr(argv[1])); inB->sin_addr.s_addr=(inet_addr(argv[3])); inA->sin_port=htons(atoi(argv[2])); inB->sin_port=htons(atoi(argv[4])); //these were to see what real sockaddr looked like. // getpeername(0,inB,&len); // getsockname(0,inA,&len); // dump_sockaddr(inA,len); // dump_sockaddr(inB,len); if(sysctl_getuid(mine,sizeof(mine),&myuid) == -1) return -1; printf("%d\n",myuid); return 0; }