Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Jan 2002 22:58:22 -0500
From:      Florent Parent <Florent.Parent@viagenie.qc.ca>
To:        Archie Cobbs <archie@dellroad.org>
Cc:        freebsd-net@FreeBSD.ORG
Subject:   Re: netgraph: how to setsockopt on ksocket node ?
Message-ID:  <214190000.1011326302@blues.viagenie.qc.ca>
In-Reply-To: <200201180216.g0I2G8k23055@arch20m.dellroad.org>
References:   <200201180216.g0I2G8k23055@arch20m.dellroad.org>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]


--On 2002-01-17 18:16:08 -0800 archie@dellroad.org wrote:

> Florent Parent writes:
>> Anyone has an example on how to setsockopt on a ksocket node in netgraph?
>>
>>     struct opts {
>>         int level;
>>         int name;
>>         int value;
>>     } myopts = { SOL_SOCKET, SO_REUSEADDR, 1
>>     };
>>
>>     ret = NgSendMsg(cs, epath, NGM_KSOCKET_COOKIE, NGM_KSOCKET_SETOPT,
>>                           (struct ng_ksocket_sockopt *)&myopts,
>> sizeof(myopts)));
>>
>> return error 14 "Bad address".
>>
>> Did some tracing in ng_ksocket.c and the struct sockopt sent as argument
>> to  sosetopt() seems to contains sane values:
>>
>> sopt.sopt_val = 0xc182452c  (pointer dereferences to 1)
>> sopt.sopt_valsize = 4
>
> What kind of socket?

UDP

>
> What version of FreeBSD?

4.5-PRERELEASE (~ 2 weeks old)


> That should work.. if the error is coming from the sosetopt()
> call then it's a socket problem rather than a netgraph problem.
>
> What if you create the socket normally and call setsockopt()?

Well that works just fine. I've attached normal.c which is a dummy example 
using standard socket calls, and I've attached netgraph.c which wants to do 
the same thing using a ksocket node. The latter fails with the following 
debug:

netgraph: SENDING MESSAGE:
netgraph: SOCKADDR: { fam=32 len=9 addr=".dummy" }
netgraph: NG_MESG :
netgraph:   vers   2
netgraph:   arglen 12
netgraph:   flags  0
netgraph:   token  3
netgraph:   cookie KSOCKET (942710669)
netgraph:   cmd    7
netgraph:   args (12 bytes)
netgraph: 0000:  ff ff 00 00 00 02 00 00 01 00 00 00 
............
netgraph: sendto(.dummy): Bad address
.dummy Cannot setopt the ksocket node: Bad address


It has to be the way I'm presenting the socket options arguments through 
the netgraph interface. This is why I originally asked for any example on 
doing a setsockopt through netgraph.

Thanks for the help

Florent.

[-- Attachment #2 --]

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>

#include <netgraph.h>
#include <netgraph/ng_message.h>
#include <netgraph/ng_ksocket.h>

#define DEBUG

#define SERVADDR "192.168.31.2" 
#define SERV_PORT 2002  

int main(int argc, char **argv)
{
    int cs, ds;
    int ret;
    struct ngm_mkpeer ksock;
    struct sockaddr_in sin;
    char epath[128];

    struct opts {
        int level;
        int name;
        int value;
    } myopts;

    myopts.level = SOL_SOCKET;
    myopts.name  = SO_REUSEPORT;
    myopts.value = 1;
    
      /* Create a socket node */
    if (NgMkSockNode(NULL, &cs, &ds) == -1) {
        perror("Cannot create netgraph socket node");
        return -1;
    }
    sprintf(epath, ".");
    snprintf(ksock.type, sizeof (ksock.type), "%s", NG_KSOCKET_NODE_TYPE);
    snprintf(ksock.ourhook, sizeof (ksock.ourhook), "%s", "dummy");
    snprintf(ksock.peerhook, sizeof (ksock.peerhook), "%s", "inet/dgram/udp");

    if ( (ret = NgSendMsg(cs, epath, NGM_GENERIC_COOKIE, NGM_MKPEER, &ksock, sizeof ksock)) < 0) {
      fprintf(stderr, "%s Cannot create an ksocket node: %s\n",
              epath, strerror(errno));
      exit(-1);
    }
    
#ifdef DEBUG
    NgSetDebug(2);
#endif
    
    sprintf(epath, ".%s", ksock.ourhook);
    
    if ( (ret = NgSendMsg(cs, epath, NGM_KSOCKET_COOKIE, NGM_KSOCKET_SETOPT,
                          (struct ng_ksocket_sockopt *)&myopts, sizeof(myopts))) < 0) {
        fprintf(stderr, "%s Cannot setopt the ksocket node: %s\n",
                epath, strerror(errno));
//        exit (-1);
    }
 
    
        /* Bind the ksocket to our IPv4 address and our UDP source port */
    bzero(&sin, sizeof(sin));
    sin.sin_len = sizeof(sin);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(SERV_PORT);
    inet_pton(AF_INET, SERVADDR, &sin.sin_addr);

    if ( (ret = NgSendMsg(cs, epath, NGM_KSOCKET_COOKIE, NGM_KSOCKET_BIND,
                          (struct sockaddr *)&sin, sizeof(sin))) < 0) {
        fprintf(stderr, "%s Cannot bind the ksocket node: %s\n",
                epath, strerror(errno));
        exit (-1);
    }
    
    getchar();
    
    exit (0);
}


[-- Attachment #3 --]

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>


#define SERVADDR "192.168.31.2" 
#define SERV_PORT 2002  

int main(int argc, char **argv)
{
    int sockfd;
    struct sockaddr_in servaddr; 
    const int on = 1;
    
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    inet_pton(AF_INET, SERVADDR, &servaddr.sin_addr);
    
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1) {
        perror("socket");
        exit(1);
    }
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) == -1) {
        perror("sockopt");
        exit(1);
    }
    if (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) == -1) {
        perror("bind");
        exit(1);
    }
    getchar();
    exit(0);
    
}

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?214190000.1011326302>