@@ -3363,31 +3363,69 @@ impl Cage {
33633363 }
33643364 }
33653365
3366+ /// ## ------------------GETPEERNAME SYSCALL------------------
3367+ /// ### Description
3368+ /// The `getpeername_syscall()` returns the address of the peer connected to
3369+ /// the socket fd, in the buffer pointed to by ret_addr
3370+ ///
3371+ /// ### Function Arguments
3372+ /// The `getpeername_syscall()` receives two arguments:
3373+ /// * `fd` - The file descriptor of the socket
3374+ /// * `ret_addr` - A buffer of GenSockaddr type to store the return value
3375+ ///
3376+ /// ### Returns
3377+ /// On success, zero is returned. Otherwise, errors or panics are returned
3378+ /// for different scenarios.
3379+ ///
3380+ /// ### Errors
3381+ /// * EBADF - The argument fd is not a valid file descriptor.
3382+ /// * ENOTSOCK - The file descriptor sockfd does not refer to a socket.
3383+ /// * ENOTCONN - The socket is not connected.
3384+ ///
3385+ /// ### Panics
3386+ /// No Panic is expected from this syscall.
3387+ ///
3388+ /// more details at https://man7.org/linux/man-pages/man2/getpeername.2.html
33663389 pub fn getpeername_syscall ( & self , fd : i32 , ret_addr : & mut interface:: GenSockaddr ) -> i32 {
3390+ // first let's check the fd range
3391+ if fd < 0 || fd >= MAXFD {
3392+ return syscall_error (
3393+ Errno :: EBADF ,
3394+ "getpeername" ,
3395+ "the provided file descriptor is not valid" ,
3396+ ) ;
3397+ }
3398+
3399+ // get the file descriptor object
33673400 let checkedfd = self . get_filedescriptor ( fd) . unwrap ( ) ;
33683401 let unlocked_fd = checkedfd. read ( ) ;
33693402 if let Some ( filedesc_enum) = & * unlocked_fd {
33703403 if let Socket ( sockfdobj) = filedesc_enum {
3371- //if the socket is not connected, then we should return an error
3404+ // get the read lock of sockhandle
33723405 let sock_tmp = sockfdobj. handle . clone ( ) ;
33733406 let sockhandle = sock_tmp. read ( ) ;
3407+ // if the socket is not connected, then we should return an error
33743408 if sockhandle. remoteaddr == None {
33753409 return syscall_error (
33763410 Errno :: ENOTCONN ,
33773411 "getpeername" ,
33783412 "the socket is not connected" ,
33793413 ) ;
33803414 }
3415+ // remoteaddr stores the value we want so we just return the remoteaddr stored
3416+ // in sockhandle
33813417 * ret_addr = sockhandle. remoteaddr . unwrap ( ) ;
33823418 return 0 ;
33833419 } else {
3420+ // if the fd is not socket object
33843421 return syscall_error (
33853422 Errno :: ENOTSOCK ,
33863423 "getpeername" ,
33873424 "the provided file is not a socket" ,
33883425 ) ;
33893426 }
33903427 } else {
3428+ // if the fd is not valid
33913429 return syscall_error (
33923430 Errno :: EBADF ,
33933431 "getpeername" ,
@@ -3396,29 +3434,76 @@ impl Cage {
33963434 }
33973435 }
33983436
3437+ /// ## ------------------GETSOCKNAME SYSCALL------------------
3438+ /// ### Description
3439+ /// The `getsockname_syscall()` returns the current address to which the
3440+ /// socket fd is bound, in the buffer pointed to by ret_addr. If the socket
3441+ /// hasn't bound to any address, it returns an empty address.
3442+ ///
3443+ /// ### Function Arguments
3444+ /// The `getsockname_syscall()` receives two arguments:
3445+ /// * `fd` - The file descriptor of the socket
3446+ /// * `ret_addr` - A buffer of GenSockaddr type to store the return value
3447+ ///
3448+ /// ### Returns
3449+ /// On success, zero is returned. Otherwise, errors or panics are returned
3450+ /// for different scenarios.
3451+ ///
3452+ /// ### Errors
3453+ /// * EBADF - The argument fd is not a valid file descriptor.
3454+ /// * ENOTSOCK - The file descriptor sockfd does not refer to a socket.
3455+ ///
3456+ /// ### Panics
3457+ /// No Panic is expected from this syscall.
3458+ ///
3459+ /// more details at https://man7.org/linux/man-pages/man2/getsockname.2.html
33993460 pub fn getsockname_syscall ( & self , fd : i32 , ret_addr : & mut interface:: GenSockaddr ) -> i32 {
3461+ // first let's check the fd range
3462+ if fd < 0 || fd >= MAXFD {
3463+ return syscall_error (
3464+ Errno :: EBADF ,
3465+ "getsockname" ,
3466+ "the provided file descriptor is not valid" ,
3467+ ) ;
3468+ }
3469+
3470+ // get the file descriptor object
34003471 let checkedfd = self . get_filedescriptor ( fd) . unwrap ( ) ;
34013472 let unlocked_fd = checkedfd. read ( ) ;
34023473 if let Some ( filedesc_enum) = & * unlocked_fd {
34033474 if let Socket ( sockfdobj) = filedesc_enum {
3475+ // must be a socket file descriptor
3476+
3477+ // get the read lock of socket handler
34043478 let sock_tmp = sockfdobj. handle . clone ( ) ;
34053479 let sockhandle = sock_tmp. read ( ) ;
3480+ // each socket type has different structure
3481+ // so we must handle them seperately
34063482 if sockhandle. domain == AF_UNIX {
3483+ // in case of AF_UNIX socket
34073484 if sockhandle. localaddr == None {
3485+ // if hasn't bound to any address,
3486+ // return an empty address
34083487 let null_path: & [ u8 ] = & [ ] ;
34093488 * ret_addr = interface:: GenSockaddr :: Unix ( interface:: new_sockaddr_unix (
34103489 sockhandle. domain as u16 ,
34113490 null_path,
34123491 ) ) ;
34133492 return 0 ;
34143493 }
3415- //if the socket is not none, then return the socket
3494+ // if the socket address is not none, then return the socket address
34163495 * ret_addr = sockhandle. localaddr . unwrap ( ) ;
34173496 return 0 ;
34183497 } else {
3498+ // in case of AF_INET/AF_INET6
34193499 if sockhandle. localaddr == None {
3420- //sets the address to 0.0.0.0 if the address is not initialized yet
3421- //setting the family as well based on the domain
3500+ // if the socket hasn't bound to any address, we'd return an empty address
3501+ // with both ip and port set to 0. But family should be set since it is
3502+ // something that was already specified when the socket was created
3503+
3504+ // for ipv4, set the address to 0.0.0.0 to indicate uninitialized address
3505+ // for ipv6, set the address to 0:0:0:0:0:0:0:0
3506+ // (::) to indicate uninitialized address
34223507 let addr = match sockhandle. domain {
34233508 AF_INET => interface:: GenIpaddr :: V4 ( interface:: V4Addr :: default ( ) ) ,
34243509 AF_INET6 => interface:: GenIpaddr :: V6 ( interface:: V6Addr :: default ( ) ) ,
@@ -3428,20 +3513,24 @@ impl Cage {
34283513 } ;
34293514 ret_addr. set_addr ( addr) ;
34303515 ret_addr. set_port ( 0 ) ;
3516+ // set the family
34313517 ret_addr. set_family ( sockhandle. domain as u16 ) ;
34323518 return 0 ;
34333519 }
3520+ // if the socket address is not none, then return the socket address
34343521 * ret_addr = sockhandle. localaddr . unwrap ( ) ;
34353522 return 0 ;
34363523 }
34373524 } else {
3525+ // the fd is not a socket
34383526 return syscall_error (
34393527 Errno :: ENOTSOCK ,
34403528 "getsockname" ,
34413529 "the provided file is not a socket" ,
34423530 ) ;
34433531 }
34443532 } else {
3533+ // invalid fd
34453534 return syscall_error (
34463535 Errno :: EBADF ,
34473536 "getsockname" ,
@@ -3450,9 +3539,32 @@ impl Cage {
34503539 }
34513540 }
34523541
3453- //we only return the default host name because we do not allow for the user to
3454- // change the host name right now
3542+ /// ## ------------------GETHOSTNAME SYSCALL------------------
3543+ /// ### Description
3544+ /// The `gethostname_syscall()` returns the null-terminated hostname in the
3545+ /// address_ptr, which has length bytes. If the null-terminated
3546+ /// hostname is too large to fit, then the name is truncated, and no error
3547+ /// is returned
3548+ ///
3549+ /// ### Function Arguments
3550+ /// The `gethostname_syscall()` receives two arguments:
3551+ /// * `address_ptr` - The buffer to hold the returned host name
3552+ /// * `length` - The length of the buffer
3553+ ///
3554+ /// ### Returns
3555+ /// On success, zero is returned. Otherwise, errors or panics are returned
3556+ /// for different scenarios.
3557+ ///
3558+ /// ### Errors
3559+ /// * EINVAL - length is negative
3560+ ///
3561+ /// ### Panics
3562+ /// No Panic is expected from this syscall.
3563+ ///
3564+ /// more details at https://www.man7.org/linux/man-pages/man2/gethostname.2.html
34553565 pub fn gethostname_syscall ( & self , address_ptr : * mut u8 , length : isize ) -> i32 {
3566+ // we only return the default host name (Lind) because we do not allow for the
3567+ // user to change the host name right now
34563568 if length < 0 {
34573569 return syscall_error (
34583570 Errno :: EINVAL ,
@@ -3461,15 +3573,19 @@ impl Cage {
34613573 ) ;
34623574 }
34633575
3576+ // DEFAULT_HOSTNAME is "Lind"
3577+ // we convert the string to vector with a null terminator
34643578 let mut bytes: Vec < u8 > = DEFAULT_HOSTNAME . as_bytes ( ) . to_vec ( ) ;
34653579 bytes. push ( 0u8 ) ; //Adding a null terminator to the end of the string
34663580 let name_length = bytes. len ( ) ;
34673581
3582+ // take the min between name_length and length from argument
34683583 let mut len = name_length;
34693584 if ( length as usize ) < len {
34703585 len = length as usize ;
34713586 }
34723587
3588+ // fill up the address_ptr
34733589 interface:: fill ( address_ptr, len, & bytes) ;
34743590
34753591 return 0 ;
@@ -4251,9 +4367,32 @@ impl Cage {
42514367 return 0 ;
42524368 }
42534369
4254- // all this does is send the net_devs data in a string to libc, where we will
4255- // later parse and alloc into getifaddrs structs
4370+ /// ## ------------------GETIFADDRS SYSCALL------------------
4371+ /// ### Description
4372+ /// The `getifaddrs_syscall()` function creates a linked list of structures
4373+ /// describing the network interfaces of the local system, and stores the
4374+ /// address of the first item of the list in buf.
4375+ ///
4376+ /// ### Function Arguments
4377+ /// The `getifaddrs_syscall()` receives two arguments:
4378+ /// * `buf` - The buffer to hold the returned address
4379+ /// * `count` - The length of the buffer
4380+ ///
4381+ /// ### Returns
4382+ /// On success, zero is returned. Otherwise, errors or panics are returned
4383+ /// for different scenarios.
4384+ ///
4385+ /// ### Errors
4386+ /// * EOPNOTSUPP - buf length is too small to hold the return value
4387+ ///
4388+ /// ### Panics
4389+ /// No Panic is expected from this syscall.
4390+ ///
4391+ /// more details at https://www.man7.org/linux/man-pages/man3/getifaddrs.3.html
42564392 pub fn getifaddrs_syscall ( & self , buf : * mut u8 , count : usize ) -> i32 {
4393+ // all this does is returning the net_devs data in a string, where we will later
4394+ // parse and alloc into getifaddrs structs in libc
4395+
42574396 if NET_IFADDRS_STR . len ( ) < count {
42584397 interface:: fill (
42594398 buf,
0 commit comments