]>
git.proxmox.com Git - mirror_iproute2.git/blob - tc/q_atm.c
4 * Hacked 1998-2000 by Werner Almesberger, EPFL ICA
14 #include <sys/socket.h>
15 #include <sys/ioctl.h>
16 #include <netinet/in.h>
17 #include <arpa/inet.h>
20 #include <linux/atmdev.h>
21 #include <linux/atmarp.h>
27 #define MAX_HDR_LEN 64
29 #define usage() return(-1)
32 static int atm_parse_opt(struct qdisc_util
*qu
, int argc
, char **argv
, struct nlmsghdr
*n
)
35 fprintf(stderr
,"Usage: atm\n");
42 static void explain(void)
44 fprintf(stderr
, "Usage: ... atm ( pvc ADDR | svc ADDR [ sap SAP ] ) "
45 "[ qos QOS ] [ sndbuf BYTES ]\n");
46 fprintf(stderr
, " [ hdr HEX... ] [ excess ( CLASSID | clp ) ] "
51 static int atm_parse_class_opt(struct qdisc_util
*qu
, int argc
, char **argv
,
54 struct sockaddr_atmsvc addr
;
57 unsigned char hdr
[MAX_HDR_LEN
];
65 memset(&addr
,0,sizeof(addr
));
66 (void) text2qos("aal5,ubr:sdu=9180,rx:none",&qos
,0);
67 (void) text2sap("blli:l2=iso8802",&sap
,0);
69 if (!strcmp(*argv
,"pvc")) {
71 if (text2atm(*argv
,(struct sockaddr
*) &addr
,
72 sizeof(addr
),T2A_PVC
| T2A_NAME
) < 0) {
77 else if (!strcmp(*argv
,"svc")) {
79 if (text2atm(*argv
,(struct sockaddr
*) &addr
,
80 sizeof(addr
),T2A_SVC
| T2A_NAME
) < 0) {
85 else if (!strcmp(*argv
,"qos")) {
87 if (text2qos(*argv
,&qos
,0) < 0) {
92 else if (!strcmp(*argv
,"sndbuf")) {
96 sndbuf
= strtol(*argv
,&end
,0);
102 else if (!strcmp(*argv
,"sap")) {
104 if (addr
.sas_family
!= AF_ATMSVC
||
105 text2sap(*argv
,&sap
,T2A_NAME
) < 0) {
110 else if (!strcmp(*argv
,"hdr")) {
116 for (walk
= *argv
; *walk
; walk
++) {
119 if (ptr
== hdr
+MAX_HDR_LEN
) {
120 fprintf(stderr
,"header is too long\n");
123 if (*walk
== '.') continue;
124 if (!isxdigit(walk
[0]) || !walk
[1] ||
125 !isxdigit(walk
[1])) {
129 sscanf(walk
,"%2x",&tmp
);
135 else if (!strcmp(*argv
,"excess")) {
137 if (!strcmp(*argv
,"clp")) excess
= 0;
138 else if (get_tc_classid(&excess
,*argv
)) {
143 else if (!strcmp(*argv
,"clip")) {
153 s
= socket(addr
.sas_family
,SOCK_DGRAM
,0);
158 if (setsockopt(s
,SOL_ATM
,SO_ATMQOS
,&qos
,sizeof(qos
)) < 0) {
163 if (setsockopt(s
,SOL_SOCKET
,SO_SNDBUF
,&sndbuf
,sizeof(sndbuf
)) < 0) {
167 if (addr
.sas_family
== AF_ATMSVC
&& setsockopt(s
,SOL_ATM
,SO_ATMSAP
,
168 &sap
,sizeof(sap
)) < 0) {
172 if (connect(s
,(struct sockaddr
*) &addr
,addr
.sas_family
== AF_ATMPVC
?
173 sizeof(struct sockaddr_atmpvc
) : sizeof(addr
)) < 0) {
178 if (ioctl(s
,ATMARP_MKIP
,0) < 0) {
179 perror("ioctl ATMARP_MKIP");
182 tail
= (struct rtattr
*) (((void *) n
)+NLMSG_ALIGN(n
->nlmsg_len
));
183 addattr_l(n
,1024,TCA_OPTIONS
,NULL
,0);
184 addattr_l(n
,1024,TCA_ATM_FD
,&s
,sizeof(s
));
185 if (excess
) addattr_l(n
,1024,TCA_ATM_EXCESS
,&excess
,sizeof(excess
));
186 if (hdr_len
!= -1) addattr_l(n
,1024,TCA_ATM_HDR
,hdr
,hdr_len
);
187 tail
->rta_len
= (((void *) n
)+NLMSG_ALIGN(n
->nlmsg_len
))-(void *) tail
;
193 static int atm_print_opt(struct qdisc_util
*qu
, FILE *f
, struct rtattr
*opt
)
195 struct rtattr
*tb
[TCA_ATM_MAX
+1];
196 char buffer
[MAX_ATM_ADDR_LEN
+1];
199 memset(tb
, 0, sizeof(tb
));
200 parse_rtattr(tb
, TCA_ATM_MAX
, RTA_DATA(opt
), RTA_PAYLOAD(opt
));
201 if (tb
[TCA_ATM_ADDR
]) {
202 if (RTA_PAYLOAD(tb
[TCA_ATM_ADDR
]) <
203 sizeof(struct sockaddr_atmpvc
))
204 fprintf(stderr
,"ATM: address too short\n");
206 if (atm2text(buffer
,MAX_ATM_ADDR_LEN
,
207 RTA_DATA(tb
[TCA_ATM_ADDR
]),A2T_PRETTY
| A2T_NAME
) <
208 0) fprintf(stderr
,"atm2text error\n");
209 fprintf(f
,"pvc %s ",buffer
);
212 if (tb
[TCA_ATM_HDR
]) {
216 for (i
= 0; i
< RTA_PAYLOAD(tb
[TCA_ATM_HDR
]); i
++)
217 fprintf(f
,"%c%02x",i
? '.' : ' ',
218 ((unsigned char *) RTA_DATA(tb
[TCA_ATM_HDR
]))[i
]);
219 if (!i
) fprintf(f
," .");
222 if (tb
[TCA_ATM_EXCESS
]) {
225 if (RTA_PAYLOAD(tb
[TCA_ATM_EXCESS
]) < sizeof(excess
))
226 fprintf(stderr
,"ATM: excess class ID too short\n");
228 excess
= *(__u32
*) RTA_DATA(tb
[TCA_ATM_EXCESS
]);
229 if (!excess
) fprintf(f
,"excess clp ");
233 print_tc_classid(buf
,sizeof(buf
),excess
);
234 fprintf(f
,"excess %s ",buf
);
238 if (tb
[TCA_ATM_STATE
]) {
239 static const char *map
[] = { ATM_VS2TXT_MAP
};
242 if (RTA_PAYLOAD(tb
[TCA_ATM_STATE
]) < sizeof(state
))
243 fprintf(stderr
,"ATM: state field too short\n");
245 state
= *(int *) RTA_DATA(tb
[TCA_ATM_STATE
]);
246 fprintf(f
,"%s ",map
[state
]);
253 static int atm_print_xstats(struct qdisc_util
*qu
, FILE *f
, struct rtattr
*xstats
)
259 struct qdisc_util atm_util
= {