我知道java需要使用第三方庫來使用unix套接字。我使用junixsocket
。如何在java中的unix套接字上發送原始數據包
如何在沒有特定文件路徑名的java unix套接字上發送未連接的數據報?
我需要發送一些數據(比如一個IP地址)給一個作爲服務器的應用程序,並寫在c
。我的java
代碼將是一個客戶端。我不希望它依賴於路徑,因爲在服務器端,c
代碼沒有在特定路徑上監聽,而是在原始unix套接字上輪詢,該套接字定義爲socket(AF_UNIX, SOCK_RAW, 0);
,它沒有特定的文件路徑名稱。謝謝!
這是c
服務器代碼中的一部分,它使用poll()
函數在原始unix套接字上偵聽。 main
函數位於底部,輪詢位於main
之上的event_loop()
函數中。
#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;
}
我沒有理由發佈C代碼。問題只關於Java。順便說一句:**特定**問題是什麼?學習[問]。 – Olaf
我如何在java中的unix套接字上發送一個未連接的數據報,而不使用filepathname。 c代碼可能是有用的,看看服務器如何收聽 – Pheonix7