---
name: "ident"
section: "3"
platform: "linux"
package: "libident-dev"
version: "0.32-4+b2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/ident/3"
---

# ident(3)

query remote IDENT server

## NAME

ident\_lookup, ident\_id, ident\_free, id\_open\_addr, id\_open, id\_close, id\_query, id\_parse, id\_fileno - query remote IDENT server

## SYNOPSIS

```
#include <ident.h>
```

*High-level calls*

**IDENT \*ident\_lookup(int fd, int timeout)**

**char \*ident\_id(int fd, int timeout)**

**void ident\_free(IDENT \*id)**

*Low-level calls*

**ident\_t \*id\_open\_addr (const struct sockaddr \*laddr,** **const struct sockaddr \*faddr, struct timeval \*timeout)** **ident\_t \*id\_open(const struct in\_addr \*laddr,** **const struct in\_addr \*faddr, struct timeval \*timeout)**

**int id\_close(ident\_t \*id)**

**int id\_query(ident\_t \*id, int lport, int fport,** **struct timeval \*timeout)**

**int id\_parse(ident\_t \*id, struct timeval \*timeout,** **int \*lport, int \*fport,** **char \*\*identifier, char \*\*opsys, char \*\*charset)**

**int id\_fileno(ident\_t \*id)**

## DESCRIPTION

**ident\_lookup** **tries to connect to a remote** **IDENT** **server to establish the identity of the peer connected on** *fd,* **which should be a socket file descriptor.** *timeout* **is the longest permissible time to block waiting for an answer, and is** **given in seconds. A value of 0 (zero) means wait indefinitely (which in the** **most extreme case will normally be until the underlying network times out).** **ident\_lookup** **returns a pointer to an** *IDENT* **struct, which has the following contents:**

```
typedef struct {
	int lport;		/* Local port */
	int fport;		/* Far (remote) port */
	char *identifier;	/* Normally user name */
	char *opsys;		/* OS */
	char *charset;		/* Charset (what did you expect?) */
} IDENT;
```

For a full description of the different fields, refer to *RFC-1413.*

All data returned by **ident\_lookup** (including the IDENT struct) points to malloc'd data, which can be freed with a call to **ident\_free.** **ident\_lookup** returns 0 on error or timeout. Presently, this should normally be taken to mean that the remote site is not running an IDENT server, but it might naturally be caused by other network related problems as well. **Note that** all fields of the IDENT struct need not necessarily be set.

**ident\_id** takes the same parameters as **ident\_lookup** but only returns a pointer to a malloc'd area containing the *identifier* string, which is probably the most wanted data from the IDENT query. You should free() the result manually.

**ident\_free** frees all data areas associated with the IDENT struct pointed to by *id,* including the struct itself.

*Low-level calls*

The low-level calls can be used when greater flexibility is needed. For example, if non-blocking I/O is needed, or multiple queries to the same host are to be made.

**id\_open\_addr** and **id\_open** both open a connection to the remote **IDENT** server referred to by  *faddr*. The timeout is specified by *timeout*. A null-pointer means wait indefinitely, while a pointer to a zero-valued *timeval* struct sets non-blocking I/O, in the same way as for [**select**(2)](/select/2.md). **id\_open\_addr** and **id\_open** return a pointer to an **id\_t** data, which is an opaque structure to be used as future reference to the opened connection. When using non-blocking I/O it might however be useful to access the underlying socket file descriptior, which can be gotten at through the **id\_fileno** macro described below. While **id\_open** only works with  *IPv4* 32-bits addresses,  **id\_open\_addr** expects complete **sockaddr** structures. At the moment, it supports **sockaddr\_in** (AF\_INET) and  **sockaddr\_in6** (AF\_INET6) structures. **id\_open\_addr** was first introduced in **libident** version 0.30.

**id\_close** closes the connection opened with **id\_open** and frees all data associated with *id.*

**id\_query** sends off a query to a remote IDENT server. *lport* and *fport* are sent to the server to identify the connection for which identification is needed. *timeout* is given as for **id\_open.** If successful, **id\_query** returns the number of bytes sent to the remote server. If not, -1 is returned and **errno** is set.

**id\_parse** parses the reply to a query sent off by **id\_query** and returns information to the locations pointed to by *lport, fport, identifier, opsys* and *charset.* For string data *(identifier, opsys* and *charset)* pointers to malloc'd space are returned.

**id\_parse** returns:

- 1

  If completely successful.

- \-3

  Illegal reply type from remote server. *identifier* is set to the illegal reply.

- \-2

  Cannot parse the reply from the server. *identifier* is normally set to the illegal reply.

- \-1

  On general errors or timeout.

- 0

  When non-blocking mode is set and **id\_parse** has not finished parsing the reply from the remote server.

- 2

  Indicates the query/reply were successful, but the remote server experienced some error. *identifier* is set to the error message from the remote server.

For all errors, *errno* is set as appropriate.

**id\_fileno** is a macro that takes an **id\_t** handle and returns the actual socket file descriptor used for the connection to the remote server.

## ERRORS

- ETIMEDOUT

  The call timed out and non-blocking I/O was not set.

## EXAMPLES

Here's an example how to handle the reply from id\_reply() in the case that non-blocking I/O is set. Note that id\_reply() will return 0 as long as it's not finished parsing a reply.

```
int rcode;
id_t idp;
/* ... */
idp = id_open_addr(...);
if (idp == NULL)
{
  perror ("id_open_addr");
  /* ... */
}
/* ... */
while ((rcode = id_parse(idp, timeout,
			 &lport, &fport, &id, &op, &cs)) == 0)
	;
if (rcode < 0)
{
  if (errno == ETIMEDOUT)
    foo();	/* Lookup timed out */
  else
    bar();      /* Fatal error */
}
else if (rcode == 1)
{
  /* Valid USERID protocol reply */
}
else if (rcode == 2)
{
  /* Protocol ERROR reply */
}
```

## SEE ALSO

RFC-1413, [socket(2)](/socket/2.md), [select(2)](/select/2.md)

## AUTHORS

Peter Eriksson \<*pen@lysator.liu.se*\>\
 P"ar Emanuelsson \<*pell@lysator.liu.se*\>\
 Rémi Denis-Courmont \<*rdenis (at) simphalempin (dot) com*\>

## BUGS

For **ident\_lookup** and **ident\_id** the blocking time in extreme cases might be as much as three times the value given in the *timeout* parameter.
