/* fcntl */ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { int ret; struct sock *sk; socket_idesc_check(sockfd, sk); if (!addr || (addrlen <= 0)) return SET_ERRNO(EINVAL); ret = kbind(sk, addr, addrlen); if (ret < 0){ return SET_ERRNO(-ret); } return 0; }
void emuinit(void *imod) { Osenv *e; char *wdir; e = up->env; e->pgrp = newpgrp(); e->fgrp = newfgrp(nil); e->egrp = newegrp(); e->errstr = e->errbuf0; e->syserrstr = e->errbuf1; e->user = strdup(""); links(); chandevinit(); if(waserror()) panic("setting root and dot"); e->pgrp->slash = namec("#/", Atodir, 0, 0); cnameclose(e->pgrp->slash->name); e->pgrp->slash->name = newcname("/"); e->pgrp->dot = cclone(e->pgrp->slash); poperror(); strcpy(up->text, "main"); if(kopen("#c/cons", OREAD) != 0) fprint(2, "failed to make fd0 from #c/cons: %r\n"); kopen("#c/cons", OWRITE); kopen("#c/cons", OWRITE); /* the setid cannot precede the bind of #U */ kbind("#U", "/", MAFTER|MCREATE); setid(eve, 0); kbind("#^", "/dev", MBEFORE); /* snarf */ kbind("#^", "/chan", MBEFORE); kbind("#m", "/dev", MBEFORE); /* pointer */ kbind("#c", "/dev", MBEFORE); kbind("#p", "/prog", MREPL); kbind("#d", "/fd", MREPL); kbind("#I", "/net", MAFTER); /* will fail on Plan 9 */ /* BUG: we actually only need to do these on Plan 9 */ kbind("#U/dev", "/dev", MAFTER); kbind("#U/net", "/net", MAFTER); kbind("#U/net.alt", "/net.alt", MAFTER); if(cputype != nil) ksetenv("cputype", cputype, 1); putenvqv("emuargs", rebootargv, rebootargc, 1); putenvq("emuroot", rootdir, 1); ksetenv("emuhost", hosttype, 1); wdir = malloc(1024); if(wdir != nil){ if(getwd(wdir, 1024) != nil) putenvq("emuwdir", wdir, 1); free(wdir); } kproc("main", disinit, imod, KPDUPFDG|KPDUPPG|KPDUPENVG); for(;;) ospause(); }
/*This function creates a server process listening at the socket rport*/ int tcp_serv (void *arg) { struct sockaddr_in relay_srv_addr, stClntAddr; int iAddrlen; int on = 1; ksocket_t sockfd_chld; /* kernel thread name*/ sprintf(current->comm, "krelaysrv"); allow_signal(SIGKILL); allow_signal(SIGTERM); /*Create socket*/ if ((SockfdRelayClntSide = ksocket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) printk(KERN_ERR "Can't create socket."); memset(&relay_srv_addr, 0, sizeof(relay_srv_addr)); relay_srv_addr.sin_family = AF_INET; relay_srv_addr.sin_addr.s_addr = INADDR_ANY; relay_srv_addr.sin_port = htons(StrToInt((char *)(pListenPort->data))); if (ksetsockopt(SockfdRelayClntSide, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { printk(KERN_ERR "ksetsockopt(SO_REUSEADDR) failed\n"); } /*Bind our local addrress so that client can send*/ if (kbind(SockfdRelayClntSide, (struct sockaddr *) &relay_srv_addr, sizeof(relay_srv_addr)) < 0) { printk(KERN_ERR "Can't bind local address\n"); return -1; } /* Make socket a listening socket */ if (klisten(SockfdRelayClntSide, 15) < 0) { printk(KERN_ERR "Call to listen failed."); return -1; } /* Loop infinitely to accept and service connections */ while ( 1 ) { /* Wait for connection */ if ( (sockfd_chld = kaccept(SockfdRelayClntSide, (struct sockaddr *) &stClntAddr, &iAddrlen)) < 0 ) { printk(KERN_ERR "Error calling accept()"); return -1; } ChldThdPid[iThdCnt] = kernel_thread ((void *)RedirectProc, sockfd_chld, 0); if (iThdCnt == (MAX_THD_IDX - 1)) iThdCnt = 0; else iThdCnt++; //Sleep for some time // mdelay (1); } (void)kclose (SockfdRelayClntSide); return -1; /* We shouldn't get here */ }
/*this handles the redirection from client to real server*/ void RedirectProc (ksocket_t SockfdFromClnt) { struct sockaddr_in RealSrvAddr, stRelayAddr, stTemp1, stTemp; ksocket_t SockfdRelay; int on = 1; char frwd_buffer[BUFFER_SIZE]; int iRBytes, iWBytes, iNWritten, cur, iLen; unsigned short iClntPort, server_port = 0; /* kernel thread name*/ sprintf(current->comm, "krelaychld"); allow_signal(SIGKILL); allow_signal(SIGTERM); //Copy the values for later use if ((kgetpeername(SockfdFromClnt, (struct sockaddr *)&stTemp1, &iLen)) < 0) { printk (KERN_ERR "kgetpeername() failed\n"); } iClntPort = stTemp1.sin_port; /*Create socket*/ if ((SockfdRelay = ksocket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) printk(KERN_ERR "Can't create socket."); memset(&stRelayAddr, 0, sizeof(stRelayAddr)); stRelayAddr.sin_family = AF_INET; stRelayAddr.sin_addr.s_addr = INADDR_ANY; stRelayAddr.sin_port = htons(0); if (ksetsockopt(SockfdRelay, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { printk(KERN_ERR "ksetsockopt(SO_REUSEADDR) failed\n"); } /*Bind our local addrress so that client can send*/ if (kbind(SockfdRelay, (struct sockaddr *) &stRelayAddr, sizeof(stRelayAddr)) < 0) { printk(KERN_ERR "Can't bind local address\n"); return; } //printk (KERN_ERR "Relay eph port= %d", ntohs(stRelayAddr.sin_port)); //Need to analyze this part@@@@@@@@@ //Store the relay server ephemeral port (Y) in NAT if (kgetsockname(SockfdRelay, (struct sockaddr *) &stTemp, &iLen) < 0) { printk(KERN_ERR "kgetpeername failed\n"); } // printk (KERN_ERR "Relay eph port= %d", ntohs(stTemp.sin_port)); for (cur = 0; cur <= MAX_TBL_IDX -1; cur++) { if (stTbl[cur].iClntPort == iClntPort) { stTbl[cur].iRelayPort = stTemp.sin_port; server_port = stTbl[cur].iClntSrvPort; break; } } if (0 == server_port) { printk (KERN_ERR "Error..Cannot get the server port\n"); kclose (SockfdRelay); return; } //Connect to the Real server RealSrvAddr.sin_family = PF_INET; RealSrvAddr.sin_addr.s_addr = (inet_addr(DEF_REAL_IP)); RealSrvAddr.sin_port = server_port; if (kconnect(SockfdRelay, (struct sockaddr *) &RealSrvAddr, sizeof(RealSrvAddr)) < 0) { printk(KERN_ERR "Connect failed\n"); } for (;;) { //printk (KERN_ERR "trying krecv from client\n"); /* Read from Client and send to Real Server */ iRBytes = krecv(SockfdFromClnt, &frwd_buffer, BUFFER_SIZE - 8, MSG_DONTWAIT); //printk (KERN_ERR "tried krecv = %d\n", iRBytes); //Client Socket is closed if (iRBytes == 0) break; iWBytes = 0; iNWritten = 0; //If some data is there to be read while (iWBytes != iRBytes && iRBytes > 0) { if ((iNWritten = ksend(SockfdRelay, &frwd_buffer + iWBytes , iRBytes-iWBytes, 0)) < 0) { printk (KERN_ERR "error occured while writing to receiver\n"); return; } iWBytes += iNWritten; } //printk (KERN_ERR "trying krecv from real server\n"); /* Read from Real server and write to client */ iRBytes = krecv(SockfdRelay, &frwd_buffer, BUFFER_SIZE - 8, MSG_DONTWAIT); //printk (KERN_ERR "tried krecv1 = %d\n", iRBytes); if (iRBytes == 0) break; iWBytes = 0; iNWritten = 0; while (iWBytes != iRBytes && iRBytes > 0) { if ((iNWritten = ksend(SockfdFromClnt, &frwd_buffer + iWBytes , iRBytes-iWBytes, 0)) < 0) { printk (KERN_ERR "error occured while writing to receiver\n"); return; } iWBytes += iNWritten; } //Sleep for sometime // mdelay (1); } (void)kclose(SockfdRelay); (void)kclose(SockfdFromClnt); }