Search code examples
javaraw-sockets

How to send a raw packet on a unix socket in java


I know that java needs 3rd party libraries to use unix sockets. Im using junixsocket.

How do i send an unconnected datagram on a unix socket in java without a specific filepathname?

I need to send some data (say an ip address) to an application which acks as a server and is written in c. My java code would be a client. I dont want it to be dependent on a path, as on the server side the c code is not listening on a particular path but is polling on a raw unix socket defined as socket(AF_UNIX, SOCK_RAW, 0); which does'nt have a specific filepath name. Thanks!

This is a part of the server code in c that listens on the raw unix socket with a poll() function. The main functions is at the bottom and the poll is int the event_loop() function just above the main.

#include "lib.h"
#include "udp.h"

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>

struct eid_lookup {
    union sockunion eid;        /* Destination EID */
    int rx;                     /* Receiving socket */
    // more parameters.
    struct timespec start;      /* Start time of lookup */
    uint64_t active;            /* Unique lookup identifier, 0 if inactive */
    union sockunion * mr;       /* Point to mapresolver */
};

struct eid_lookup lookups[MAX_LOOKUPS];
struct pollfd fds[MAX_LOOKUPS + 1];
int fds_idx[MAX_LOOKUPS +1];
nfds_t nfds = 0;
struct protoent     *proto;
int udpproto;
int seq;
int openlispsck;


static void map_message_handler(union sockunion * mr);
int check_eid(union sockunion *eid);
void  new_lookup(union sockunion *eid,  union sockunion * mr);
int  send_mr(int idx);
int read_rec(union map_reply_record_generic * rec);

    size_t
_get_sock_size(union sockunion * eid)
{
    size_t ss_len;
    switch (eid->sa.sa_family){
        case AF_INET:
            ss_len = sizeof(struct sockaddr_in);
            break;
        default:
            fprintf(OUTPUT_ERROR, "AF not support::%d\n",eid->sa.sa_family);
            return -1;
    }
    return ss_len;
}

    int
sockunioncmp(void * m, void * n)
{
    union sockunion * sp, * dp;
    sp = m; dp = n;
    if(sp->sa.sa_family != dp->sa.sa_family)
        return -1;

    switch (sp->sa.sa_family){
        case AF_INET:
            return memcmp(&sp->sin.sin_addr, &dp->sin.sin_addr,sizeof(struct in_addr));
            break;
        default:
            return -1;
    }
    return -1;      
}

/* Process message from Openlis socket */
    static void 
map_message_handler(union sockunion * mr)
{

    struct timespec now;
    char msg[PSIZE];         /* buffer for mapping messages */
    int n = 0;              /* number of bytes received on mapping socket */
    union sockunion *eid;

    n = read(lookups[0].rx, msg, PSIZE);
    clock_gettime(CLOCK_REALTIME, &now);


    printf("%" PRIu16 "\n",((struct map_msghdr *)msg)->map_type);

    eid = (union sockunion *)CO(msg,sizeof(struct map_msghdr));

    printf("map_type: %" PRIu16 "\n",((struct map_msghdr *)msg)->map_type);

    //i Added this, but im not sure its fully required. It has some propertyies of the map db
    if (((struct map_msghdr *)msg)->map_type == MAPM_MISS_EID) {
            printf("Im in the 1 if\n");
            eid = (union sockunion *)CO(msg,sizeof(struct map_msghdr));
            if (check_eid(eid)) {
                printf("Im in the 2 if\n");
                new_lookup(eid, mr);
            }
        }

}

/*Check if an EID-prefix exist in poll */
    int 
check_eid(union sockunion *eid)
{
    int i;

    for (i = 1; i < MAX_LOOKUPS; i++)
        if (lookups[i].active)
            if (!memcmp(eid, &lookups[i].eid, _get_sock_size(eid))){                
                return 0;               
            }
    return 1;
}

/*Add new EID to poll*/
    void 
new_lookup(union sockunion *eid,  union sockunion * mr)
{


    int i,e,r;
    uint16_t sport;             /* inner EMR header source port */
    char sport_str[NI_MAXSERV]; /* source port in string format */
    struct addrinfo hints;
    struct addrinfo *res;

    /* Find an inactive slot in the lookup table */
    for (i = 1; i < MAX_LOOKUPS; i++)
        if (!lookups[i].active)
            break;

    if (i >= MAX_LOOKUPS) {
        return;
    }

    /*new socket for map-request */
    if ((r = socket(mr->sa.sa_family, SOCK_DGRAM, udpproto)) < 0) {
        fprintf(OUTPUT_ERROR, "Error when create new socket\n");
        return;
    }

    /*random source port of map-request */
    e = -1;
    while (e == -1){
        sport = MIN_EPHEMERAL_PORT + random() % (MAX_EPHEMERAL_PORT - MIN_EPHEMERAL_PORT);
        sprintf(sport_str, "%d", sport);
        memset(&hints, 0, sizeof(struct addrinfo));
        hints.ai_family    = mr->sa.sa_family; 
        hints.ai_socktype  = SOCK_DGRAM;                
        hints.ai_flags     = AI_PASSIVE;                
        hints.ai_canonname = NULL;
        hints.ai_addr      = NULL;
        hints.ai_next      = NULL;

        if ((e = getaddrinfo(NULL, sport_str, &hints, &res)) != 0) {
            fprintf(OUTPUT_ERROR, "getaddrinfo: %s\n", gai_strerror(e));    
            e = -1;
            continue;
        }

        if ((e = bind(r, res->ai_addr, res->ai_addrlen)) == -1) {
            fprintf(OUTPUT_ERROR, "bind error to port %s\n", sport_str);
            e = -1;
            continue;
        }
        freeaddrinfo(res);
    }

    memcpy(&lookups[i].eid, eid, _get_sock_size(eid));
    lookups[i].rx = r;
    lookups[i].sport = sport;
    clock_gettime(CLOCK_REALTIME, &lookups[i].start);
    lookups[i].count = 0;
    lookups[i].active = 1;
    if(mr->sa.sa_family == AF_INET)
        mr->sin.sin_port = htons(LISP_CP_PORT);
    lookups[i].mr = mr;
    send_mr(i);
}

/* Send map-request */
    int 
send_mr(int idx)
{

    uint32_t nonce0, nonce1;
    int cnt;
    union sockunion *eid;
    char buf[PSIZE];
    struct lisp_control_hdr * lh;
    struct ip * ih; 
    struct ip6_hdr *ih6;
    struct udphdr * udp ;
    struct map_request_hdr * lcm;
    union afi_address_generic * itr_rloc;
    union map_request_record_generic * rec;
    union afi_address_generic afi_addr_src;
    union afi_address_generic afi_addr_dst;
    uint8_t * ptr;
    int sockaddr_len;
    size_t itr_size, ip_len;
    char ip[INET6_ADDRSTRLEN];
    int mask; 
    eid = &lookups[idx].eid;
    if (lookups[idx].count >= COUNT) {
        lookups[idx].active = 0;
        close(lookups[idx].rx);
        return 0;
    }
    bzero(buf,PSIZE);
    lh = (struct lisp_control_hdr *)buf;
    ih = (struct ip *)CO(lh, sizeof(struct lisp_control_hdr));
    ih6 = (struct ip6_hdr *)CO(lh, sizeof(struct lisp_control_hdr));

    /*choose source/destionation ip */
    switch (lookups[idx].mr->sa.sa_family ){
        case AF_INET:
            afi_addr_dst.ip.afi = AF_INET;
            memcpy(&afi_addr_dst.ip.address,(struct in_addr *)&(lookups[idx].mr->sin.sin_addr),sizeof(struct in_addr));
            afi_addr_src.ip.afi = AF_INET;
            memcpy(&afi_addr_src.ip.address,(struct in_addr *)(src_addr[0]),sizeof(struct in_addr));
            udp = (struct udphdr *)CO(ih, sizeof(struct ip));
            sockaddr_len = sizeof(struct sockaddr_in);
            break;
        default:
            fprintf(OUTPUT_ERROR,"AF not support\n");
            return -1;
    }

    lcm = (struct map_request_hdr*)CO(udp, sizeof(struct udphdr));

    /*build message header*/
    /* set all the LISP flags  */
    uint64_t nonce;

    _make_nonce(&nonce);
    nonce0 = (uint32_t)(*(uint32_t *)&nonce);
    nonce1 = (uint32_t)(*(uint32_t *)(&nonce0+1));


    /* set no source EID <AFI=0, addres is empty> -> jump of 2 bytes */
    /* nothing to do as bzero of the packet at init */
    itr_rloc = (union afi_address_generic *)CO(lcm, sizeof(struct map_request_hdr) + 2);

    itr_size = SA_LEN(afi_addr_src.ip.afi);
    memcpy(itr_rloc, &afi_addr_src, itr_size);
    /* set source ITR */
    switch(afi_addr_src.ip.afi){
        case AF_INET:
            itr_rloc->ip.afi = htons(LISP_AFI_IP);
            itr_size = sizeof(struct afi_address);
            break;
        default:
            printf("not supported\n");
            return (FALSE);
    }
    rec = (union map_request_record_generic *)CO(itr_rloc, itr_size);

    /* assign correctly the EID prefix */
    switch(eid->sa.sa_family){
        case AF_INET:
            /* EID prefix is an IPv4 so 32 bits (4 bytes) */
            rec->record.eid_mask_len = mask = 32;
            rec->record.eid_prefix_afi = htons(LISP_AFI_IP);
            memcpy(&rec->record.eid_prefix, &(eid->sin.sin_addr), sizeof(struct in_addr));  
            inet_ntop(AF_INET, (void *)&rec->record.eid_prefix, ip, INET6_ADDRSTRLEN);
            ptr = (uint8_t *)CO(rec,4+4);   
            break;
        default:
            printf("not supported\n");
            return (FALSE);
    }

    /* set the UDP parameters */
    udp->source = htons(lookups[idx].sport);
    udp->dest = htons(LISP_CP_PORT);
    udp->len = htons((uint8_t *)ptr - (uint8_t *) udp );
    udp->check = 0;


    /* setup the IP parameters */
    switch (lookups[idx].mr->sin.sin_family ){
        case AF_INET:
            ip_len = (uint8_t *)ptr - (uint8_t *) ih;
            ih->ip_hl         = 5;
            ih->ip_v          = 4;
            ih->ip_tos        = 0;
            ih->ip_len        = htons(ip_len);
            ih->ip_id         = htons(0);
            ih->ip_off        = 0;
            ih->ip_ttl        = 255;
            ih->ip_p          = IPPROTO_UDP;
            ih->ip_sum        = 0;         
            ih->ip_src.s_addr = afi_addr_src.ip.address.s_addr;
            ih->ip_dst.s_addr = eid->sin.sin_addr.s_addr;
            ih->ip_sum = ip_checksum((unsigned short *)ih, ip_len);
            break;  
    }



    if (sendto(lookups[idx].rx, (void *)buf, (uint8_t *)ptr - (uint8_t *)lh, 0, &(lookups[idx].mr->sa), sockaddr_len) < 0) {
        return 0;
    } else {
        cnt = lookups[idx].count;
        lookups[idx].nonce0[cnt] = nonce0;
        lookups[idx].nonce1[cnt] = nonce1;
        lookups[idx].count++;
        char ip2[INET6_ADDRSTRLEN];
        if(_debug == LLOG || _debug == LDEBUG){
            fprintf(OUTPUT_STREAM, "\n#Send Map-Request to %s:%d <nonce=0x%x - 0x%x>\n", \
                        sk_get_ip(lookups[idx].mr, ip2) , sk_get_port(lookups[idx].mr),\
                        nonce0, nonce1);            
            if(_debug == LDEBUG)
                fprintf(OUTPUT_STREAM,"   EID %s/%d\n",ip,mask);
        }
    }   
    return 1;
}

/* Process with map-reply */

    int
read_rec(union map_reply_record_generic * rec)
{

    fprintf(OUTPUT_STREAM, "\n");
    fprintf(OUTPUT_STREAM, "---------------Begin----------------\n");

    size_t rlen;
    union map_reply_locator_generic * loc;
    char buf[BSIZE];
    size_t len;
    struct map_entry * entry;
    uint8_t lcount;
    struct prefix eid;
    struct mapping_flags mflags;
    void * mapping;
    struct db_node node;
    struct lcaf_hdr *lcaf;
    union rloc_te_generic *hop;
    void *barr;

    node.flags = NULL;
    rlen = 0;
    bzero(buf, BSIZE);
    mapping = NULL;

    bzero(&eid, sizeof(struct prefix));
    switch(ntohs(rec->record.eid_prefix_afi)){
        case LISP_AFI_IP:
            eid.family = AF_INET;
            eid.u.prefix4 = rec->record.eid_prefix;
            inet_ntop(AF_INET, (void *)&eid.u.prefix4, buf, BSIZE);
            rlen += sizeof(struct map_reply_record);
            break;
        default:
            fprintf(OUTPUT_STREAM, "unsuported family\n");
            return (0);
    }
    eid.prefixlen = rec->record.eid_mask_len;
    lcount = rec->record.locator_count;
    bzero(&mflags, sizeof(struct mapping_flags));
    mflags.act = rec->record.act;
    mflags.A = rec->record.a;
    mflags.version = rec->record.version;
    mflags.ttl = ntohl(rec->record.ttl);
    memcpy(&node.p, &eid, sizeof(struct prefix));
    generic_mapping_set_flags(&node, &mflags);
    node.info = list_init();


        return EXIT_SUCCESS;


    loc = (union map_reply_locator_generic *)CO(rec, rlen);

    /* ==================== RLOCs ========================= */
    while(lcount--){
        bzero(buf, BSIZE);
        entry = (struct map_entry *)calloc(1, sizeof(struct map_entry));
        entry->priority = loc->rloc.priority;
        entry->weight = loc->rloc.weight;
        entry->m_priority = loc->rloc.m_priority;
        entry->m_weight = loc->rloc.m_weight;
        entry->r = loc->rloc.R;
        entry->L =loc->rloc.L;
        entry->p = loc->rloc.p;

        lcaf = (struct lcaf_hdr *)&loc->rloc.rloc_afi;
        if(ntohs(lcaf->afi) == LCAF_AFI && lcaf->type == LCAF_TE){
            struct sockaddr_in hop_inet;
            struct sockaddr_in6 hop_inet6;

            int pec = 0;
            int rtr = 0;

            barr = (void *)CO(lcaf,sizeof(struct lcaf_hdr)+ntohs(lcaf->payload_len));
            hop = (union rloc_te_generic *)CO(lcaf,sizeof(struct lcaf_hdr));

            /* run over pe 
                if lisp_te 
                    if xTR --> get the first hop
                    if RTR --> get the hop after RTR
                if not lisp_te --> get last hop             
            */

            hop = (union rloc_te_generic *)CO(lcaf,sizeof(struct lcaf_hdr));
            while((char *)hop < (char *)barr){
                switch(ntohs(hop->rloc.afi)){
                    case LISP_AFI_IP:
                        /* xTR get first hop in pe */
                        if(!pec && lisp_te && (_fncs & _FNC_XTR)){
                            entry->rloc.sin.sin_family = AF_INET;
                            memcpy(&entry->rloc.sin.sin_addr, &hop->rloc.hop_addr, sizeof(struct in_addr));
                            hop = loc = barr;
                            continue;
                        }
                        /* RTR get next hop after it in pe */
                        if(lisp_te && (_fncs & _FNC_RTR)){
                            if(!rtr){
                                /* check if hop's ip is rtr's ip  */
                                hop_inet.sin_family = AF_INET;
                                hop_inet.sin_addr.s_addr = hop->rloc.hop_addr.s_addr;
                                if (is_my_addr((union sockunion *)&hop_inet))
                                    rtr = 1;                                
                            }
                            else{
                                entry->rloc.sin.sin_family = AF_INET;
                                memcpy(&entry->rloc.sin.sin_addr, &hop->rloc.hop_addr,sizeof(struct in_addr));
                                hop = loc = barr;
                                rtr = 0;
                                continue;                               
                            }
                        }

                        /* not lisp_te function get last hop */
                        if( !lisp_te && (CO(hop,sizeof(struct rloc_te) >= (char *)barr )) ){
                            entry->rloc.sin.sin_family = AF_INET;
                            memcpy(&entry->rloc.sin.sin_addr, &hop->rloc.hop_addr,sizeof(struct in_addr));
                            hop = loc = barr;                           
                            continue;
                        }
                        hop = CO(hop,sizeof(struct rloc_te));
                        break;                      
                    case LISP_AFI_IPV6:
                        /* xTR get first hop in pe */
                        if(lisp_te && !pec && (_fncs & _FNC_XTR)){
                            entry->rloc.sin6.sin6_family = AF_INET6;
                            memcpy(&entry->rloc.sin6.sin6_addr, &hop->rloc6.hop_addr, sizeof(struct in6_addr));
                            hop = loc = barr;
                            continue;
                        }
                        /* RTR get next hop after it in pe */
                        if(lisp_te && (_fncs & _FNC_RTR)){
                            if(!rtr){
                                hop_inet6.sin6_family = AF_INET6;
                                memcpy(&hop_inet6.sin6_addr,&hop->rloc6.hop_addr,sizeof(struct in6_addr));
                                if (is_my_addr((union sockunion *)&hop_inet6))
                                    rtr = 1;
                            }
                            else{
                                entry->rloc.sin6.sin6_family = AF_INET6;
                                memcpy(&entry->rloc.sin6.sin6_addr, &hop->rloc6.hop_addr,sizeof(struct in6_addr));
                                hop = loc = barr;
                                rtr = 0;
                                continue;                               
                            }
                        }
                        /* not lisp_te function get last hop */
                        if( (char *)(hop + sizeof(struct rloc6_te)) > (char *)barr){
                            entry->rloc.sin6.sin6_family = AF_INET6;
                            memcpy(&entry->rloc.sin6.sin6_addr, &hop->rloc6.hop_addr,sizeof(struct in6_addr));
                            hop = loc = barr;
                            continue;
                        }
                        hop = (union rloc_te_generic *)CO(hop,sizeof(struct rloc6_te));
                        break;
                    default:
                        fprintf(OUTPUT_STREAM, "unsuported family\n");
                        free(entry);
                        return (0);
                }
                pec++;
            }
            loc = barr;     
        }
        else{
            switch(ntohs(loc->rloc.rloc_afi)){
                case LISP_AFI_IP:
                    entry->rloc.sin.sin_family = AF_INET;
                    memcpy(&entry->rloc.sin.sin_addr, &loc->rloc.rloc, sizeof(struct in_addr));                 
                    len = sizeof(struct map_reply_locator);
                    break;
                case LISP_AFI_IPV6:
                    entry->rloc.sin6.sin6_family = AF_INET6;
                    memcpy(&entry->rloc.sin6.sin6_addr, &loc->rloc6.rloc, sizeof(struct in6_addr));                 
                    len = sizeof(struct map_reply_locator6);
                    break;
                default:
                    fprintf(OUTPUT_STREAM, "unsuported family\n");
                    free(entry);
                    return (0);
            }

            loc = (union map_reply_locator_generic *)CO(loc, len);  
        }
        /* add the locator to the table */
        rlen = (char *)loc - (char *)rec;   
        assert((struct list_t *)node.info);
        struct list_entry_t *m;
        struct map_entry *n_entry;
        if(entry->rloc.sa.sa_family){
            if(!(m = list_search(node.info, entry,entrycmp))){
                list_insert((struct list_t *)node.info, entry, NULL);   
            }               
            else{               
                /* new rloc exist, only updat priority and pe */
                n_entry = (struct map_entry *)m->data;
                if(n_entry->priority > entry->priority){ 
                    m->data = entry;                    
                    free(n_entry);
                }
                else
                    free(entry);
            }           
        }
        else{
            free(entry);
            return 0;
        }       
    }
    fprintf(OUTPUT_STREAM, "  =====================3=====================");
    /* add to OpenLISP mapping cache */
    if(node.info)
        list_destroy((struct list_t *)node.info, NULL);
    return (rlen);
}

/* get map-reply */
    int 
read_mr(int idx)
{

    fprintf(OUTPUT_STREAM, "0000000 Im in plugin_openlisp.c 10 000000");

    int i;
    int rcvl;
    char buf[PSIZE];
    union sockunion si;
    struct map_reply_hdr * lh;
    union map_reply_record_generic * lcm;
    uint32_t nonce0, nonce1;
    socklen_t sockaddr_len;
    int rec_len;
    char ip[INET6_ADDRSTRLEN];

    //printf("get reply\n");
    if(lookups[idx].mr->sa.sa_family == AF_INET)
        sockaddr_len = sizeof(struct sockaddr_in);
    else
        sockaddr_len = sizeof(struct sockaddr_in6);

    /* read package */
    if ((rcvl = recvfrom(lookups[idx].rx,
             buf,
             PSIZE,
            0,
            (struct sockaddr *)&(si.sa),
            &sockaddr_len)) < 0) {
        return 0;
    }

    /*only accept map-reply with not empty record */
    lh = (struct map_reply_hdr *)buf;   
    if (lh->lisp_type != LISP_TYPE_MAP_REPLY) {
        return 0;
    }
    /* check nonce to see reply for what */
    nonce0 = ntohl(lh->lisp_nonce0);
    nonce1 = ntohl(lh->lisp_nonce1);
    fprintf(OUTPUT_STREAM, "---------------p2--------------\n");
    if(_debug == LLOG || _debug == LDEBUG)
        fprintf(OUTPUT_STREAM, "\n#Received Map-Reply from %s:%d <nonce=0x%x - 0x%x>\n",\
                    sk_get_ip(&si, ip) , sk_get_port(&si),\
                    nonce0,nonce1);


    for (i = 0;i <= MAX_COUNT ; i++) {
        if (lookups[idx].nonce0[i] == nonce0 && lookups[idx].nonce1[i] == nonce1)
            break;      
    }
    if (i > MAX_COUNT)
        return 0;

    if (lh->record_count <= 0)
        return 0;

    /* process map-reply */
    lcm = (union map_reply_record_generic *)CO(lh,sizeof(struct  map_reply_hdr));

    for (i = 0; i < lh->record_count; i++){
        if( (rec_len = read_rec(lcm)) < 0){
            if(_debug == LDEBUG)
                fprintf(OUTPUT_ERROR, "Record error\n");
            return -1;
        }
        lcm = (union map_reply_record_generic * )CO(lcm,rec_len);
    }

    lookups[idx].active = 0;
    close(lookups[idx].rx);
    return 0;
}

/* Main poll function */

    static void 
event_loop(void)
{   

    for (;;) {
        int e, i, j, l = -1;
        int poll_timeout = INFTIM; /* poll() timeout in milliseconds. We initialize
                                   to INFTIM = -1 (infinity). If there are no
                                   active lookups, we wait in poll() until a
                                   mapping socket event is received. */
        struct timespec now, deadline, delta, to, tmp;
        //printf("start event_loop\n");
        to.tv_sec  = timeout;
        to.tv_nsec = 0;

        nfds = 1;

        clock_gettime(CLOCK_REALTIME, &now);


            //If lookups inactive continue/salta!
            if (!(lookups[i].active)) continue;
            deadline.tv_sec = lookups[i].start.tv_sec + (lookups[i].count +1) * timeout; 
            deadline.tv_nsec = lookups[i].start.tv_nsec;

            timespec_subtract(&delta, &deadline, &now);

            fds[nfds].fd     = lookups[i].rx;
            fds[nfds].events = POLLIN;
            fds_idx[nfds]    = i;
            nfds++;

            /* Find the minimum delta */
            if (timespec_subtract(&tmp, &delta, &to)) {
                printf("delta.tv_sec: %d\n",delta.tv_sec);
                to.tv_sec    = delta.tv_sec;
                to.tv_nsec   = delta.tv_nsec;
                poll_timeout = to.tv_sec * 1000 + to.tv_nsec / 1000000;
                printf("poll_timeout = %d \n", poll_timeout);
                if (to.tv_sec < 0) poll_timeout = 0;
                l = i;
            }           
        } /* Finished iterating through all lookups */
        printf("--------------\n");
        printf("time_out:%d\n",poll_timeout);
        printf("fds:%d\n",fds);
        printf("nfds:%d\n",nfds);
        printf("Waiting.....\n");
        printf("--------------\n");

        e = poll(fds, nfds, poll_timeout);

        printf("e = %d\n",e);
        printf("l = %d\n",l);

        if (e < 0) continue;
        if (e == 0)                             // If timeout expires
            if (l >= 0)                         // and slot is defined
                send_mr(l);                    // retry Map-Request

        for (j = nfds - 1; j >= 0; j--) {
            printf("Type of event that actually occurred = %d\n",fds[j].revents);
            if (fds[j].revents == POLLIN) {
                printf("j = %d\n",j);
                if (j == 0)
                    map_message_handler(_get_mr());
                else
                    read_mr(fds_idx[j]);
            }
        }

    }
}

/* Main function of thread with intergrate with OpenLisp */
/* Size of socket must be multiple of long (from OpenLISP code) 
    so size of sockaddr_in6 is 32 instead 28 
*/
#define SS_SIZE(ss)                         \
    (  (!(ss) || ((struct sockaddr_storage *)(ss))->ss_len == 0) ?  \
       sizeof(long)     :                   \
    1 + ( (((struct sockaddr_storage *)(ss))->ss_len - 1) | (sizeof(long) - 1) ) )


//MAIN
void main(void * data)
{

    int i;
    struct protoent     *proto;

    if ((proto = getprotobyname("UDP")) == NULL) {
        perror ("getprotobyname");
        exit(0);
    }
    udpproto = proto->p_proto;

    openlispsck = socket(AF_UNIX, SOCK_RAW, 0); // The sysem will chose the most appropriate when specifying set to 0

    lookups[0].rx = fds[0].fd = openlispsck;
    fds[0].events = POLLIN;
    fds_idx[0] = -1;
    nfds = 1;

    /* Initialize lookups[]: all inactive */
    for (i = 0; i < MAX_LOOKUPS; i++){
        lookups[i].active = 0;
    }

    event_loop();
    pthread_exit(NULL);
    return 0;
}

Solution

  • This ULSE answer says that, in general, name-less resources (such as your socket) can only be connected-to from children of the same process, via their resource-descriptor (a process-internal integer ID assigned by the kernel on creation).

    In your c-code, openlispsck (the server AF_UNIX, SOCK_RAW resource-descriptor for the socket that you wish to connect to) is a global variable, and therefore available to other running pthreads spawned from the same process (it is also copied over to the lookups and fds global arrays). Client pthreads can then communicate with the server pthread via sendto calls that use this socket's resource-descriptor; the server pthread, which is listening on the socket, will then process whatever is sent.

    Therefore, you are highly unlikely to manage to communicate with that socket from another process in Java or anything else. Even if you know the resource-descriptor, it is useless from outside the same process. If you can modify the C-code, give your socket a path. If you can't modify the C-code, you can still find the target socket somewhere in the /proc entry of the server process; but I have no idea how you will manage to access it from another process.