Subject: raw socket at link level
To: 'tech-net@netbsd.org' <tech-net@netbsd.org>
From: James Braswell <James.Braswell@quantum.com>
List: tech-net
Date: 03/08/1999 09:06:05
I am trying to write to a raw socket, providing the ether_header, ip header,
udp header, the usr data. I make the following function calls to set up and
use the socket:
if ( (sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
{
syslog (LOG_INFO, "sendraw: socket error %d", errno);
return;
}
if ( setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &optval, sizeof
(optval)) < 0 )
{
syslog (LOG_INFO, "sendraw: setsocketopt error %d", errno);
return;
}
bzero ((char*)&name, sizeof (name));
dpp = (struct sockaddr_in*)&name;
dpp->sin_family = AF_INET;
dpp->sin_port = 61166; // arbitrarily picked
dpp->sin_len = sizeof(struct sockaddr_in);
if (bind ( sock, &name, sizeof (struct sockaddr)) < 0)
{
syslog (LOG_INFO, "sendraw: bind sock error %d", errno);
return;
}
the headers are setup as follows:
ether_header
for (i = 0; i < ETHER_ADDR_LEN; i++)
{
ep->ether_dhost[i] = 0xff; // broadcast
ep->ether_shost[i] = ourhp->our_etherAddr[i];
}
ep->ether_type = htons( ETHERTYPE_IP);
ip header
ip = (struct ip*)(buf + sizeof (struct ether_header));
ip->ip_v = 4;
// ip->ip_hl = htons(sizeof (struct ip) >> 2);
ip->ip_hl = sizeof (struct ip) >> 2;
have tried both of the above
ip->ip_tos = 0; //IPTOS_LOWDELAY;
// ip->ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) +
datalen);
ip->ip_len = sizeof(struct ip) + sizeof(struct udphdr) + datalen;
have tried both of the above
ip->ip_id = 0;
ip->ip_off = 0;
ip->ip_ttl = 16;
ip->ip_p = IPPROTO_UDP;
ip->ip_src.s_addr = our_addr->our_ipAddr.s_addr;
// from
ip->ip_dst.s_addr = 0xffffffff;
// to - broadcast
/* Checksum the IP header... */
ip->ip_sum = 0;
ip->ip_sum = htons(chk_sum ((unsigned char *)ip, sizeof (struct ip),
0));
// ip->ip_sum = chk_sum ((unsigned char *)ip, sizeof (struct ip), 0);
I have tried both of the above
udp hdr
udp = (struct udphdr*)(buf + sizeof(struct ether_header) + sizeof
(struct ip));
udp->uh_sport = src_port;
udp->uh_dport = dest_port
// udp->uh_ulen = htons(sizeof(struct udphdr) + datalen);
udp->uh_ulen = sizeof(struct udphdr) + datalen;
have tried both of the above
udp->uh_sum = 0;
// udp->uh_sum = chk_sum ((unsigned char *)udp, sizeof (struct udphdr),
0);
udp->uh_sum = htons (chk_sum ((unsigned char *)udp, sizeof (struct
udphdr), 0));
have tried both the above
/* add usr data after headers */
cp = (char*) (buf + hdrlen);
bcopy(pData, cp, datalen);
dpp = (struct sockaddr_in*)&source;
dpp->sin_addr.s_addr = 0xffffffff;
sap = (struct sockaddr*)dpp;
ret = sendto (sock, buf, hdrlen + datalen, 0, sap, sizeof (struct
sockaddr));
if (ret < 0)
{
syslog (LOG_INFO, "sendto error return %d", errno);
}
the error return is EINVAL (22): "The total length of the I/O is more than
can be expressed by the ssize_t return value."
hdrlen = 42
datalen = 132
Does anyone see the problem(s)??
regards
jim Braswell