Why the value is changing unexpectedly ? inet_ntoa - c++

I'm trying to create a function which gathers all IPs present on the machine and will be able to detect when the IP in parameter is present. 
The Issue is that the value of the variable containing my IP is changing after an inet_ntoa done on another IN_ADDR.
I tried to use std::string without success. I know inet_ntoa is deprecated but I tried something else without success. Also I would like to understand what I'm doing wrong.
void CIPUtilities::AwaitIPAddress(struct sockaddr_in WFIAddr) {
// also tried with AwaitIPAddress(char * IPName)
char* IPName = inet_ntoa(WFIAddr.sin_addr);
printf("\n Waiting for the IP: %s to be ready.\n", IPName);
int i;
bool ctn = TRUE;
/* Variables used by GetIpAddrTable */
PMIB_IPADDRTABLE pIPAddrTable;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
IN_ADDR IPAddr;
ULONG outBufLen = 0;
ULONG Iterations = 0;
/* Variables used to return error message */
LPVOID lpMsgBuf;
// Allocate a 15 KB buffer to start with.
outBufLen = WORKING_BUFFER_SIZE;
do {
do {
//printf("inside do\n");
Sleep(300); //to be removed ? Only there to avaoid to loop too much.
pIPAddrTable = (MIB_IPADDRTABLE*)MALLOC(outBufLen);
if (pIPAddrTable == NULL) {
printf("Memory allocation failed for GetIpAddrTable\n");
//exit(1); // no need to exit we need debug
}
dwRetVal = GetIpAddrTable(pIPAddrTable, &outBufLen, 0);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
FREE(pIPAddrTable);
pIPAddrTable = NULL;
}
else {
break;
}
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES));
if (dwRetVal == NO_ERROR) {
// If successful, search the IP from the data we retrived
for (i = 0; i < (int)pIPAddrTable->dwNumEntries; i++) {
IPAddr.S_un.S_addr = (u_long)pIPAddrTable->table[i].dwAddr;
printf("1- The value of IPName is %s\n", IPName);
printf("\tIP Address[%d]: \t%s\n", i, inet_ntoa(IPAddr));
printf("2- The value of IPName is %s\n", IPName);
//if (strcmp(IPName, inet_ntoa(IPAddr)) == 0) {
// printf("IP adress[%s] is found in AddrTable\n", inet_ntoa(IPAddr));
// ctn = FALSE; // We exit the loop because the adress is created.
// break; // no need to parse more addresses.
//}
}
}
else
{
printf("GetIpAddrTable failed with error %d\n", dwRetVal);
printf("Required size should be %d\n", dwSize);
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf, 0, NULL)) {
printf("\tError: %s", (char*)lpMsgBuf);
LocalFree(lpMsgBuf);
}
//exit(1); // no need to exit we need debug
}
if (pIPAddrTable) {
FREE(pIPAddrTable);
pIPAddrTable = NULL;
}
} while (ctn);}
Basically the output will be :
Waiting for the IP: 10.0.4.3 to be ready.
1- The value of IPName is 10.0.4.3
IP Address[0]: 160.223.17.135
2- The value of IPName is 160.223.17.135
1- The value of IPName is 160.223.17.135
IP Address[1]: 169.254.165.50
2- The value of IPName is 169.254.165.50
1- The value of IPName is 169.254.165.50
IP Address[2]: 10.0.4.3
2- The value of IPName is 10.0.4.3
1- The value of IPName is 10.0.4.3
IP Address[3]: 10.0.12.44
2- The value of IPName is 10.0.12.44
1- The value of IPName is 10.0.12.44
IP Address[4]: 192.168.0.17
2- The value of IPName is 192.168.0.17
1- The value of IPName is 192.168.0.17
IP Address[5]: 127.0.0.1
2- The value of IPName is 127.0.0.1
1- The value of IPName is 127.0.0.1
I removed some parts of the function to make it more readable.

In short: this happens because you use the returned pointer directly instead of making a copy of the string.
char* IPName = inet_ntoa(WFIAddr.sin_addr);
As stated in the documentation of inet_ntoa (see here for Windows or here for Linux) the result is a pointer to a static buffer:
The string returned is guaranteed to be valid only until the next Windows Sockets function call is made within the same thread. Therefore, the data should be copied before another Windows Sockets call is made.
All you need to do, is copy the contents of the buffer into a string variable.
char IPName[18];
char* temp = inet_ntoa(WFIAddr.sin_addr);
if (temp != NULL)
{
strcpy(IPName, temp);
}
(For details about the size of your buffer see here)
And you should, of course, treat the error case (if temp is NULL)

Related

How to get IP Address from url without gethostbyname in Winsock API

I want to get IP Address from URL. I find the answer in google, it only has gethostbyname() function solution, but MSDN said that this function is not used anymore.
I try to use getaddressinfo() or getnameinfo() (the example in MSDN), it only returns 255.255.255.255.
How can I do? Thank all!
gethostbyname() is indeed deprecated, and getaddrinfo() is the correct function to use now.
You need to parse the URL to extract its hostname, and optionally its port number (see InternetCrackUrl(), or other similar parser), then pass that hostname/port to getaddrinfo(). It will give you back a linked list of addrinfo structs containing each IP address assigned to the host, in sockaddr_in (IPv4) or sockaddr_in6 (IPv6) format.
If you need those IPs as strings, you can use inet_ntop(), RtlIpv4AddressToString()/RtlIpv6AddressToString(), getnameinfo() with the NI_NUMERICHOST flag, etc.
Addresses are obtained by domain name, not by URL.
Here are two functions to get an IPv6 and IPv4 address from a domain name.
Functions parameter is domain_name - domain name (eg dns.google).
The result is local_internet_name - a list of IPv6 or IPv4 addresses depending on the function used (e.g. {[8.8.8.8], [8.8.4.4]} for IPv4 addresses of the dns.google domain)
The return value is the attribute "Addresses found or not found" (true and false).
domain_name_to_internet_6_name
domain_name_to_internet_4_name
The functions use the MFC string classes, the C++ standard library, Windows DNS functions, and network functions.
An example of the output from a test console program:
2001:4860:4860::8888
2001:4860:4860::8844
8.8.8.8
8.8.4.4
D:\Projects\DNS_Test\Debug\DNS_Test.exe (process 14740) exited with code 0.
Press any key to close this window . . .
To create an executable for Windows, in Microsoft Visual Studio, you need to create a project from the "Console Application for Windows" template, and set the project properties to "Use MFC library" (as a shared library or as a static library)
Here's the code for a console program:
#include <afxwin.h>
#include <iostream>
#include <string>
#include <list>
#include <ws2tcpip.h>
#pragma comment(lib, "normaliz.lib")
#pragma comment(lib, "dnsapi.lib")
bool domain_name_to_internet_6_name(CStringW domain_name, std::list<CStringA>& local_internet_name)
{
const size_t CONST_MESSAGE_LENGTH = 500;
wchar_t local_domain_name_unicode[CONST_MESSAGE_LENGTH];
ZeroMemory(local_domain_name_unicode, sizeof(wchar_t) * CONST_MESSAGE_LENGTH);
if (IdnToAscii(0, domain_name, domain_name.GetLength(), local_domain_name_unicode, CONST_MESSAGE_LENGTH) == 0)
{
const int local_error_message_size = 500;
wchar_t local_error_message[local_error_message_size];
const int local_system_error_message_size = local_error_message_size - 250;
wchar_t local_system_error_message[local_system_error_message_size];
wcscpy_s(local_system_error_message, local_system_error_message_size, L"IdnToAscii finished with error");
CString local_time_string = CTime::GetCurrentTime().FormatGmt("%d/%m/%y %H:%M:%S GMT");
wsprintf((wchar_t*)local_error_message, L"Networking error -- %s -- %s\r\n", local_system_error_message, local_time_string.GetBuffer());
// В local_error_message находится текст с кодом сетевой ошибки при выполнении функции IdnToAscii
return false;
}
PDNS_RECORD ppQueryResults;
ZeroMemory(&ppQueryResults, sizeof(ppQueryResults));
if (DnsQuery_W(local_domain_name_unicode, DNS_TYPE_AAAA, 0, NULL, &ppQueryResults, NULL) == ERROR_SUCCESS)
{
for (PDNS_RECORD ptr = ppQueryResults; ptr != NULL; ptr = ptr->pNext)
{
if (ptr->wType == DNS_TYPE_AAAA)
{
if (ptr->wDataLength != 0)
{
char local_address_buffer[100];
inet_ntop(AF_INET6, &ptr->Data.AAAA.Ip6Address.IP6Byte, local_address_buffer, 100);
local_internet_name.push_back(local_address_buffer);
}
}
}
DnsFree(ppQueryResults, DnsFreeRecordList);
if (local_internet_name.size() != 0)
{
return true; // Адреса найдены
}
else
{
return false; // Адреса не найдены
}
return true;
}
return false;
}
bool domain_name_to_internet_4_name(CStringW domain_name, std::list<CStringA>& local_internet_name)
{
const size_t CONST_MESSAGE_LENGTH = 500;
wchar_t local_domain_name_unicode[CONST_MESSAGE_LENGTH];
ZeroMemory(local_domain_name_unicode, sizeof(wchar_t) * CONST_MESSAGE_LENGTH);
if (IdnToAscii(0, domain_name, domain_name.GetLength(), local_domain_name_unicode, CONST_MESSAGE_LENGTH) == 0)
{
const int local_error_message_size = 500;
wchar_t local_error_message[local_error_message_size];
const int local_system_error_message_size = local_error_message_size - 250;
wchar_t local_system_error_message[local_system_error_message_size];
wcscpy_s(local_system_error_message, local_system_error_message_size, L"IdnToAscii finished with error");
CString local_time_string = CTime::GetCurrentTime().FormatGmt("%d/%m/%y %H:%M:%S GMT");
wsprintf((wchar_t*)local_error_message, L"Networking error -- %s -- %s\r\n", local_system_error_message, local_time_string.GetBuffer());
// В local_error_message находится текст с кодом сетевой ошибки при выполнении функции IdnToAscii
return false;
}
PDNS_RECORD ppQueryResults;
ZeroMemory(&ppQueryResults, sizeof(ppQueryResults));
if (DnsQuery_W(local_domain_name_unicode, DNS_TYPE_A, 0, NULL, &ppQueryResults, NULL) == ERROR_SUCCESS)
{
for (PDNS_RECORD ptr = ppQueryResults; ptr != NULL; ptr = ptr->pNext)
{
if (ptr->wType == DNS_TYPE_A)
{
if (ptr->wDataLength != 0)
{
char local_address_buffer[100];
inet_ntop(AF_INET, &ptr->Data.A.IpAddress, local_address_buffer, 100);
local_internet_name.push_back(local_address_buffer);
}
}
}
DnsFree(ppQueryResults, DnsFreeRecordList);
if (local_internet_name.size() != 0)
{
return true; // Адреса найдены
}
else
{
return false; // Адреса не найдены
}
return true;
}
return false;
}
int main()
{
std::list<CStringA> local_internet_name_6;
if (domain_name_to_internet_6_name(CStringW(L"dns.google"), local_internet_name_6))
{
for (auto i = local_internet_name_6.begin(); i != local_internet_name_6.end(); i++)
{
std::cout << *i << std::endl;
}
}
std::list<CStringA> local_internet_name_4;
if (domain_name_to_internet_4_name(CStringW(L"dns.google"), local_internet_name_4))
{
for (auto i = local_internet_name_4.begin(); i != local_internet_name_4.end(); i++)
{
std::cout << *i << std::endl;
}
}
}

poll() method not working in Linux but working in Mac

I am using C++ code snippet for port forwarding. The requirement is to do the hand shake between two ports. It should be two way communication. That is to forward what ever iscoming on the source port to destination port. And then to forward the response of the destination port to the source port.
This piece of code is working as expected on my mac system. But when I am running this code on Linux system I am facing one issue.
Issue:
The C++ code that I am using is having 3 parts:
establish_connection_to_source();
open_connection_to_destination();
processconnetion();
On Linux: establish_connection_to_source(); and open_connection_to_destination(); is working perfectly fine. But processconnetion(); is havng one issue.
Following is the process connection method:
void processconnetion()
{
buffer *todest = new buffer(socket_list[e_source].fd,socket_list[e_dest].fd);
buffer *tosrc = new buffer(socket_list[e_dest].fd,socket_list[e_source].fd);
if (todest == NULL || tosrc == NULL){
fprintf(stderr,"out of mememory\n");
exit(-1);
}
unsigned int loopcnt;
profilecommuncation srcprofile(COMM_BUFSIZE);
profilecommuncation destprofile(COMM_BUFSIZE);
while (true) {
int withevent = poll(socket_list, 2, -1);
loopcnt++;
fprintf(stderr,"loopcnt %d socketswith events = %d source:0x%x dest:0x%x\n", loopcnt, withevent, socket_list[e_source].revents, socket_list[e_dest].revents);
if ((socket_list[e_source].revents | socket_list[e_dest].revents) & (POLLHUP | POLLERR)) {
// one of the connections has a problem or has Hungup
fprintf(stderr,"socket_list[e_source].revents= 0x%X\n", socket_list[e_source].revents);
fprintf(stderr,"socket_list[e_dest].revents= 0x%X\n", socket_list[e_dest].revents);
fprintf(stderr,"POLLHUP= 0x%X\n", POLLHUP);
fprintf(stderr,"POLLERR= 0x%X\n", POLLERR);
int result;
socklen_t result_len = sizeof(result);
getsockopt(socket_list[e_dest].fd, SOL_SOCKET, SO_ERROR, &result, &result_len);
fprintf(stderr, "result = %d\n", result);
fprintf(stderr,"exiting as one connection had an issue\n");
break;
}
if (socket_list[e_source].revents & POLLIN) {
srcprofile.increment_size(todest->copydata());
}
if (socket_list[e_dest].revents & POLLIN) {
destprofile.increment_size(tosrc->copydata());
}
}
delete todest;
delete tosrc;
close(socket_list[e_source].fd);
close(socket_list[e_dest].fd);
srcprofile.dumpseensizes("source");
destprofile.dumpseensizes("destination");
}
Here it is giving error - exiting as one connection had an issue that means that if ((socket_list[e_source].revents | socket_list[e_dest].revents) & (POLLHUP | POLLERR)) is returning true. The issue is with the destination port and not in case of source.
Note:
Variales used in the processconnetion(); method:
socket_list is a structure of type pollfd. Following is the description:
struct pollfd {
int fd;
short events;
short revents;
};
pollfd socket_list[3];
#define e_source 0
#define e_dest 1
#define e_listen 2
Following is the output at the time for exit:
connecting to destination: destination IP / 32001.
connected...
loopcnt 1 socketswith events = 1 source:0x0 dest:0x10
socket_list[e_source].revents= 0x0
socket_list[e_dest].revents= 0x10
POLLHUP= 0x10
POLLERR= 0x8
result = 0
exiting as one connection had an issue
int withevent = poll(socket_list, 2, -1); here the withevent value returned is 1
Socket List Initialisation:
guard( (socket_list[e_listen].fd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP )), "Failed to create socket listen, error: %s\n", "created listen socket");
void guard(int n, char *msg, char *success)
{
if (n < 0) {
fprintf(stderr, msg, strerror(errno) );
exit(-1);
}
fprintf(stderr,"n = %d %s\n",n, success);
}
I am not able to figure out the issue as it is working fine in mac. Any leads why this behaviour in Linux is highly appreciated. Thanks in advance.

How to get number of connections on PORT per IP in Windows?

I have been searching around Google for some time and I can`t seem to find an answer...
I am using GetExtendedTcpTable() to view my current connections, but I am unable to get the number of connections that each IP does on a specific PORT.
Is there any example/function for this ? Or do I have to create something ?
Any guidance or example is much appreciated.
Have a nice day!
So using this code from MSDN as the basis we end up with this example which enumerates a list of connections, populating the pointer to int ports with the number of connections from remote systems to the local ports.
To determine the number of connections to a particular local port, you can simply print out the value of ports[port].
The code as supplied is very much more C, than C++, I just used a new[] and delete[] for the ports.
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
#define MALLOC(x) calloc(1, (x))
#define FREE(x) free((x))
int main()
{
// Declare and initialize variables
PMIB_TCPTABLE_OWNER_PID pTcpTable;
int *ports; // an array of all the possible ports
DWORD dwSize = 0;
DWORD dwRetVal = 0;
char szRemoteAddr[128];
struct in_addr IpAddr;
int i;
ports = new int[1 << (sizeof(u_short) * 8)]();
pTcpTable = (MIB_TCPTABLE_OWNER_PID *)MALLOC(sizeof(MIB_TCPTABLE_OWNER_PID));
if (pTcpTable == NULL) {
printf("Error allocating memory\n");
return 1;
}
dwSize = sizeof(MIB_TCPTABLE);
// Make an initial call to GetTcpTable to
// get the necessary size into the dwSize variable
if ((dwRetVal = GetExtendedTcpTable(pTcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_BASIC_CONNECTIONS, 0)) ==
ERROR_INSUFFICIENT_BUFFER) {
FREE(pTcpTable);
pTcpTable = (MIB_TCPTABLE_OWNER_PID *)MALLOC(dwSize);
if (pTcpTable == NULL) {
printf("Error allocating memory\n");
return 1;
}
}
// Make a second call to GetTcpTable to get
// the actual data we require
if ((dwRetVal = GetExtendedTcpTable(pTcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_BASIC_CONNECTIONS, 0)) == NO_ERROR) {
printf("\tNumber of entries: %d\n", (int)pTcpTable->dwNumEntries);
for (i = 0; i < (int)pTcpTable->dwNumEntries; i++) {
printf("\n\tTCP[%d] State: %ld - ", i,
pTcpTable->table[i].dwState);
if (pTcpTable->table[i].dwState != MIB_TCP_STATE_ESTAB)
continue;
// get the port in host order
u_short port = ntohs((u_short)pTcpTable->table[i].dwLocalPort);
ports[port] += 1; // increment this port
IpAddr.S_un.S_addr = (u_long)pTcpTable->table[i].dwRemoteAddr;
inet_ntop(AF_INET, &IpAddr, szRemoteAddr, sizeof(szRemoteAddr));
printf("\tTCP[%d] Remote Addr: %s:%d\n", i, szRemoteAddr, ntohs((u_short)pTcpTable->table[i].dwRemotePort));
}
}
else {
printf("\tGetExtendedTcpTable failed with %d\n", dwRetVal);
FREE(pTcpTable);
delete[] ports;
return 1;
}
if (pTcpTable != NULL) {
FREE(pTcpTable);
pTcpTable = NULL;
}
delete[] ports;
return 0;
}
Now if you wanted a list of the remote addresses coming to a port, then you could make a std::vector<std::string> remote_addresses and perform a remote_addresses.push_back(szRemoteAddr) when you determined that the port was correct.
There is a potential race condition where between the initial call to GetExtendedTcpTable and the subsequent call to GetExtendedTcpTable another connection comes in, which increases the value of dwSize. Generally asking for more memory helps in this case to just prevent this from being an issue - i.e. after the initial call, try asking for 8K more than you need - it's not likely to be a big issue, though.

how to print the MAC address

i created a client server program that displays the MAC and ip addresses of the clients and i have a function that gets the MAC address of the computer but I'm having trouble printing the MAC address in a listbox. I created a print function that did work before but i changed the code for finding the mac address and now its not working (also i don't know if i'm calling printMACaddress in the right place). I have two list boxes - one displays the ip address the other displays the MAC address. When i click the ip address i want the MAC address of that computer to be displayed but right now its not displaying. nothing happens when i click the ip address
void CmfcServerDlg::OnLbnSelchangeListClientaddr()
{
bool GetMACFromIP(BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH], const std::string &selected_ip_adr);
}
void CmfcServerDlg::PrintMACaddress(unsigned char MACData[])
{
CString
strText;
strText.Format("%02X-%02X-%02X-%02X-%02X-%02X\n",MACData[0], MACData[1], MACData[2], MACData[3], MACData[4], MACData[5]);
m_ClientIdList.AddString(strText);
}
bool CmfcServerDlg::GetMACFromIP(BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH], const std::string &selected_ip_adr)
{
IP_ADAPTER_INFO AdapterInfo[16];
DWORD dwBufLen = sizeof(AdapterInfo);
DWORD dwStatus = GetAdaptersInfo(
AdapterInfo,
&dwBufLen);
assert(dwStatus == ERROR_SUCCESS);
PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;
bool found = false;
do {
const IP_ADDR_STRING *addr_str = &pAdapterInfo->IpAddressList;
while(addr_str != NULL)
{
if(selected_ip_adr == addr_str->IpAddress.String)
{
found = true;
break;
}
}
if(found)
{
memcpy(Address, pAdapterInfo->Address, MAX_ADAPTER_ADDRESS_LENGTH);
PrintMACaddress(pAdapterInfo->Address); //problem here
break;
}
else
{
PrintMACaddress(pAdapterInfo->Address);
pAdapterInfo = pAdapterInfo->Next;
}
}
while(pAdapterInfo);
return found;
}
You do realize that your stated goal in the comment ("i am trying to find the MAC address of any computer that connects to the server") is not possible? MAC addresses are lower-level than IP addresses, they identify the "media port", i.e. the place where the cable sits.
You cannot get the MAC address for a client on the other side of a switch even, much less across the Internet.

C++ code to find BSSID OF associated network [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Want to know the ESSID of wireless network via C++ in UBUNTU
Hello I have written the following code which is a part of a project. It is used to find the ESSID of the current associated network. But it has a flaw that it also the displays the ESSID of the network with which I am not associated i.e. if I try to associate myself with a wireless n/w and if it is unsuccessfull i.e. NO DHCP OFFERS ARE RECEIVED, then also it will display the that ESSID with which I have made my attempt.
Is it possible to find the BSSID of current associated wireless network as it is the only way with which I can mark b/w associated and non associated, e.g. with an ioctl call?
int main (void)
{
int errno;
struct iwreq wreq;
CStdString result = "None";
int sockfd;
char * id;
char ESSID[20];
memset(&wreq, 0, sizeof(struct iwreq));
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
fprintf(stderr, "Cannot open socket \n");
fprintf(stderr, "errno = %d \n", errno);
fprintf(stderr, "Error description is : %s\n",strerror(errno));
return result ;
}
CLog::Log(LOGINFO,"Socket opened successfully");
FILE* fp = fopen("/proc/net/dev", "r");
if (!fp)
{
// TBD: Error
return result;
}
char* line = NULL;
size_t linel = 0;
int n;
char* p;
int linenum = 0;
while (getdelim(&line, &linel, '\n', fp) > 0)
{
// skip first two lines
if (linenum++ < 2)
continue;
p = line;
while (isspace(*p))
++p;
n = strcspn(p, ": \t");
p[n] = 0;
strcpy(wreq.ifr_name, p);
id = new char[IW_ESSID_MAX_SIZE+100];
wreq.u.essid.pointer = id;
wreq.u.essid.length = 100;
if ( ioctl(sockfd,SIOCGIWESSID, &wreq) == -1 ) {
continue;
}
else
{
strcpy(ESSID,id);
return ESSID;
}
free(id);
}
free(line);
fclose(fp);
return result;
}
Note: Since this question seems to be duplicated in two places, I'm repeating my answer here as well.
You didn't mention whether you were using an independent basic service set or not (i.e., an ad-hoc network with no controlling access point), so if you're not trying to create an ad-hoc network, then the BSSID should be the MAC address of the local access point. The ioctl() constant you can use to access that information is SIOCGIWAP. The ioctl payload information will be stored inside of your iwreq structure at u.ap_addr.sa_data.